Merge branch 'master' into zsviczian-loop-lock

# Conflicts:
#	packages/element/src/linearElementEditor.ts
#	packages/excalidraw/actions/actionFinalize.tsx
#	packages/excalidraw/actions/actionLinearEditor.tsx
This commit is contained in:
dwelle 2025-05-10 10:14:59 +02:00
commit e7deda0404
143 changed files with 1016 additions and 776 deletions

View File

@ -63,7 +63,7 @@ The Excalidraw editor (npm package) supports:
- 🏗️ Customizable. - 🏗️ Customizable.
- 📷 Image support. - 📷 Image support.
- 😀 Shape libraries support. - 😀 Shape libraries support.
- 👅 Localization (i18n) support. - 🌐 Localization (i18n) support.
- 🖼️ Export to PNG, SVG & clipboard. - 🖼️ Export to PNG, SVG & clipboard.
- 💾 Open format - export drawings as an `.excalidraw` json file. - 💾 Open format - export drawings as an `.excalidraw` json file.
- ⚒️ Wide range of tools - rectangle, circle, diamond, arrow, line, free-draw, eraser... - ⚒️ Wide range of tools - rectangle, circle, diamond, arrow, line, free-draw, eraser...

View File

@ -47,10 +47,10 @@ import {
share, share,
youtubeIcon, youtubeIcon,
} from "@excalidraw/excalidraw/components/icons"; } from "@excalidraw/excalidraw/components/icons";
import { isElementLink } from "@excalidraw/element/elementLink"; import { isElementLink } from "@excalidraw/element";
import { restore, restoreAppState } from "@excalidraw/excalidraw/data/restore"; import { restore, restoreAppState } from "@excalidraw/excalidraw/data/restore";
import { newElementWith } from "@excalidraw/element/mutateElement"; import { newElementWith } from "@excalidraw/element";
import { isInitializedImageElement } from "@excalidraw/element/typeChecks"; import { isInitializedImageElement } from "@excalidraw/element";
import clsx from "clsx"; import clsx from "clsx";
import { import {
parseLibraryTokensFromUrl, parseLibraryTokensFromUrl,

View File

@ -19,12 +19,9 @@ import {
throttleRAF, throttleRAF,
} from "@excalidraw/common"; } from "@excalidraw/common";
import { decryptData } from "@excalidraw/excalidraw/data/encryption"; import { decryptData } from "@excalidraw/excalidraw/data/encryption";
import { getVisibleSceneBounds } from "@excalidraw/element/bounds"; import { getVisibleSceneBounds } from "@excalidraw/element";
import { newElementWith } from "@excalidraw/element/mutateElement"; import { newElementWith } from "@excalidraw/element";
import { import { isImageElement, isInitializedImageElement } from "@excalidraw/element";
isImageElement,
isInitializedImageElement,
} from "@excalidraw/element/typeChecks";
import { AbortError } from "@excalidraw/excalidraw/errors"; import { AbortError } from "@excalidraw/excalidraw/errors";
import { t } from "@excalidraw/excalidraw/i18n"; import { t } from "@excalidraw/excalidraw/i18n";
import { withBatchedUpdates } from "@excalidraw/excalidraw/reactUtils"; import { withBatchedUpdates } from "@excalidraw/excalidraw/reactUtils";

View File

@ -1,7 +1,7 @@
import { CaptureUpdateAction } from "@excalidraw/excalidraw"; import { CaptureUpdateAction } from "@excalidraw/excalidraw";
import { trackEvent } from "@excalidraw/excalidraw/analytics"; import { trackEvent } from "@excalidraw/excalidraw/analytics";
import { encryptData } from "@excalidraw/excalidraw/data/encryption"; import { encryptData } from "@excalidraw/excalidraw/data/encryption";
import { newElementWith } from "@excalidraw/element/mutateElement"; import { newElementWith } from "@excalidraw/element";
import throttle from "lodash.throttle"; import throttle from "lodash.throttle";
import type { UserIdleState } from "@excalidraw/common"; import type { UserIdleState } from "@excalidraw/common";

View File

@ -12,7 +12,7 @@ import {
generateEncryptionKey, generateEncryptionKey,
} from "@excalidraw/excalidraw/data/encryption"; } from "@excalidraw/excalidraw/data/encryption";
import { serializeAsJSON } from "@excalidraw/excalidraw/data/json"; import { serializeAsJSON } from "@excalidraw/excalidraw/data/json";
import { isInitializedImageElement } from "@excalidraw/element/typeChecks"; import { isInitializedImageElement } from "@excalidraw/element";
import { useI18n } from "@excalidraw/excalidraw/i18n"; import { useI18n } from "@excalidraw/excalidraw/i18n";
import type { import type {

View File

@ -1,7 +1,7 @@
import { CaptureUpdateAction } from "@excalidraw/excalidraw"; import { CaptureUpdateAction } from "@excalidraw/excalidraw";
import { compressData } from "@excalidraw/excalidraw/data/encode"; import { compressData } from "@excalidraw/excalidraw/data/encode";
import { newElementWith } from "@excalidraw/element/mutateElement"; import { newElementWith } from "@excalidraw/element";
import { isInitializedImageElement } from "@excalidraw/element/typeChecks"; import { isInitializedImageElement } from "@excalidraw/element";
import { t } from "@excalidraw/excalidraw/i18n"; import { t } from "@excalidraw/excalidraw/i18n";
import type { import type {

View File

@ -9,14 +9,14 @@ import {
} from "@excalidraw/excalidraw/data/encryption"; } from "@excalidraw/excalidraw/data/encryption";
import { serializeAsJSON } from "@excalidraw/excalidraw/data/json"; import { serializeAsJSON } from "@excalidraw/excalidraw/data/json";
import { restore } from "@excalidraw/excalidraw/data/restore"; import { restore } from "@excalidraw/excalidraw/data/restore";
import { isInvisiblySmallElement } from "@excalidraw/element/sizeHelpers"; import { isInvisiblySmallElement } from "@excalidraw/element";
import { isInitializedImageElement } from "@excalidraw/element/typeChecks"; import { isInitializedImageElement } from "@excalidraw/element";
import { t } from "@excalidraw/excalidraw/i18n"; import { t } from "@excalidraw/excalidraw/i18n";
import { bytesToHexString } from "@excalidraw/common"; import { bytesToHexString } from "@excalidraw/common";
import type { UserIdleState } from "@excalidraw/common"; import type { UserIdleState } from "@excalidraw/common";
import type { ImportedDataState } from "@excalidraw/excalidraw/data/types"; import type { ImportedDataState } from "@excalidraw/excalidraw/data/types";
import type { SceneBounds } from "@excalidraw/element/bounds"; import type { SceneBounds } from "@excalidraw/element";
import type { import type {
ExcalidrawElement, ExcalidrawElement,
FileId, FileId,

View File

@ -3,17 +3,14 @@ import {
createRedoAction, createRedoAction,
createUndoAction, createUndoAction,
} from "@excalidraw/excalidraw/actions/actionHistory"; } from "@excalidraw/excalidraw/actions/actionHistory";
import { syncInvalidIndices } from "@excalidraw/element/fractionalIndex"; import { syncInvalidIndices } from "@excalidraw/element";
import { API } from "@excalidraw/excalidraw/tests/helpers/api"; import { API } from "@excalidraw/excalidraw/tests/helpers/api";
import { act, render, waitFor } from "@excalidraw/excalidraw/tests/test-utils"; import { act, render, waitFor } from "@excalidraw/excalidraw/tests/test-utils";
import { vi } from "vitest"; import { vi } from "vitest";
import { StoreIncrement } from "@excalidraw/element/store"; import { StoreIncrement } from "@excalidraw/element";
import type { import type { DurableIncrement, EphemeralIncrement } from "@excalidraw/element";
DurableIncrement,
EphemeralIncrement,
} from "@excalidraw/element/store";
import ExcalidrawApp from "../App"; import ExcalidrawApp from "../App";

View File

@ -143,6 +143,7 @@ export const FONT_FAMILY = {
"Lilita One": 7, "Lilita One": 7,
"Comic Shanns": 8, "Comic Shanns": 8,
"Liberation Sans": 9, "Liberation Sans": 9,
Assistant: 10,
}; };
export const FONT_FAMILY_FALLBACKS = { export const FONT_FAMILY_FALLBACKS = {

View File

@ -22,8 +22,10 @@ export interface FontMetadata {
}; };
/** flag to indicate a deprecated font */ /** flag to indicate a deprecated font */
deprecated?: true; deprecated?: true;
/** flag to indicate a server-side only font */ /**
serverSide?: true; * whether this is a font that users can use (= shown in font picker)
*/
private?: true;
/** flag to indiccate a local-only font */ /** flag to indiccate a local-only font */
local?: true; local?: true;
/** flag to indicate a fallback font */ /** flag to indicate a fallback font */
@ -98,7 +100,16 @@ export const FONT_METADATA: Record<number, FontMetadata> = {
descender: -434, descender: -434,
lineHeight: 1.15, lineHeight: 1.15,
}, },
serverSide: true, private: true,
},
[FONT_FAMILY.Assistant]: {
metrics: {
unitsPerEm: 2048,
ascender: 1021,
descender: -287,
lineHeight: 1.25,
},
private: true,
}, },
[FONT_FAMILY_FALLBACKS.Xiaolai]: { [FONT_FAMILY_FALLBACKS.Xiaolai]: {
metrics: { metrics: {

View File

@ -9,21 +9,18 @@ import {
toArray, toArray,
} from "@excalidraw/common"; } from "@excalidraw/common";
import { isNonDeletedElement } from "@excalidraw/element"; import { isNonDeletedElement } from "@excalidraw/element";
import { isFrameLikeElement } from "@excalidraw/element/typeChecks"; import { isFrameLikeElement } from "@excalidraw/element";
import { getElementsInGroup } from "@excalidraw/element/groups"; import { getElementsInGroup } from "@excalidraw/element";
import { import {
syncInvalidIndices, syncInvalidIndices,
syncMovedIndices, syncMovedIndices,
validateFractionalIndices, validateFractionalIndices,
} from "@excalidraw/element/fractionalIndex"; } from "@excalidraw/element";
import { getSelectedElements } from "@excalidraw/element/selection"; import { getSelectedElements } from "@excalidraw/element";
import { import { mutateElement, type ElementUpdate } from "@excalidraw/element";
mutateElement,
type ElementUpdate,
} from "@excalidraw/element/mutateElement";
import type { import type {
ExcalidrawElement, ExcalidrawElement,
@ -108,7 +105,7 @@ const hashSelectionOpts = (
// in our codebase // in our codebase
export type ExcalidrawElementsIncludingDeleted = readonly ExcalidrawElement[]; export type ExcalidrawElementsIncludingDeleted = readonly ExcalidrawElement[];
class Scene { export class Scene {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// instance methods/props // instance methods/props
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -457,5 +454,3 @@ class Scene {
return element; return element;
} }
} }
export default Scene;

View File

@ -2,7 +2,7 @@ import { updateBoundElements } from "./binding";
import { getCommonBoundingBox } from "./bounds"; import { getCommonBoundingBox } from "./bounds";
import { getMaximumGroups } from "./groups"; import { getMaximumGroups } from "./groups";
import type Scene from "./Scene"; import type { Scene } from "./Scene";
import type { BoundingBox } from "./bounds"; import type { BoundingBox } from "./bounds";
import type { ExcalidrawElement } from "./types"; import type { ExcalidrawElement } from "./types";

View File

@ -66,7 +66,7 @@ import {
import { aabbForElement, getElementShape, pointInsideBounds } from "./shapes"; import { aabbForElement, getElementShape, pointInsideBounds } from "./shapes";
import { updateElbowArrowPoints } from "./elbowArrow"; import { updateElbowArrowPoints } from "./elbowArrow";
import type Scene from "./Scene"; import type { Scene } from "./Scene";
import type { Bounds } from "./bounds"; import type { Bounds } from "./bounds";
import type { ElementUpdate } from "./mutateElement"; import type { ElementUpdate } from "./mutateElement";

View File

@ -49,7 +49,7 @@ import { getNonDeletedGroupIds } from "./groups";
import { orderByFractionalIndex, syncMovedIndices } from "./fractionalIndex"; import { orderByFractionalIndex, syncMovedIndices } from "./fractionalIndex";
import Scene from "./Scene"; import { Scene } from "./Scene";
import type { BindableProp, BindingProp } from "./binding"; import type { BindableProp, BindingProp } from "./binding";

View File

@ -26,7 +26,7 @@ import {
isTextElement, isTextElement,
} from "./typeChecks"; } from "./typeChecks";
import type Scene from "./Scene"; import type { Scene } from "./Scene";
import type { Bounds } from "./bounds"; import type { Bounds } from "./bounds";
import type { ExcalidrawElement } from "./types"; import type { ExcalidrawElement } from "./types";

View File

@ -39,7 +39,7 @@ import {
type OrderedExcalidrawElement, type OrderedExcalidrawElement,
} from "./types"; } from "./types";
import type Scene from "./Scene"; import type { Scene } from "./Scene";
type LinkDirection = "up" | "right" | "down" | "left"; type LinkDirection = "up" | "right" | "down" | "left";

View File

@ -905,13 +905,16 @@ export const shouldApplyFrameClip = (
return false; return false;
}; };
export const getFrameLikeTitle = (element: ExcalidrawFrameLikeElement) => { const DEFAULT_FRAME_NAME = "Frame";
const DEFAULT_AI_FRAME_NAME = "AI Frame";
export const getDefaultFrameName = (element: ExcalidrawFrameLikeElement) => {
// TODO name frames "AI" only if specific to AI frames // TODO name frames "AI" only if specific to AI frames
return element.name === null return isFrameElement(element) ? DEFAULT_FRAME_NAME : DEFAULT_AI_FRAME_NAME;
? isFrameElement(element) };
? "Frame"
: "AI Frame" export const getFrameLikeTitle = (element: ExcalidrawFrameLikeElement) => {
: element.name; return element.name === null ? getDefaultFrameName(element) : element.name;
}; };
export const getElementsOverlappingFrame = ( export const getElementsOverlappingFrame = (

View File

@ -72,3 +72,47 @@ export const clearElementsForExport = (
export const clearElementsForLocalStorage = ( export const clearElementsForLocalStorage = (
elements: readonly ExcalidrawElement[], elements: readonly ExcalidrawElement[],
) => _clearElements(elements); ) => _clearElements(elements);
export * from "./align";
export * from "./binding";
export * from "./bounds";
export * from "./collision";
export * from "./comparisons";
export * from "./containerCache";
export * from "./cropElement";
export * from "./delta";
export * from "./distance";
export * from "./distribute";
export * from "./dragElements";
export * from "./duplicate";
export * from "./elbowArrow";
export * from "./elementLink";
export * from "./embeddable";
export * from "./flowchart";
export * from "./fractionalIndex";
export * from "./frame";
export * from "./groups";
export * from "./heading";
export * from "./image";
export * from "./linearElementEditor";
export * from "./mutateElement";
export * from "./newElement";
export * from "./renderElement";
export * from "./resizeElements";
export * from "./resizeTest";
export * from "./Scene";
export * from "./selection";
export * from "./Shape";
export * from "./ShapeCache";
export * from "./shapes";
export * from "./showSelectedShapeActions";
export * from "./sizeHelpers";
export * from "./sortElements";
export * from "./store";
export * from "./textElement";
export * from "./textMeasurements";
export * from "./textWrapping";
export * from "./transformHandles";
export * from "./typeChecks";
export * from "./utils";
export * from "./zindex";

View File

@ -20,7 +20,7 @@ import {
tupleToCoors, tupleToCoors,
} from "@excalidraw/common"; } from "@excalidraw/common";
import type { Store } from "@excalidraw/element/store"; import type { Store } from "@excalidraw/element";
import type { Radians } from "@excalidraw/math"; import type { Radians } from "@excalidraw/math";
@ -70,7 +70,7 @@ import { getLockedLinearCursorAlignSize } from "./sizeHelpers";
import { isLineElement } from "./typeChecks"; import { isLineElement } from "./typeChecks";
import type Scene from "./Scene"; import type { Scene } from "./Scene";
import type { Bounds } from "./bounds"; import type { Bounds } from "./bounds";
import type { import type {

View File

@ -57,7 +57,7 @@ import {
import { isInGroup } from "./groups"; import { isInGroup } from "./groups";
import type Scene from "./Scene"; import type { Scene } from "./Scene";
import type { BoundingBox } from "./bounds"; import type { BoundingBox } from "./bounds";
import type { import type {

View File

@ -30,7 +30,7 @@ import {
isTextElement, isTextElement,
} from "./typeChecks"; } from "./typeChecks";
import type Scene from "./Scene"; import type { Scene } from "./Scene";
import type { MaybeTransformHandleType } from "./transformHandles"; import type { MaybeTransformHandleType } from "./transformHandles";
import type { import type {

View File

@ -10,7 +10,7 @@ import { syncMovedIndices } from "./fractionalIndex";
import { getSelectedElements } from "./selection"; import { getSelectedElements } from "./selection";
import type Scene from "./Scene"; import type { Scene } from "./Scene";
import type { ExcalidrawElement, ExcalidrawFrameLikeElement } from "./types"; import type { ExcalidrawElement, ExcalidrawFrameLikeElement } from "./types";

View File

@ -3,21 +3,30 @@ import { vi } from "vitest";
import { KEYS, cloneJSON } from "@excalidraw/common"; import { KEYS, cloneJSON } from "@excalidraw/common";
import { duplicateElement } from "@excalidraw/element/duplicate"; import {
Excalidraw,
exportToCanvas,
exportToSvg,
} from "@excalidraw/excalidraw";
import {
actionFlipHorizontal,
actionFlipVertical,
} from "@excalidraw/excalidraw/actions";
import type { import { API } from "@excalidraw/excalidraw/tests/helpers/api";
ExcalidrawImageElement, import { Keyboard, Pointer, UI } from "@excalidraw/excalidraw/tests/helpers/ui";
ImageCrop, import {
} from "@excalidraw/element/types"; act,
GlobalTestState,
render,
unmountComponent,
} from "@excalidraw/excalidraw/tests/test-utils";
import { Excalidraw, exportToCanvas, exportToSvg } from ".."; import type { NormalizedZoomValue } from "@excalidraw/excalidraw/types";
import { actionFlipHorizontal, actionFlipVertical } from "../actions";
import { API } from "./helpers/api"; import { duplicateElement } from "../src/duplicate";
import { Keyboard, Pointer, UI } from "./helpers/ui";
import { act, GlobalTestState, render, unmountComponent } from "./test-utils";
import type { NormalizedZoomValue } from "../types"; import type { ExcalidrawImageElement, ImageCrop } from "../src/types";
const { h } = window; const { h } = window;
const mouse = new Pointer("mouse"); const mouse = new Pointer("mouse");

View File

@ -1,5 +1,5 @@
import type { ObservedAppState } from "@excalidraw/excalidraw/types"; import type { ObservedAppState } from "@excalidraw/excalidraw/types";
import type { LinearElementEditor } from "@excalidraw/element/linearElementEditor"; import type { LinearElementEditor } from "@excalidraw/element";
import { AppStateDelta } from "../src/delta"; import { AppStateDelta } from "../src/delta";

View File

@ -22,7 +22,7 @@ import type { LocalPoint } from "@excalidraw/math";
import { bindLinearElement } from "../src/binding"; import { bindLinearElement } from "../src/binding";
import Scene from "../src/Scene"; import { Scene } from "../src/Scene";
import type { import type {
ExcalidrawArrowElement, ExcalidrawArrowElement,

View File

@ -7,9 +7,9 @@ import {
syncInvalidIndices, syncInvalidIndices,
syncMovedIndices, syncMovedIndices,
validateFractionalIndices, validateFractionalIndices,
} from "@excalidraw/element/fractionalIndex"; } from "@excalidraw/element";
import { deepCopyElement } from "@excalidraw/element/duplicate"; import { deepCopyElement } from "@excalidraw/element";
import { API } from "@excalidraw/excalidraw/tests/helpers/api"; import { API } from "@excalidraw/excalidraw/tests/helpers/api";

View File

@ -1,5 +1,3 @@
import { newArrowElement } from "@excalidraw/element/newElement";
import { pointCenter, pointFrom } from "@excalidraw/math"; import { pointCenter, pointFrom } from "@excalidraw/math";
import { act, queryByTestId, queryByText } from "@testing-library/react"; import { act, queryByTestId, queryByText } from "@testing-library/react";
import React from "react"; import React from "react";
@ -13,36 +11,34 @@ import {
arrayToMap, arrayToMap,
} from "@excalidraw/common"; } from "@excalidraw/common";
import { LinearElementEditor } from "@excalidraw/element/linearElementEditor"; import { Excalidraw } from "@excalidraw/excalidraw";
import { import * as InteractiveCanvas from "@excalidraw/excalidraw/renderer/interactiveScene";
getBoundTextElementPosition, import * as StaticScene from "@excalidraw/excalidraw/renderer/staticScene";
getBoundTextMaxWidth, import { API } from "@excalidraw/excalidraw/tests/helpers/api";
} from "@excalidraw/element/textElement";
import * as textElementUtils from "@excalidraw/element/textElement";
import { wrapText } from "@excalidraw/element/textWrapping";
import type { GlobalPoint, LocalPoint } from "@excalidraw/math"; import { Keyboard, Pointer, UI } from "@excalidraw/excalidraw/tests/helpers/ui";
import type {
ExcalidrawElement,
ExcalidrawLinearElement,
ExcalidrawTextElementWithContainer,
FontString,
} from "@excalidraw/element/types";
import { Excalidraw } from "../index";
import * as InteractiveCanvas from "../renderer/interactiveScene";
import * as StaticScene from "../renderer/staticScene";
import { API } from "../tests/helpers/api";
import { Keyboard, Pointer, UI } from "./helpers/ui";
import { import {
screen, screen,
render, render,
fireEvent, fireEvent,
GlobalTestState, GlobalTestState,
unmountComponent, unmountComponent,
} from "./test-utils"; } from "@excalidraw/excalidraw/tests/test-utils";
import type { GlobalPoint, LocalPoint } from "@excalidraw/math";
import { wrapText } from "../src";
import * as textElementUtils from "../src/textElement";
import { getBoundTextElementPosition, getBoundTextMaxWidth } from "../src";
import { LinearElementEditor } from "../src";
import { newArrowElement } from "../src";
import type {
ExcalidrawElement,
ExcalidrawLinearElement,
ExcalidrawTextElementWithContainer,
FontString,
} from "../src/types";
const renderInteractiveScene = vi.spyOn( const renderInteractiveScene = vi.spyOn(
InteractiveCanvas, InteractiveCanvas,

View File

@ -1,6 +1,6 @@
import { API } from "@excalidraw/excalidraw/tests/helpers/api"; import { API } from "@excalidraw/excalidraw/tests/helpers/api";
import { mutateElement } from "@excalidraw/element/mutateElement"; import { mutateElement } from "@excalidraw/element";
import { normalizeElementOrder } from "../src/sortElements"; import { normalizeElementOrder } from "../src/sortElements";

View File

@ -1,7 +1,7 @@
import { LIBRARY_DISABLED_TYPES, randomId } from "@excalidraw/common"; import { LIBRARY_DISABLED_TYPES, randomId } from "@excalidraw/common";
import { deepCopyElement } from "@excalidraw/element/duplicate"; import { deepCopyElement } from "@excalidraw/element";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import { t } from "../i18n"; import { t } from "../i18n";

View File

@ -1,18 +1,18 @@
import { getNonDeletedElements } from "@excalidraw/element"; import { getNonDeletedElements } from "@excalidraw/element";
import { isFrameLikeElement } from "@excalidraw/element/typeChecks"; import { isFrameLikeElement } from "@excalidraw/element";
import { updateFrameMembershipOfSelectedElements } from "@excalidraw/element/frame"; import { updateFrameMembershipOfSelectedElements } from "@excalidraw/element";
import { KEYS, arrayToMap, getShortcutKey } from "@excalidraw/common"; import { KEYS, arrayToMap, getShortcutKey } from "@excalidraw/common";
import { alignElements } from "@excalidraw/element/align"; import { alignElements } from "@excalidraw/element";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import type { ExcalidrawElement } from "@excalidraw/element/types"; import type { ExcalidrawElement } from "@excalidraw/element/types";
import type { Alignment } from "@excalidraw/element/align"; import type { Alignment } from "@excalidraw/element";
import { ToolButton } from "../components/ToolButton"; import { ToolButton } from "../components/ToolButton";
import { import {

View File

@ -10,14 +10,14 @@ import {
getOriginalContainerHeightFromCache, getOriginalContainerHeightFromCache,
resetOriginalContainerCache, resetOriginalContainerCache,
updateOriginalContainerCache, updateOriginalContainerCache,
} from "@excalidraw/element/containerCache"; } from "@excalidraw/element";
import { import {
computeBoundTextPosition, computeBoundTextPosition,
computeContainerDimensionForBoundText, computeContainerDimensionForBoundText,
getBoundTextElement, getBoundTextElement,
redrawTextBoundingBox, redrawTextBoundingBox,
} from "@excalidraw/element/textElement"; } from "@excalidraw/element";
import { import {
hasBoundTextElement, hasBoundTextElement,
@ -25,15 +25,15 @@ import {
isTextBindableContainer, isTextBindableContainer,
isTextElement, isTextElement,
isUsingAdaptiveRadius, isUsingAdaptiveRadius,
} from "@excalidraw/element/typeChecks"; } from "@excalidraw/element";
import { measureText } from "@excalidraw/element/textMeasurements"; import { measureText } from "@excalidraw/element";
import { syncMovedIndices } from "@excalidraw/element/fractionalIndex"; import { syncMovedIndices } from "@excalidraw/element";
import { newElement } from "@excalidraw/element/newElement"; import { newElement } from "@excalidraw/element";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import type { import type {
ExcalidrawElement, ExcalidrawElement,

View File

@ -14,10 +14,10 @@ import {
} from "@excalidraw/common"; } from "@excalidraw/common";
import { getNonDeletedElements } from "@excalidraw/element"; import { getNonDeletedElements } from "@excalidraw/element";
import { newElementWith } from "@excalidraw/element/mutateElement"; import { newElementWith } from "@excalidraw/element";
import { getCommonBounds, type SceneBounds } from "@excalidraw/element/bounds"; import { getCommonBounds, type SceneBounds } from "@excalidraw/element";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import type { ExcalidrawElement } from "@excalidraw/element/types"; import type { ExcalidrawElement } from "@excalidraw/element/types";

View File

@ -1,9 +1,9 @@
import { isTextElement } from "@excalidraw/element/typeChecks"; import { isTextElement } from "@excalidraw/element";
import { getTextFromElements } from "@excalidraw/element/textElement"; import { getTextFromElements } from "@excalidraw/element";
import { CODES, KEYS, isFirefox } from "@excalidraw/common"; import { CODES, KEYS, isFirefox } from "@excalidraw/common";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import { import {
copyTextToSystemClipboard, copyTextToSystemClipboard,

View File

@ -1,6 +1,6 @@
import { isImageElement } from "@excalidraw/element/typeChecks"; import { isImageElement } from "@excalidraw/element";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import type { ExcalidrawImageElement } from "@excalidraw/element/types"; import type { ExcalidrawImageElement } from "@excalidraw/element/types";

View File

@ -1,23 +1,23 @@
import { KEYS, updateActiveTool } from "@excalidraw/common"; import { KEYS, updateActiveTool } from "@excalidraw/common";
import { getNonDeletedElements } from "@excalidraw/element"; import { getNonDeletedElements } from "@excalidraw/element";
import { fixBindingsAfterDeletion } from "@excalidraw/element/binding"; import { fixBindingsAfterDeletion } from "@excalidraw/element";
import { LinearElementEditor } from "@excalidraw/element/linearElementEditor"; import { LinearElementEditor } from "@excalidraw/element";
import { newElementWith } from "@excalidraw/element/mutateElement"; import { newElementWith } from "@excalidraw/element";
import { getContainerElement } from "@excalidraw/element/textElement"; import { getContainerElement } from "@excalidraw/element";
import { import {
isBoundToContainer, isBoundToContainer,
isElbowArrow, isElbowArrow,
isFrameLikeElement, isFrameLikeElement,
} from "@excalidraw/element/typeChecks"; } from "@excalidraw/element";
import { getFrameChildren } from "@excalidraw/element/frame"; import { getFrameChildren } from "@excalidraw/element";
import { import {
getElementsInGroup, getElementsInGroup,
selectGroupsForSelectedElements, selectGroupsForSelectedElements,
} from "@excalidraw/element/groups"; } from "@excalidraw/element";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import type { ExcalidrawElement } from "@excalidraw/element/types"; import type { ExcalidrawElement } from "@excalidraw/element/types";

View File

@ -1,18 +1,18 @@
import { getNonDeletedElements } from "@excalidraw/element"; import { getNonDeletedElements } from "@excalidraw/element";
import { isFrameLikeElement } from "@excalidraw/element/typeChecks"; import { isFrameLikeElement } from "@excalidraw/element";
import { CODES, KEYS, arrayToMap, getShortcutKey } from "@excalidraw/common"; import { CODES, KEYS, arrayToMap, getShortcutKey } from "@excalidraw/common";
import { updateFrameMembershipOfSelectedElements } from "@excalidraw/element/frame"; import { updateFrameMembershipOfSelectedElements } from "@excalidraw/element";
import { distributeElements } from "@excalidraw/element/distribute"; import { distributeElements } from "@excalidraw/element";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import type { ExcalidrawElement } from "@excalidraw/element/types"; import type { ExcalidrawElement } from "@excalidraw/element/types";
import type { Distribution } from "@excalidraw/element/distribute"; import type { Distribution } from "@excalidraw/element";
import { ToolButton } from "../components/ToolButton"; import { ToolButton } from "../components/ToolButton";
import { import {

View File

@ -7,18 +7,18 @@ import {
import { getNonDeletedElements } from "@excalidraw/element"; import { getNonDeletedElements } from "@excalidraw/element";
import { LinearElementEditor } from "@excalidraw/element/linearElementEditor"; import { LinearElementEditor } from "@excalidraw/element";
import { import {
getSelectedElements, getSelectedElements,
getSelectionStateForElements, getSelectionStateForElements,
} from "@excalidraw/element/selection"; } from "@excalidraw/element";
import { syncMovedIndices } from "@excalidraw/element/fractionalIndex"; import { syncMovedIndices } from "@excalidraw/element";
import { duplicateElements } from "@excalidraw/element/duplicate"; import { duplicateElements } from "@excalidraw/element";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import { ToolButton } from "../components/ToolButton"; import { ToolButton } from "../components/ToolButton";
import { DuplicateIcon } from "../components/icons"; import { DuplicateIcon } from "../components/icons";

View File

@ -2,9 +2,9 @@ import {
canCreateLinkFromElements, canCreateLinkFromElements,
defaultGetElementLinkFromSelection, defaultGetElementLinkFromSelection,
getLinkIdAndTypeFromSelection, getLinkIdAndTypeFromSelection,
} from "@excalidraw/element/elementLink"; } from "@excalidraw/element";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import { copyTextToSystemClipboard } from "../clipboard"; import { copyTextToSystemClipboard } from "../clipboard";
import { copyIcon, elementLinkIcon } from "../components/icons"; import { copyIcon, elementLinkIcon } from "../components/icons";

View File

@ -1,10 +1,10 @@
import { KEYS, arrayToMap } from "@excalidraw/common"; import { KEYS, arrayToMap } from "@excalidraw/common";
import { newElementWith } from "@excalidraw/element/mutateElement"; import { newElementWith } from "@excalidraw/element";
import { isFrameLikeElement } from "@excalidraw/element/typeChecks"; import { isFrameLikeElement } from "@excalidraw/element";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import type { ExcalidrawElement } from "@excalidraw/element/types"; import type { ExcalidrawElement } from "@excalidraw/element/types";

View File

@ -1,6 +1,6 @@
import { updateActiveTool } from "@excalidraw/common"; import { updateActiveTool } from "@excalidraw/common";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import { setCursorForShape } from "../cursor"; import { setCursorForShape } from "../cursor";

View File

@ -7,7 +7,7 @@ import {
import { getNonDeletedElements } from "@excalidraw/element"; import { getNonDeletedElements } from "@excalidraw/element";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import type { Theme } from "@excalidraw/element/types"; import type { Theme } from "@excalidraw/element/types";

View File

@ -3,22 +3,22 @@ import { pointFrom } from "@excalidraw/math";
import { import {
maybeBindLinearElement, maybeBindLinearElement,
bindOrUnbindLinearElement, bindOrUnbindLinearElement,
} from "@excalidraw/element/binding"; } from "@excalidraw/element";
import { LinearElementEditor } from "@excalidraw/element/linearElementEditor"; import { LinearElementEditor } from "@excalidraw/element";
import { import {
isBindingElement, isBindingElement,
isFreeDrawElement, isFreeDrawElement,
isLinearElement, isLinearElement,
isLineElement, isLineElement,
} from "@excalidraw/element/typeChecks"; } from "@excalidraw/element";
import { KEYS, arrayToMap, updateActiveTool } from "@excalidraw/common"; import { KEYS, arrayToMap, updateActiveTool } from "@excalidraw/common";
import { isPathALoop } from "@excalidraw/element/shapes"; import { isPathALoop } from "@excalidraw/element";
import { isInvisiblySmallElement } from "@excalidraw/element/sizeHelpers"; import { isInvisiblySmallElement } from "@excalidraw/element";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import type { LocalPoint } from "@excalidraw/math"; import type { LocalPoint } from "@excalidraw/math";

View File

@ -2,20 +2,20 @@ import { getNonDeletedElements } from "@excalidraw/element";
import { import {
bindOrUnbindLinearElements, bindOrUnbindLinearElements,
isBindingEnabled, isBindingEnabled,
} from "@excalidraw/element/binding"; } from "@excalidraw/element";
import { getCommonBoundingBox } from "@excalidraw/element/bounds"; import { getCommonBoundingBox } from "@excalidraw/element";
import { newElementWith } from "@excalidraw/element/mutateElement"; import { newElementWith } from "@excalidraw/element";
import { deepCopyElement } from "@excalidraw/element/duplicate"; import { deepCopyElement } from "@excalidraw/element";
import { resizeMultipleElements } from "@excalidraw/element/resizeElements"; import { resizeMultipleElements } from "@excalidraw/element";
import { import {
isArrowElement, isArrowElement,
isElbowArrow, isElbowArrow,
isLinearElement, isLinearElement,
} from "@excalidraw/element/typeChecks"; } from "@excalidraw/element";
import { updateFrameMembershipOfSelectedElements } from "@excalidraw/element/frame"; import { updateFrameMembershipOfSelectedElements } from "@excalidraw/element";
import { CODES, KEYS, arrayToMap } from "@excalidraw/common"; import { CODES, KEYS, arrayToMap } from "@excalidraw/common";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import type { import type {
ExcalidrawArrowElement, ExcalidrawArrowElement,

View File

@ -1,20 +1,20 @@
import { getNonDeletedElements } from "@excalidraw/element"; import { getNonDeletedElements } from "@excalidraw/element";
import { mutateElement } from "@excalidraw/element/mutateElement"; import { mutateElement } from "@excalidraw/element";
import { newFrameElement } from "@excalidraw/element/newElement"; import { newFrameElement } from "@excalidraw/element";
import { isFrameLikeElement } from "@excalidraw/element/typeChecks"; import { isFrameLikeElement } from "@excalidraw/element";
import { import {
addElementsToFrame, addElementsToFrame,
removeAllElementsFromFrame, removeAllElementsFromFrame,
} from "@excalidraw/element/frame"; } from "@excalidraw/element";
import { getFrameChildren } from "@excalidraw/element/frame"; import { getFrameChildren } from "@excalidraw/element";
import { KEYS, updateActiveTool } from "@excalidraw/common"; import { KEYS, updateActiveTool } from "@excalidraw/common";
import { getElementsInGroup } from "@excalidraw/element/groups"; import { getElementsInGroup } from "@excalidraw/element";
import { getCommonBounds } from "@excalidraw/element/bounds"; import { getCommonBounds } from "@excalidraw/element";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import type { ExcalidrawElement } from "@excalidraw/element/types"; import type { ExcalidrawElement } from "@excalidraw/element/types";

View File

@ -1,8 +1,8 @@
import { getNonDeletedElements } from "@excalidraw/element"; import { getNonDeletedElements } from "@excalidraw/element";
import { newElementWith } from "@excalidraw/element/mutateElement"; import { newElementWith } from "@excalidraw/element";
import { isBoundToContainer } from "@excalidraw/element/typeChecks"; import { isBoundToContainer } from "@excalidraw/element";
import { import {
frameAndChildrenSelectedTogether, frameAndChildrenSelectedTogether,
@ -12,7 +12,7 @@ import {
groupByFrameLikes, groupByFrameLikes,
removeElementsFromFrame, removeElementsFromFrame,
replaceAllElementsInFrame, replaceAllElementsInFrame,
} from "@excalidraw/element/frame"; } from "@excalidraw/element";
import { KEYS, randomId, arrayToMap, getShortcutKey } from "@excalidraw/common"; import { KEYS, randomId, arrayToMap, getShortcutKey } from "@excalidraw/common";
@ -24,11 +24,11 @@ import {
addToGroup, addToGroup,
removeFromSelectedGroups, removeFromSelectedGroups,
isElementInGroup, isElementInGroup,
} from "@excalidraw/element/groups"; } from "@excalidraw/element";
import { syncMovedIndices } from "@excalidraw/element/fractionalIndex"; import { syncMovedIndices } from "@excalidraw/element";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import type { import type {
ExcalidrawElement, ExcalidrawElement,

View File

@ -1,8 +1,8 @@
import { isWindows, KEYS, matchKey, arrayToMap } from "@excalidraw/common"; import { isWindows, KEYS, matchKey, arrayToMap } from "@excalidraw/common";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import { orderByFractionalIndex } from "@excalidraw/element/fractionalIndex"; import { orderByFractionalIndex } from "@excalidraw/element";
import type { SceneElementsMap } from "@excalidraw/element/types"; import type { SceneElementsMap } from "@excalidraw/element/types";

View File

@ -1,12 +1,12 @@
import { LinearElementEditor } from "@excalidraw/element/linearElementEditor"; import { LinearElementEditor } from "@excalidraw/element";
import { import {
isElbowArrow, isElbowArrow,
isLinearElement, isLinearElement,
isLineElement, isLineElement,
} from "@excalidraw/element/typeChecks"; } from "@excalidraw/element";
import { arrayToMap } from "@excalidraw/common"; import { arrayToMap } from "@excalidraw/common";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import type { import type {
ExcalidrawLinearElement, ExcalidrawLinearElement,

View File

@ -1,8 +1,8 @@
import { isEmbeddableElement } from "@excalidraw/element/typeChecks"; import { isEmbeddableElement } from "@excalidraw/element";
import { KEYS, getShortcutKey } from "@excalidraw/common"; import { KEYS, getShortcutKey } from "@excalidraw/common";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import { ToolButton } from "../components/ToolButton"; import { ToolButton } from "../components/ToolButton";
import { getContextMenuLabel } from "../components/hyperlink/Hyperlink"; import { getContextMenuLabel } from "../components/hyperlink/Hyperlink";

View File

@ -2,9 +2,9 @@ import { KEYS } from "@excalidraw/common";
import { getNonDeletedElements } from "@excalidraw/element"; import { getNonDeletedElements } from "@excalidraw/element";
import { showSelectedShapeActions } from "@excalidraw/element/showSelectedShapeActions"; import { showSelectedShapeActions } from "@excalidraw/element";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import { ToolButton } from "../components/ToolButton"; import { ToolButton } from "../components/ToolButton";
import { HamburgerMenuIcon, HelpIconThin, palette } from "../components/icons"; import { HamburgerMenuIcon, HelpIconThin, palette } from "../components/icons";

View File

@ -1,6 +1,6 @@
import clsx from "clsx"; import clsx from "clsx";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import { getClientColor } from "../clients"; import { getClientColor } from "../clients";
import { Avatar } from "../components/Avatar"; import { Avatar } from "../components/Avatar";

View File

@ -31,16 +31,16 @@ import {
calculateFixedPointForElbowArrowBinding, calculateFixedPointForElbowArrowBinding,
getHoveredElementForBinding, getHoveredElementForBinding,
updateBoundElements, updateBoundElements,
} from "@excalidraw/element/binding"; } from "@excalidraw/element";
import { LinearElementEditor } from "@excalidraw/element/linearElementEditor"; import { LinearElementEditor } from "@excalidraw/element";
import { newElementWith } from "@excalidraw/element/mutateElement"; import { newElementWith } from "@excalidraw/element";
import { import {
getBoundTextElement, getBoundTextElement,
redrawTextBoundingBox, redrawTextBoundingBox,
} from "@excalidraw/element/textElement"; } from "@excalidraw/element";
import { import {
isArrowElement, isArrowElement,
@ -50,13 +50,13 @@ import {
isLineElement, isLineElement,
isTextElement, isTextElement,
isUsingAdaptiveRadius, isUsingAdaptiveRadius,
} from "@excalidraw/element/typeChecks"; } from "@excalidraw/element";
import { hasStrokeColor } from "@excalidraw/element/comparisons"; import { hasStrokeColor } from "@excalidraw/element";
import { updateElbowArrowPoints } from "@excalidraw/element/elbowArrow"; import { updateElbowArrowPoints } from "@excalidraw/element";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import type { LocalPoint } from "@excalidraw/math"; import type { LocalPoint } from "@excalidraw/math";
@ -72,9 +72,9 @@ import type {
VerticalAlign, VerticalAlign,
} from "@excalidraw/element/types"; } from "@excalidraw/element/types";
import type Scene from "@excalidraw/element/Scene"; import type { Scene } from "@excalidraw/element";
import type { CaptureUpdateActionType } from "@excalidraw/element/store"; import type { CaptureUpdateActionType } from "@excalidraw/element";
import { trackEvent } from "../analytics"; import { trackEvent } from "../analytics";
import { ButtonIconSelect } from "../components/ButtonIconSelect"; import { ButtonIconSelect } from "../components/ButtonIconSelect";

View File

@ -1,12 +1,12 @@
import { getNonDeletedElements } from "@excalidraw/element"; import { getNonDeletedElements } from "@excalidraw/element";
import { LinearElementEditor } from "@excalidraw/element/linearElementEditor"; import { LinearElementEditor } from "@excalidraw/element";
import { isLinearElement, isTextElement } from "@excalidraw/element/typeChecks"; import { isLinearElement, isTextElement } from "@excalidraw/element";
import { arrayToMap, KEYS } from "@excalidraw/common"; import { arrayToMap, KEYS } from "@excalidraw/common";
import { selectGroupsForSelectedElements } from "@excalidraw/element/groups"; import { selectGroupsForSelectedElements } from "@excalidraw/element";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import type { ExcalidrawElement } from "@excalidraw/element/types"; import type { ExcalidrawElement } from "@excalidraw/element/types";

View File

@ -7,7 +7,7 @@ import {
getLineHeight, getLineHeight,
} from "@excalidraw/common"; } from "@excalidraw/common";
import { newElementWith } from "@excalidraw/element/mutateElement"; import { newElementWith } from "@excalidraw/element";
import { import {
hasBoundTextElement, hasBoundTextElement,
@ -17,14 +17,14 @@ import {
isArrowElement, isArrowElement,
isExcalidrawElement, isExcalidrawElement,
isTextElement, isTextElement,
} from "@excalidraw/element/typeChecks"; } from "@excalidraw/element";
import { import {
getBoundTextElement, getBoundTextElement,
redrawTextBoundingBox, redrawTextBoundingBox,
} from "@excalidraw/element/textElement"; } from "@excalidraw/element";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import type { ExcalidrawTextElement } from "@excalidraw/element/types"; import type { ExcalidrawTextElement } from "@excalidraw/element/types";

View File

@ -1,11 +1,11 @@
import { getFontString } from "@excalidraw/common"; import { getFontString } from "@excalidraw/common";
import { newElementWith } from "@excalidraw/element/mutateElement"; import { newElementWith } from "@excalidraw/element";
import { measureText } from "@excalidraw/element/textMeasurements"; import { measureText } from "@excalidraw/element";
import { isTextElement } from "@excalidraw/element/typeChecks"; import { isTextElement } from "@excalidraw/element";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import { getSelectedElements } from "../scene"; import { getSelectedElements } from "../scene";

View File

@ -1,6 +1,6 @@
import { CODES, KEYS } from "@excalidraw/common"; import { CODES, KEYS } from "@excalidraw/common";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import { gridIcon } from "../components/icons"; import { gridIcon } from "../components/icons";

View File

@ -1,6 +1,6 @@
import { CODES, KEYS } from "@excalidraw/common"; import { CODES, KEYS } from "@excalidraw/common";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import { magnetIcon } from "../components/icons"; import { magnetIcon } from "../components/icons";

View File

@ -5,7 +5,7 @@ import {
DEFAULT_SIDEBAR, DEFAULT_SIDEBAR,
} from "@excalidraw/common"; } from "@excalidraw/common";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import { searchIcon } from "../components/icons"; import { searchIcon } from "../components/icons";
@ -34,13 +34,6 @@ export const actionToggleSearchMenu = register({
`.${CLASSES.SEARCH_MENU_INPUT_WRAPPER} input`, `.${CLASSES.SEARCH_MENU_INPUT_WRAPPER} input`,
); );
if (searchInput?.matches(":focus")) {
return {
appState: { ...appState, openSidebar: null },
captureUpdate: CaptureUpdateAction.EVENTUALLY,
};
}
searchInput?.focus(); searchInput?.focus();
searchInput?.select(); searchInput?.select();
return false; return false;

View File

@ -1,4 +1,4 @@
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import type { ExcalidrawElement } from "@excalidraw/element/types"; import type { ExcalidrawElement } from "@excalidraw/element/types";

View File

@ -1,6 +1,6 @@
import { CODES, KEYS } from "@excalidraw/common"; import { CODES, KEYS } from "@excalidraw/common";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import { abacusIcon } from "../components/icons"; import { abacusIcon } from "../components/icons";

View File

@ -1,6 +1,6 @@
import { CODES, KEYS } from "@excalidraw/common"; import { CODES, KEYS } from "@excalidraw/common";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import { eyeIcon } from "../components/icons"; import { eyeIcon } from "../components/icons";

View File

@ -1,6 +1,6 @@
import { CODES, KEYS } from "@excalidraw/common"; import { CODES, KEYS } from "@excalidraw/common";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import { coffeeIcon } from "../components/icons"; import { coffeeIcon } from "../components/icons";

View File

@ -5,9 +5,9 @@ import {
moveOneRight, moveOneRight,
moveAllLeft, moveAllLeft,
moveAllRight, moveAllRight,
} from "@excalidraw/element/zindex"; } from "@excalidraw/element";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import { import {
BringForwardIcon, BringForwardIcon,

View File

@ -3,7 +3,7 @@ import type {
OrderedExcalidrawElement, OrderedExcalidrawElement,
} from "@excalidraw/element/types"; } from "@excalidraw/element/types";
import type { CaptureUpdateActionType } from "@excalidraw/element/store"; import type { CaptureUpdateActionType } from "@excalidraw/element";
import type { import type {
AppClassProperties, AppClassProperties,

View File

@ -121,7 +121,7 @@ export const getDefaultAppState = (): Omit<
followedBy: new Set(), followedBy: new Set(),
isCropping: false, isCropping: false,
croppingElementId: null, croppingElementId: null,
searchMatches: [], searchMatches: null,
}; };
}; };

View File

@ -15,7 +15,7 @@ import {
newTextElement, newTextElement,
newLinearElement, newLinearElement,
newElement, newElement,
} from "@excalidraw/element/newElement"; } from "@excalidraw/element";
import type { Radians } from "@excalidraw/math"; import type { Radians } from "@excalidraw/math";

View File

@ -7,14 +7,14 @@ import {
isPromiseLike, isPromiseLike,
} from "@excalidraw/common"; } from "@excalidraw/common";
import { mutateElement } from "@excalidraw/element/mutateElement"; import { mutateElement } from "@excalidraw/element";
import { deepCopyElement } from "@excalidraw/element/duplicate"; import { deepCopyElement } from "@excalidraw/element";
import { import {
isFrameLikeElement, isFrameLikeElement,
isInitializedImageElement, isInitializedImageElement,
} from "@excalidraw/element/typeChecks"; } from "@excalidraw/element";
import { getContainingFrame } from "@excalidraw/element/frame"; import { getContainingFrame } from "@excalidraw/element";
import type { import type {
ExcalidrawElement, ExcalidrawElement,

View File

@ -11,7 +11,7 @@ import {
import { import {
shouldAllowVerticalAlign, shouldAllowVerticalAlign,
suppportsHorizontalAlign, suppportsHorizontalAlign,
} from "@excalidraw/element/textElement"; } from "@excalidraw/element";
import { import {
hasBoundTextElement, hasBoundTextElement,
@ -19,9 +19,9 @@ import {
isImageElement, isImageElement,
isLinearElement, isLinearElement,
isTextElement, isTextElement,
} from "@excalidraw/element/typeChecks"; } from "@excalidraw/element";
import { hasStrokeColor, toolIsArrow } from "@excalidraw/element/comparisons"; import { hasStrokeColor, toolIsArrow } from "@excalidraw/element";
import type { import type {
ExcalidrawElement, ExcalidrawElement,

View File

@ -104,10 +104,7 @@ import {
Emitter, Emitter,
} from "@excalidraw/common"; } from "@excalidraw/common";
import { import { getCommonBounds, getElementAbsoluteCoords } from "@excalidraw/element";
getCommonBounds,
getElementAbsoluteCoords,
} from "@excalidraw/element/bounds";
import { import {
bindOrUnbindLinearElement, bindOrUnbindLinearElement,
@ -120,11 +117,11 @@ import {
shouldEnableBindingForPointerEvent, shouldEnableBindingForPointerEvent,
updateBoundElements, updateBoundElements,
getSuggestedBindingsForArrows, getSuggestedBindingsForArrows,
} from "@excalidraw/element/binding"; } from "@excalidraw/element";
import { LinearElementEditor } from "@excalidraw/element/linearElementEditor"; import { LinearElementEditor } from "@excalidraw/element";
import { newElementWith } from "@excalidraw/element/mutateElement"; import { newElementWith } from "@excalidraw/element";
import { import {
newFrameElement, newFrameElement,
@ -138,12 +135,9 @@ import {
newLinearElement, newLinearElement,
newTextElement, newTextElement,
refreshTextDimensions, refreshTextDimensions,
} from "@excalidraw/element/newElement"; } from "@excalidraw/element";
import { import { deepCopyElement, duplicateElements } from "@excalidraw/element";
deepCopyElement,
duplicateElements,
} from "@excalidraw/element/duplicate";
import { import {
hasBoundTextElement, hasBoundTextElement,
@ -166,7 +160,7 @@ import {
isFlowchartNodeElement, isFlowchartNodeElement,
isBindableElement, isBindableElement,
isTextElement, isTextElement,
} from "@excalidraw/element/typeChecks"; } from "@excalidraw/element";
import { import {
getLockedLinearCursorAlignSize, getLockedLinearCursorAlignSize,
@ -174,28 +168,28 @@ import {
isElementCompletelyInViewport, isElementCompletelyInViewport,
isElementInViewport, isElementInViewport,
isInvisiblySmallElement, isInvisiblySmallElement,
} from "@excalidraw/element/sizeHelpers"; } from "@excalidraw/element";
import { import {
getBoundTextShape, getBoundTextShape,
getCornerRadius, getCornerRadius,
getElementShape, getElementShape,
isPathALoop, isPathALoop,
} from "@excalidraw/element/shapes"; } from "@excalidraw/element";
import { import {
createSrcDoc, createSrcDoc,
embeddableURLValidator, embeddableURLValidator,
maybeParseEmbedSrc, maybeParseEmbedSrc,
getEmbedLink, getEmbedLink,
} from "@excalidraw/element/embeddable"; } from "@excalidraw/element";
import { import {
getInitializedImageElements, getInitializedImageElements,
loadHTMLImageElement, loadHTMLImageElement,
normalizeSVG, normalizeSVG,
updateImageCache as _updateImageCache, updateImageCache as _updateImageCache,
} from "@excalidraw/element/image"; } from "@excalidraw/element";
import { import {
getBoundTextElement, getBoundTextElement,
@ -203,9 +197,9 @@ import {
getContainerElement, getContainerElement,
isValidTextContainer, isValidTextContainer,
redrawTextBoundingBox, redrawTextBoundingBox,
} from "@excalidraw/element/textElement"; } from "@excalidraw/element";
import { shouldShowBoundingBox } from "@excalidraw/element/transformHandles"; import { shouldShowBoundingBox } from "@excalidraw/element";
import { import {
getFrameChildren, getFrameChildren,
@ -222,30 +216,27 @@ import {
getFrameLikeTitle, getFrameLikeTitle,
getElementsOverlappingFrame, getElementsOverlappingFrame,
filterElementsEligibleAsFrameChildren, filterElementsEligibleAsFrameChildren,
} from "@excalidraw/element/frame"; } from "@excalidraw/element";
import { import {
hitElementBoundText, hitElementBoundText,
hitElementBoundingBoxOnly, hitElementBoundingBoxOnly,
hitElementItself, hitElementItself,
} from "@excalidraw/element/collision"; } from "@excalidraw/element";
import { getVisibleSceneBounds } from "@excalidraw/element/bounds"; import { getVisibleSceneBounds } from "@excalidraw/element";
import { import {
FlowChartCreator, FlowChartCreator,
FlowChartNavigator, FlowChartNavigator,
getLinkDirectionFromKey, getLinkDirectionFromKey,
} from "@excalidraw/element/flowchart"; } from "@excalidraw/element";
import { cropElement } from "@excalidraw/element/cropElement"; import { cropElement } from "@excalidraw/element";
import { wrapText } from "@excalidraw/element/textWrapping"; import { wrapText } from "@excalidraw/element";
import { import { isElementLink, parseElementLinkFromURL } from "@excalidraw/element";
isElementLink,
parseElementLinkFromURL,
} from "@excalidraw/element/elementLink";
import { import {
isMeasureTextSupported, isMeasureTextSupported,
@ -255,11 +246,11 @@ import {
getApproxMinLineWidth, getApproxMinLineWidth,
getApproxMinLineHeight, getApproxMinLineHeight,
getMinTextElementWidth, getMinTextElementWidth,
} from "@excalidraw/element/textMeasurements"; } from "@excalidraw/element";
import { ShapeCache } from "@excalidraw/element/ShapeCache"; import { ShapeCache } from "@excalidraw/element";
import { getRenderOpacity } from "@excalidraw/element/renderElement"; import { getRenderOpacity } from "@excalidraw/element";
import { import {
editGroupForSelectedElement, editGroupForSelectedElement,
@ -269,44 +260,41 @@ import {
isElementInGroup, isElementInGroup,
isSelectedViaGroup, isSelectedViaGroup,
selectGroupsForSelectedElements, selectGroupsForSelectedElements,
} from "@excalidraw/element/groups"; } from "@excalidraw/element";
import { import { syncInvalidIndices, syncMovedIndices } from "@excalidraw/element";
syncInvalidIndices,
syncMovedIndices,
} from "@excalidraw/element/fractionalIndex";
import { import {
excludeElementsInFramesFromSelection, excludeElementsInFramesFromSelection,
getSelectionStateForElements, getSelectionStateForElements,
makeNextSelectedElementIds, makeNextSelectedElementIds,
} from "@excalidraw/element/selection"; } from "@excalidraw/element";
import { import {
getResizeOffsetXY, getResizeOffsetXY,
getResizeArrowDirection, getResizeArrowDirection,
transformElements, transformElements,
} from "@excalidraw/element/resizeElements"; } from "@excalidraw/element";
import { import {
getCursorForResizingElement, getCursorForResizingElement,
getElementWithTransformHandleType, getElementWithTransformHandleType,
getTransformHandleTypeFromCoords, getTransformHandleTypeFromCoords,
} from "@excalidraw/element/resizeTest"; } from "@excalidraw/element";
import { import {
dragNewElement, dragNewElement,
dragSelectedElements, dragSelectedElements,
getDragOffsetXY, getDragOffsetXY,
} from "@excalidraw/element/dragElements"; } from "@excalidraw/element";
import { isNonDeletedElement } from "@excalidraw/element"; import { isNonDeletedElement } from "@excalidraw/element";
import Scene from "@excalidraw/element/Scene"; import { Scene } from "@excalidraw/element";
import { Store, CaptureUpdateAction } from "@excalidraw/element/store"; import { Store, CaptureUpdateAction } from "@excalidraw/element";
import type { ElementUpdate } from "@excalidraw/element/mutateElement"; import type { ElementUpdate } from "@excalidraw/element";
import type { LocalPoint, Radians } from "@excalidraw/math"; import type { LocalPoint, Radians } from "@excalidraw/math";
@ -1417,8 +1405,19 @@ class App extends React.Component<AppProps, AppState> {
} }
const isDarkTheme = this.state.theme === THEME.DARK; const isDarkTheme = this.state.theme === THEME.DARK;
const nonDeletedFramesLikes = this.scene.getNonDeletedFramesLikes();
return this.scene.getNonDeletedFramesLikes().map((f) => { const focusedSearchMatch =
nonDeletedFramesLikes.length > 0
? this.state.searchMatches?.focusedId &&
isFrameLikeElement(
this.scene.getElement(this.state.searchMatches.focusedId),
)
? this.state.searchMatches.matches.find((sm) => sm.focus)
: null
: null;
return nonDeletedFramesLikes.map((f) => {
if ( if (
!isElementInViewport( !isElementInViewport(
f, f,
@ -1484,7 +1483,7 @@ class App extends React.Component<AppProps, AppState> {
borderRadius: 4, borderRadius: 4,
boxShadow: "inset 0 0 0 1px var(--color-primary)", boxShadow: "inset 0 0 0 1px var(--color-primary)",
fontFamily: "Assistant", fontFamily: "Assistant",
fontSize: "14px", fontSize: `${FRAME_STYLE.nameFontSize}px`,
transform: `translate(-${FRAME_NAME_EDIT_PADDING}px, ${FRAME_NAME_EDIT_PADDING}px)`, transform: `translate(-${FRAME_NAME_EDIT_PADDING}px, ${FRAME_NAME_EDIT_PADDING}px)`,
color: "var(--color-gray-80)", color: "var(--color-gray-80)",
overflow: "hidden", overflow: "hidden",
@ -1528,7 +1527,10 @@ class App extends React.Component<AppProps, AppState> {
: FRAME_STYLE.nameColorLightTheme, : FRAME_STYLE.nameColorLightTheme,
lineHeight: FRAME_STYLE.nameLineHeight, lineHeight: FRAME_STYLE.nameLineHeight,
width: "max-content", width: "max-content",
maxWidth: `${f.width}px`, maxWidth:
focusedSearchMatch?.id === f.id && focusedSearchMatch?.focus
? "none"
: `${f.width * this.state.zoom.value}px`,
overflow: f.id === this.state.editingFrame ? "visible" : "hidden", overflow: f.id === this.state.editingFrame ? "visible" : "hidden",
whiteSpace: "nowrap", whiteSpace: "nowrap",
textOverflow: "ellipsis", textOverflow: "ellipsis",
@ -6405,12 +6407,17 @@ class App extends React.Component<AppProps, AppState> {
this.maybeUnfollowRemoteUser(); this.maybeUnfollowRemoteUser();
if (this.state.searchMatches) { if (this.state.searchMatches) {
this.setState((state) => ({ this.setState((state) => {
searchMatches: state.searchMatches.map((searchMatch) => ({ return {
searchMatches: state.searchMatches && {
focusedId: null,
matches: state.searchMatches.matches.map((searchMatch) => ({
...searchMatch, ...searchMatch,
focus: false, focus: false,
})), })),
})); },
};
});
this.updateEditorAtom(searchItemInFocusAtom, null); this.updateEditorAtom(searchItemInFocusAtom, null);
} }

View File

@ -1,6 +1,6 @@
import { type ReactNode, useEffect, useMemo, useRef, useState } from "react"; import { type ReactNode, useEffect, useMemo, useRef, useState } from "react";
import { updateElbowArrowPoints } from "@excalidraw/element/elbowArrow"; import { updateElbowArrowPoints } from "@excalidraw/element";
import { pointFrom, pointRotateRads, type LocalPoint } from "@excalidraw/math"; import { pointFrom, pointRotateRads, type LocalPoint } from "@excalidraw/math";
@ -13,21 +13,21 @@ import {
isLinearElement, isLinearElement,
isSharpArrow, isSharpArrow,
isUsingAdaptiveRadius, isUsingAdaptiveRadius,
} from "@excalidraw/element/typeChecks"; } from "@excalidraw/element";
import { import {
getCommonBoundingBox, getCommonBoundingBox,
getElementAbsoluteCoords, getElementAbsoluteCoords,
} from "@excalidraw/element/bounds"; } from "@excalidraw/element";
import { import {
getBoundTextElement, getBoundTextElement,
getBoundTextMaxHeight, getBoundTextMaxHeight,
getBoundTextMaxWidth, getBoundTextMaxWidth,
redrawTextBoundingBox, redrawTextBoundingBox,
} from "@excalidraw/element/textElement"; } from "@excalidraw/element";
import { wrapText } from "@excalidraw/element/textWrapping"; import { wrapText } from "@excalidraw/element";
import { import {
assertNever, assertNever,
@ -37,17 +37,19 @@ import {
updateActiveTool, updateActiveTool,
} from "@excalidraw/common"; } from "@excalidraw/common";
import { measureText } from "@excalidraw/element/textMeasurements"; import { measureText } from "@excalidraw/element";
import { LinearElementEditor } from "@excalidraw/element/linearElementEditor"; import { LinearElementEditor } from "@excalidraw/element";
import { import {
newArrowElement, newArrowElement,
newElement, newElement,
newLinearElement, newLinearElement,
} from "@excalidraw/element/newElement"; } from "@excalidraw/element";
import { ShapeCache } from "@excalidraw/element/ShapeCache"; import { ShapeCache } from "@excalidraw/element";
import { updateBindings } from "@excalidraw/element";
import type { import type {
ConvertibleGenericTypes, ConvertibleGenericTypes,
@ -66,7 +68,7 @@ import type {
FixedSegment, FixedSegment,
} from "@excalidraw/element/types"; } from "@excalidraw/element/types";
import type Scene from "@excalidraw/element/Scene"; import type { Scene } from "@excalidraw/element";
import { import {
bumpVersion, bumpVersion,
@ -76,7 +78,6 @@ import {
} from ".."; } from "..";
import { trackEvent } from "../analytics"; import { trackEvent } from "../analytics";
import { atom, editorJotaiStore, useSetAtom } from "../editor-jotai"; import { atom, editorJotaiStore, useSetAtom } from "../editor-jotai";
import { updateBindings } from "../../element/src/binding";
import "./ConvertElementTypePopup.scss"; import "./ConvertElementTypePopup.scss";
import { ToolButton } from "./ToolButton"; import { ToolButton } from "./ToolButton";

View File

@ -1,5 +1,5 @@
import { sceneCoordsToViewportCoords } from "@excalidraw/common"; import { sceneCoordsToViewportCoords } from "@excalidraw/common";
import { getElementAbsoluteCoords } from "@excalidraw/element/bounds"; import { getElementAbsoluteCoords } from "@excalidraw/element";
import type { import type {
ElementsMap, ElementsMap,

View File

@ -5,11 +5,11 @@ import { normalizeLink, KEYS } from "@excalidraw/common";
import { import {
defaultGetElementLinkFromSelection, defaultGetElementLinkFromSelection,
getLinkIdAndTypeFromSelection, getLinkIdAndTypeFromSelection,
} from "@excalidraw/element/elementLink"; } from "@excalidraw/element";
import type { ExcalidrawElement } from "@excalidraw/element/types"; import type { ExcalidrawElement } from "@excalidraw/element/types";
import type Scene from "@excalidraw/element/Scene"; import type { Scene } from "@excalidraw/element";
import { t } from "../i18n"; import { t } from "../i18n";
import { getSelectedElements } from "../scene"; import { getSelectedElements } from "../scene";

View File

@ -99,7 +99,7 @@ export const FontPickerList = React.memo(
() => () =>
Array.from(Fonts.registered.entries()) Array.from(Fonts.registered.entries())
.filter( .filter(
([_, { metadata }]) => !metadata.serverSide && !metadata.fallback, ([_, { metadata }]) => !metadata.private && !metadata.fallback,
) )
.map(([familyId, { metadata, fontFaces }]) => { .map(([familyId, { metadata, fontFaces }]) => {
const fontDescriptor = { const fontDescriptor = {

View File

@ -6,11 +6,11 @@ import {
isLinearElement, isLinearElement,
isTextBindableContainer, isTextBindableContainer,
isTextElement, isTextElement,
} from "@excalidraw/element/typeChecks"; } from "@excalidraw/element";
import { getShortcutKey } from "@excalidraw/common"; import { getShortcutKey } from "@excalidraw/common";
import { isNodeInFlowchart } from "@excalidraw/element/flowchart"; import { isNodeInFlowchart } from "@excalidraw/element";
import { t } from "../i18n"; import { t } from "../i18n";
import { isEraserActive } from "../appState"; import { isEraserActive } from "../appState";
@ -39,7 +39,7 @@ const getHints = ({
if ( if (
appState.openSidebar?.name === DEFAULT_SIDEBAR.name && appState.openSidebar?.name === DEFAULT_SIDEBAR.name &&
appState.openSidebar.tab === CANVAS_SEARCH_TAB && appState.openSidebar.tab === CANVAS_SEARCH_TAB &&
appState.searchMatches?.length appState.searchMatches?.matches.length
) { ) {
return t("hints.dismissSearch"); return t("hints.dismissSearch");
} }

View File

@ -10,11 +10,11 @@ import {
isShallowEqual, isShallowEqual,
} from "@excalidraw/common"; } from "@excalidraw/common";
import { mutateElement } from "@excalidraw/element/mutateElement"; import { mutateElement } from "@excalidraw/element";
import { showSelectedShapeActions } from "@excalidraw/element/showSelectedShapeActions"; import { showSelectedShapeActions } from "@excalidraw/element";
import { ShapeCache } from "@excalidraw/element/ShapeCache"; import { ShapeCache } from "@excalidraw/element";
import type { NonDeletedExcalidrawElement } from "@excalidraw/element/types"; import type { NonDeletedExcalidrawElement } from "@excalidraw/element/types";

View File

@ -8,7 +8,7 @@ import React, {
import { MIME_TYPES, arrayToMap } from "@excalidraw/common"; import { MIME_TYPES, arrayToMap } from "@excalidraw/common";
import { duplicateElements } from "@excalidraw/element/duplicate"; import { duplicateElements } from "@excalidraw/element";
import { serializeLibraryAsJSON } from "../data/json"; import { serializeLibraryAsJSON } from "../data/json";
import { useLibraryCache } from "../hooks/useLibraryItemSvg"; import { useLibraryCache } from "../hooks/useLibraryItemSvg";

View File

@ -1,6 +1,6 @@
import React from "react"; import React from "react";
import { showSelectedShapeActions } from "@excalidraw/element/showSelectedShapeActions"; import { showSelectedShapeActions } from "@excalidraw/element";
import type { NonDeletedExcalidrawElement } from "@excalidraw/element/types"; import type { NonDeletedExcalidrawElement } from "@excalidraw/element/types";

View File

@ -1,4 +1,5 @@
@import "open-color/open-color"; @import "open-color/open-color";
@import "../css//variables.module.scss";
.excalidraw { .excalidraw {
.layer-ui__search { .layer-ui__search {
@ -64,21 +65,51 @@
flex: 1 1 0; flex: 1 1 0;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
padding: 0 0.75rem;
gap: 0.125rem; gap: 0.125rem;
} }
.layer-ui__search .collapsible-items {
gap: 2px;
}
.layer-ui__search-result-title {
font-size: 0.875rem;
margin-bottom: 0.25rem;
display: flex;
align-items: center;
gap: 0.25rem;
font-weight: 700;
.title-icon {
width: 0.875rem;
height: 0.875rem;
margin-right: 0.25rem;
svg g {
stroke-width: 1.25;
}
}
}
.layer-ui__divider {
width: 100%;
margin-top: 0.25rem;
margin-bottom: 1rem;
position: relative;
}
.layer-ui__result-item { .layer-ui__result-item {
display: flex; display: flex;
align-items: center; align-items: center;
min-height: 2rem; min-height: 1.875rem;
flex: 0 0 auto; flex: 0 0 auto;
padding: 0.25rem 0.75rem; padding: 0.25rem 0.75rem;
cursor: pointer; cursor: pointer;
border: 1px solid transparent; border: 1px solid transparent;
outline: none; outline: none;
font-size: 16px;
margin: 0 0.75rem;
border-radius: var(--border-radius-md); border-radius: var(--border-radius-md);
.text-icon { .text-icon {

View File

@ -1,13 +1,19 @@
import { round } from "@excalidraw/math"; import { round } from "@excalidraw/math";
import clsx from "clsx"; import clsx from "clsx";
import debounce from "lodash.debounce"; import debounce from "lodash.debounce";
import { Fragment, memo, useEffect, useRef, useState } from "react"; import { Fragment, memo, useEffect, useMemo, useRef, useState } from "react";
import { CLASSES, EVENT } from "@excalidraw/common"; import {
CLASSES,
EVENT,
FONT_FAMILY,
FRAME_STYLE,
getLineHeight,
} from "@excalidraw/common";
import { isElementCompletelyInViewport } from "@excalidraw/element/sizeHelpers"; import { isElementCompletelyInViewport } from "@excalidraw/element";
import { measureText } from "@excalidraw/element/textMeasurements"; import { measureText } from "@excalidraw/element";
import { import {
KEYS, KEYS,
@ -16,10 +22,15 @@ import {
getFontString, getFontString,
} from "@excalidraw/common"; } from "@excalidraw/common";
import { newTextElement } from "@excalidraw/element/newElement"; import { newTextElement } from "@excalidraw/element";
import { isTextElement } from "@excalidraw/element/typeChecks"; import { isTextElement, isFrameLikeElement } from "@excalidraw/element";
import type { ExcalidrawTextElement } from "@excalidraw/element/types"; import { getDefaultFrameName } from "@excalidraw/element/frame";
import type {
ExcalidrawFrameLikeElement,
ExcalidrawTextElement,
} from "@excalidraw/element/types";
import { atom, useAtom } from "../editor-jotai"; import { atom, useAtom } from "../editor-jotai";
@ -29,11 +40,17 @@ import { t } from "../i18n";
import { useApp, useExcalidrawSetAppState } from "./App"; import { useApp, useExcalidrawSetAppState } from "./App";
import { Button } from "./Button"; import { Button } from "./Button";
import { TextField } from "./TextField"; import { TextField } from "./TextField";
import { collapseDownIcon, upIcon, searchIcon } from "./icons"; import {
collapseDownIcon,
upIcon,
searchIcon,
frameToolIcon,
TextIcon,
} from "./icons";
import "./SearchMenu.scss"; import "./SearchMenu.scss";
import type { AppClassProperties } from "../types"; import type { AppClassProperties, SearchMatch } from "../types";
const searchQueryAtom = atom<string>(""); const searchQueryAtom = atom<string>("");
export const searchItemInFocusAtom = atom<number | null>(null); export const searchItemInFocusAtom = atom<number | null>(null);
@ -41,7 +58,7 @@ export const searchItemInFocusAtom = atom<number | null>(null);
const SEARCH_DEBOUNCE = 350; const SEARCH_DEBOUNCE = 350;
type SearchMatchItem = { type SearchMatchItem = {
textElement: ExcalidrawTextElement; element: ExcalidrawTextElement | ExcalidrawFrameLikeElement;
searchQuery: SearchQuery; searchQuery: SearchQuery;
index: number; index: number;
preview: { preview: {
@ -50,12 +67,7 @@ type SearchMatchItem = {
moreBefore: boolean; moreBefore: boolean;
moreAfter: boolean; moreAfter: boolean;
}; };
matchedLines: { matchedLines: SearchMatch["matchedLines"];
offsetX: number;
offsetY: number;
width: number;
height: number;
}[];
}; };
type SearchMatches = { type SearchMatches = {
@ -103,11 +115,16 @@ export const SearchMenu = () => {
searchedQueryRef.current = searchQuery; searchedQueryRef.current = searchQuery;
lastSceneNonceRef.current = app.scene.getSceneNonce(); lastSceneNonceRef.current = app.scene.getSceneNonce();
setAppState({ setAppState({
searchMatches: matchItems.map((searchMatch) => ({ searchMatches: matchItems.length
id: searchMatch.textElement.id, ? {
focusedId: null,
matches: matchItems.map((searchMatch) => ({
id: searchMatch.element.id,
focus: false, focus: false,
matchedLines: searchMatch.matchedLines, matchedLines: searchMatch.matchedLines,
})), })),
}
: null,
}); });
}); });
} }
@ -149,13 +166,25 @@ export const SearchMenu = () => {
useEffect(() => { useEffect(() => {
setAppState((state) => { setAppState((state) => {
if (!state.searchMatches) {
return null;
}
const focusedId =
focusIndex !== null
? state.searchMatches?.matches[focusIndex]?.id || null
: null;
return { return {
searchMatches: state.searchMatches.map((match, index) => { searchMatches: {
focusedId,
matches: state.searchMatches.matches.map((match, index) => {
if (index === focusIndex) { if (index === focusIndex) {
return { ...match, focus: true }; return { ...match, focus: true };
} }
return { ...match, focus: false }; return { ...match, focus: false };
}), }),
},
}; };
}); });
}, [focusIndex, setAppState]); }, [focusIndex, setAppState]);
@ -169,17 +198,21 @@ export const SearchMenu = () => {
const matchAsElement = newTextElement({ const matchAsElement = newTextElement({
text: match.searchQuery, text: match.searchQuery,
x: match.textElement.x + (match.matchedLines[0]?.offsetX ?? 0), x: match.element.x + (match.matchedLines[0]?.offsetX ?? 0),
y: match.textElement.y + (match.matchedLines[0]?.offsetY ?? 0), y: match.element.y + (match.matchedLines[0]?.offsetY ?? 0),
width: match.matchedLines[0]?.width, width: match.matchedLines[0]?.width,
height: match.matchedLines[0]?.height, height: match.matchedLines[0]?.height,
fontSize: match.textElement.fontSize, fontSize: isFrameLikeElement(match.element)
fontFamily: match.textElement.fontFamily, ? FRAME_STYLE.nameFontSize
: match.element.fontSize,
fontFamily: isFrameLikeElement(match.element)
? FONT_FAMILY.Assistant
: match.element.fontFamily,
}); });
const FONT_SIZE_LEGIBILITY_THRESHOLD = 14; const FONT_SIZE_LEGIBILITY_THRESHOLD = 14;
const fontSize = match.textElement.fontSize; const fontSize = matchAsElement.fontSize;
const isTextTiny = const isTextTiny =
fontSize * zoomValue < FONT_SIZE_LEGIBILITY_THRESHOLD; fontSize * zoomValue < FONT_SIZE_LEGIBILITY_THRESHOLD;
@ -233,7 +266,7 @@ export const SearchMenu = () => {
searchedQueryRef.current = null; searchedQueryRef.current = null;
lastSceneNonceRef.current = undefined; lastSceneNonceRef.current = undefined;
setAppState({ setAppState({
searchMatches: [], searchMatches: null,
}); });
setIsSearching(false); setIsSearching(false);
}; };
@ -272,10 +305,6 @@ export const SearchMenu = () => {
} }
searchInputRef.current?.focus(); searchInputRef.current?.focus();
searchInputRef.current?.select(); searchInputRef.current?.select();
} else {
setAppState({
openSidebar: null,
});
} }
} }
@ -336,11 +365,16 @@ export const SearchMenu = () => {
searchedQueryRef.current = searchQuery; searchedQueryRef.current = searchQuery;
lastSceneNonceRef.current = app.scene.getSceneNonce(); lastSceneNonceRef.current = app.scene.getSceneNonce();
setAppState({ setAppState({
searchMatches: matchItems.map((searchMatch) => ({ searchMatches: matchItems.length
id: searchMatch.textElement.id, ? {
focusedId: null,
matches: matchItems.map((searchMatch) => ({
id: searchMatch.element.id,
focus: false, focus: false,
matchedLines: searchMatch.matchedLines, matchedLines: searchMatch.matchedLines,
})), })),
}
: null,
}); });
setIsSearching(false); setIsSearching(false);
@ -447,17 +481,56 @@ interface MatchListProps {
} }
const MatchListBase = (props: MatchListProps) => { const MatchListBase = (props: MatchListProps) => {
const frameNameMatches = useMemo(
() =>
props.matches.items.filter((match) => isFrameLikeElement(match.element)),
[props.matches],
);
const textMatches = useMemo(
() => props.matches.items.filter((match) => isTextElement(match.element)),
[props.matches],
);
return ( return (
<div>
{frameNameMatches.length > 0 && (
<div className="layer-ui__search-result-container"> <div className="layer-ui__search-result-container">
{props.matches.items.map((searchMatch, index) => ( <div className="layer-ui__search-result-title">
<div className="title-icon">{frameToolIcon}</div>
<div>{t("search.frames")}</div>
</div>
{frameNameMatches.map((searchMatch, index) => (
<ListItem <ListItem
key={searchMatch.textElement.id + searchMatch.index} key={searchMatch.element.id + searchMatch.index}
searchQuery={props.searchQuery} searchQuery={props.searchQuery}
preview={searchMatch.preview} preview={searchMatch.preview}
highlighted={index === props.focusIndex} highlighted={index === props.focusIndex}
onClick={() => props.onItemClick(index)} onClick={() => props.onItemClick(index)}
/> />
))} ))}
{textMatches.length > 0 && <div className="layer-ui__divider" />}
</div>
)}
{textMatches.length > 0 && (
<div className="layer-ui__search-result-container">
<div className="layer-ui__search-result-title">
<div className="title-icon">{TextIcon}</div>
<div>{t("search.texts")}</div>
</div>
{textMatches.map((searchMatch, index) => (
<ListItem
key={searchMatch.element.id + searchMatch.index}
searchQuery={props.searchQuery}
preview={searchMatch.preview}
highlighted={index + frameNameMatches.length === props.focusIndex}
onClick={() => props.onItemClick(index + frameNameMatches.length)}
/>
))}
</div>
)}
</div> </div>
); );
}; };
@ -592,12 +665,7 @@ const getMatchedLines = (
index, index,
index + searchQuery.length, index + searchQuery.length,
); );
const matchedLines: { const matchedLines: SearchMatch["matchedLines"] = [];
offsetX: number;
offsetY: number;
width: number;
height: number;
}[] = [];
for (const lineIndexRange of lineIndexRanges) { for (const lineIndexRange of lineIndexRanges) {
if (remainingQuery === "") { if (remainingQuery === "") {
@ -657,6 +725,7 @@ const getMatchedLines = (
offsetY, offsetY,
width, width,
height, height,
showOnCanvas: true,
}); });
startIndex += matchCapacity; startIndex += matchCapacity;
@ -666,6 +735,47 @@ const getMatchedLines = (
return matchedLines; return matchedLines;
}; };
const getMatchInFrame = (
frame: ExcalidrawFrameLikeElement,
searchQuery: SearchQuery,
index: number,
zoomValue: number,
): SearchMatch["matchedLines"] => {
const text = frame.name ?? getDefaultFrameName(frame);
const matchedText = text.slice(index, index + searchQuery.length);
const prefixText = text.slice(0, index);
const font = getFontString({
fontSize: FRAME_STYLE.nameFontSize,
fontFamily: FONT_FAMILY.Assistant,
});
const lineHeight = getLineHeight(FONT_FAMILY.Assistant);
const offset = measureText(prefixText, font, lineHeight);
// Correct non-zero width for empty string
if (prefixText === "") {
offset.width = 0;
}
const matchedMetrics = measureText(matchedText, font, lineHeight);
const offsetX = offset.width;
const offsetY = -offset.height - FRAME_STYLE.strokeWidth;
const width = matchedMetrics.width;
return [
{
offsetX,
offsetY,
width,
height: matchedMetrics.height,
showOnCanvas: offsetX + width <= frame.width * zoomValue,
},
];
};
const escapeSpecialCharacters = (string: string) => { const escapeSpecialCharacters = (string: string) => {
return string.replace(/[.*+?^${}()|[\]\\-]/g, "\\$&"); return string.replace(/[.*+?^${}()|[\]\\-]/g, "\\$&");
}; };
@ -686,9 +796,14 @@ const handleSearch = debounce(
isTextElement(el), isTextElement(el),
) as ExcalidrawTextElement[]; ) as ExcalidrawTextElement[];
texts.sort((a, b) => a.y - b.y); const frames = elements.filter((el) =>
isFrameLikeElement(el),
) as ExcalidrawFrameLikeElement[];
const matchItems: SearchMatchItem[] = []; texts.sort((a, b) => a.y - b.y);
frames.sort((a, b) => a.y - b.y);
const textMatches: SearchMatchItem[] = [];
const regex = new RegExp(escapeSpecialCharacters(searchQuery), "gi"); const regex = new RegExp(escapeSpecialCharacters(searchQuery), "gi");
@ -701,8 +816,35 @@ const handleSearch = debounce(
const matchedLines = getMatchedLines(textEl, searchQuery, match.index); const matchedLines = getMatchedLines(textEl, searchQuery, match.index);
if (matchedLines.length > 0) { if (matchedLines.length > 0) {
matchItems.push({ textMatches.push({
textElement: textEl, element: textEl,
searchQuery,
preview,
index: match.index,
matchedLines,
});
}
}
}
const frameMatches: SearchMatchItem[] = [];
for (const frame of frames) {
let match = null;
const name = frame.name ?? getDefaultFrameName(frame);
while ((match = regex.exec(name)) !== null) {
const preview = getMatchPreview(name, match.index, searchQuery);
const matchedLines = getMatchInFrame(
frame,
searchQuery,
match.index,
app.state.zoom.value,
);
if (matchedLines.length > 0) {
frameMatches.push({
element: frame,
searchQuery, searchQuery,
preview, preview,
index: match.index, index: match.index,
@ -716,9 +858,12 @@ const handleSearch = debounce(
app.visibleElements.map((visibleElement) => visibleElement.id), app.visibleElements.map((visibleElement) => visibleElement.id),
); );
// putting frame matches first
const matchItems: SearchMatchItem[] = [...frameMatches, ...textMatches];
const focusIndex = const focusIndex =
matchItems.findIndex((matchItem) => matchItems.findIndex((matchItem) =>
visibleIds.has(matchItem.textElement.id), visibleIds.has(matchItem.element.id),
) ?? null; ) ?? null;
cb(matchItems, focusIndex); cb(matchItems, focusIndex);

View File

@ -1,18 +1,18 @@
import { degreesToRadians, radiansToDegrees } from "@excalidraw/math"; import { degreesToRadians, radiansToDegrees } from "@excalidraw/math";
import { getBoundTextElement } from "@excalidraw/element/textElement"; import { getBoundTextElement } from "@excalidraw/element";
import { isArrowElement, isElbowArrow } from "@excalidraw/element/typeChecks"; import { isArrowElement, isElbowArrow } from "@excalidraw/element";
import { updateBindings } from "@excalidraw/element";
import type { Degrees } from "@excalidraw/math"; import type { Degrees } from "@excalidraw/math";
import type { ExcalidrawElement } from "@excalidraw/element/types"; import type { ExcalidrawElement } from "@excalidraw/element/types";
import type Scene from "@excalidraw/element/Scene"; import type { Scene } from "@excalidraw/element";
import { angleIcon } from "../icons"; import { angleIcon } from "../icons";
import { updateBindings } from "../../../element/src/binding";
import DragInput from "./DragInput"; import DragInput from "./DragInput";
import { getStepSizedValue, isPropertyEditable } from "./utils"; import { getStepSizedValue, isPropertyEditable } from "./utils";

View File

@ -1,4 +1,4 @@
import type Scene from "@excalidraw/element/Scene"; import type { Scene } from "@excalidraw/element";
import { getNormalizedGridStep } from "../../scene"; import { getNormalizedGridStep } from "../../scene";

View File

@ -10,6 +10,7 @@ interface CollapsibleProps {
openTrigger: () => void; openTrigger: () => void;
children: React.ReactNode; children: React.ReactNode;
className?: string; className?: string;
showCollapsedIcon?: boolean;
} }
const Collapsible = ({ const Collapsible = ({
@ -18,6 +19,7 @@ const Collapsible = ({
openTrigger, openTrigger,
children, children,
className, className,
showCollapsedIcon = true,
}: CollapsibleProps) => { }: CollapsibleProps) => {
return ( return (
<> <>
@ -32,7 +34,9 @@ const Collapsible = ({
onClick={openTrigger} onClick={openTrigger}
> >
{label} {label}
{showCollapsedIcon && (
<InlineIcon icon={open ? collapseUpIcon : collapseDownIcon} /> <InlineIcon icon={open ? collapseUpIcon : collapseDownIcon} />
)}
</div> </div>
{open && ( {open && (
<div style={{ display: "flex", flexDirection: "column" }}> <div style={{ display: "flex", flexDirection: "column" }}>

View File

@ -4,13 +4,13 @@ import { MIN_WIDTH_OR_HEIGHT } from "@excalidraw/common";
import { import {
MINIMAL_CROP_SIZE, MINIMAL_CROP_SIZE,
getUncroppedWidthAndHeight, getUncroppedWidthAndHeight,
} from "@excalidraw/element/cropElement"; } from "@excalidraw/element";
import { resizeSingleElement } from "@excalidraw/element/resizeElements"; import { resizeSingleElement } from "@excalidraw/element";
import { isImageElement } from "@excalidraw/element/typeChecks"; import { isImageElement } from "@excalidraw/element";
import type { ExcalidrawElement } from "@excalidraw/element/types"; import type { ExcalidrawElement } from "@excalidraw/element/types";
import type Scene from "@excalidraw/element/Scene"; import type { Scene } from "@excalidraw/element";
import DragInput from "./DragInput"; import DragInput from "./DragInput";
import { getStepSizedValue, isPropertyEditable } from "./utils"; import { getStepSizedValue, isPropertyEditable } from "./utils";

View File

@ -3,13 +3,13 @@ import { useEffect, useRef, useState } from "react";
import { EVENT, KEYS, cloneJSON } from "@excalidraw/common"; import { EVENT, KEYS, cloneJSON } from "@excalidraw/common";
import { deepCopyElement } from "@excalidraw/element/duplicate"; import { deepCopyElement } from "@excalidraw/element";
import { CaptureUpdateAction } from "@excalidraw/element/store"; import { CaptureUpdateAction } from "@excalidraw/element";
import type { ElementsMap, ExcalidrawElement } from "@excalidraw/element/types"; import type { ElementsMap, ExcalidrawElement } from "@excalidraw/element/types";
import type Scene from "@excalidraw/element/Scene"; import type { Scene } from "@excalidraw/element";
import { useApp } from "../App"; import { useApp } from "../App";
import { InlineIcon } from "../InlineIcon"; import { InlineIcon } from "../InlineIcon";

View File

@ -1,18 +1,15 @@
import { import {
getBoundTextElement, getBoundTextElement,
redrawTextBoundingBox, redrawTextBoundingBox,
} from "@excalidraw/element/textElement"; } from "@excalidraw/element";
import { import { hasBoundTextElement, isTextElement } from "@excalidraw/element";
hasBoundTextElement,
isTextElement,
} from "@excalidraw/element/typeChecks";
import type { import type {
ExcalidrawElement, ExcalidrawElement,
ExcalidrawTextElement, ExcalidrawTextElement,
} from "@excalidraw/element/types"; } from "@excalidraw/element/types";
import type Scene from "@excalidraw/element/Scene"; import type { Scene } from "@excalidraw/element";
import { fontSizeIcon } from "../icons"; import { fontSizeIcon } from "../icons";

View File

@ -1,15 +1,15 @@
import { degreesToRadians, radiansToDegrees } from "@excalidraw/math"; import { degreesToRadians, radiansToDegrees } from "@excalidraw/math";
import { getBoundTextElement } from "@excalidraw/element/textElement"; import { getBoundTextElement } from "@excalidraw/element";
import { isArrowElement } from "@excalidraw/element/typeChecks"; import { isArrowElement } from "@excalidraw/element";
import { isInGroup } from "@excalidraw/element/groups"; import { isInGroup } from "@excalidraw/element";
import type { Degrees } from "@excalidraw/math"; import type { Degrees } from "@excalidraw/math";
import type { ExcalidrawElement } from "@excalidraw/element/types"; import type { ExcalidrawElement } from "@excalidraw/element/types";
import type Scene from "@excalidraw/element/Scene"; import type { Scene } from "@excalidraw/element";
import { angleIcon } from "../icons"; import { angleIcon } from "../icons";

View File

@ -2,17 +2,14 @@ import { pointFrom, type GlobalPoint } from "@excalidraw/math";
import { useMemo } from "react"; import { useMemo } from "react";
import { MIN_WIDTH_OR_HEIGHT } from "@excalidraw/common"; import { MIN_WIDTH_OR_HEIGHT } from "@excalidraw/common";
import { updateBoundElements } from "@excalidraw/element/binding"; import { updateBoundElements } from "@excalidraw/element";
import { import {
rescalePointsInElement, rescalePointsInElement,
resizeSingleElement, resizeSingleElement,
} from "@excalidraw/element/resizeElements"; } from "@excalidraw/element";
import { import { getBoundTextElement, handleBindTextResize } from "@excalidraw/element";
getBoundTextElement,
handleBindTextResize,
} from "@excalidraw/element/textElement";
import { isTextElement } from "@excalidraw/element/typeChecks"; import { isTextElement } from "@excalidraw/element";
import { getCommonBounds } from "@excalidraw/utils"; import { getCommonBounds } from "@excalidraw/utils";
@ -22,7 +19,7 @@ import type {
NonDeletedSceneElementsMap, NonDeletedSceneElementsMap,
} from "@excalidraw/element/types"; } from "@excalidraw/element/types";
import type Scene from "@excalidraw/element/Scene"; import type { Scene } from "@excalidraw/element";
import DragInput from "./DragInput"; import DragInput from "./DragInput";
import { getAtomicUnits, getStepSizedValue, isPropertyEditable } from "./utils"; import { getAtomicUnits, getStepSizedValue, isPropertyEditable } from "./utils";

View File

@ -1,13 +1,10 @@
import { import {
getBoundTextElement, getBoundTextElement,
redrawTextBoundingBox, redrawTextBoundingBox,
} from "@excalidraw/element/textElement"; } from "@excalidraw/element";
import { import { hasBoundTextElement, isTextElement } from "@excalidraw/element";
hasBoundTextElement,
isTextElement,
} from "@excalidraw/element/typeChecks";
import { isInGroup } from "@excalidraw/element/groups"; import { isInGroup } from "@excalidraw/element";
import type { import type {
ExcalidrawElement, ExcalidrawElement,
@ -15,7 +12,7 @@ import type {
NonDeletedSceneElementsMap, NonDeletedSceneElementsMap,
} from "@excalidraw/element/types"; } from "@excalidraw/element/types";
import type Scene from "@excalidraw/element/Scene"; import type { Scene } from "@excalidraw/element";
import { fontSizeIcon } from "../icons"; import { fontSizeIcon } from "../icons";

View File

@ -1,13 +1,13 @@
import { pointFrom, pointRotateRads } from "@excalidraw/math"; import { pointFrom, pointRotateRads } from "@excalidraw/math";
import { useMemo } from "react"; import { useMemo } from "react";
import { isTextElement } from "@excalidraw/element/typeChecks"; import { isTextElement } from "@excalidraw/element";
import { getCommonBounds } from "@excalidraw/element/bounds"; import { getCommonBounds } from "@excalidraw/element";
import type { ElementsMap, ExcalidrawElement } from "@excalidraw/element/types"; import type { ElementsMap, ExcalidrawElement } from "@excalidraw/element/types";
import type Scene from "@excalidraw/element/Scene"; import type { Scene } from "@excalidraw/element";
import StatsDragInput from "./DragInput"; import StatsDragInput from "./DragInput";
import { import {

View File

@ -3,12 +3,12 @@ import { clamp, pointFrom, pointRotateRads, round } from "@excalidraw/math";
import { import {
getFlipAdjustedCropPosition, getFlipAdjustedCropPosition,
getUncroppedWidthAndHeight, getUncroppedWidthAndHeight,
} from "@excalidraw/element/cropElement"; } from "@excalidraw/element";
import { isImageElement } from "@excalidraw/element/typeChecks"; import { isImageElement } from "@excalidraw/element";
import type { ElementsMap, ExcalidrawElement } from "@excalidraw/element/types"; import type { ElementsMap, ExcalidrawElement } from "@excalidraw/element/types";
import type Scene from "@excalidraw/element/Scene"; import type { Scene } from "@excalidraw/element";
import StatsDragInput from "./DragInput"; import StatsDragInput from "./DragInput";
import { getStepSizedValue, moveElement, STEP_SIZE } from "./utils"; import { getStepSizedValue, moveElement, STEP_SIZE } from "./utils";

View File

@ -4,13 +4,13 @@ import throttle from "lodash.throttle";
import { useEffect, useMemo, useState, memo } from "react"; import { useEffect, useMemo, useState, memo } from "react";
import { STATS_PANELS } from "@excalidraw/common"; import { STATS_PANELS } from "@excalidraw/common";
import { getCommonBounds } from "@excalidraw/element/bounds"; import { getCommonBounds } from "@excalidraw/element";
import { getUncroppedWidthAndHeight } from "@excalidraw/element/cropElement"; import { getUncroppedWidthAndHeight } from "@excalidraw/element";
import { isElbowArrow, isImageElement } from "@excalidraw/element/typeChecks"; import { isElbowArrow, isImageElement } from "@excalidraw/element";
import { frameAndChildrenSelectedTogether } from "@excalidraw/element/frame"; import { frameAndChildrenSelectedTogether } from "@excalidraw/element";
import { elementsAreInSameGroup } from "@excalidraw/element/groups"; import { elementsAreInSameGroup } from "@excalidraw/element";
import type { NonDeletedExcalidrawElement } from "@excalidraw/element/types"; import type { NonDeletedExcalidrawElement } from "@excalidraw/element/types";

View File

@ -5,9 +5,9 @@ import { vi } from "vitest";
import { setDateTimeForTests, reseed } from "@excalidraw/common"; import { setDateTimeForTests, reseed } from "@excalidraw/common";
import { isInGroup } from "@excalidraw/element/groups"; import { isInGroup } from "@excalidraw/element";
import { isTextElement } from "@excalidraw/element/typeChecks"; import { isTextElement } from "@excalidraw/element";
import type { Degrees } from "@excalidraw/math"; import type { Degrees } from "@excalidraw/math";

View File

@ -1,18 +1,17 @@
import { pointFrom, pointRotateRads } from "@excalidraw/math"; import { pointFrom, pointRotateRads } from "@excalidraw/math";
import { getBoundTextElement } from "@excalidraw/element/textElement"; import { getBoundTextElement } from "@excalidraw/element";
import { import { isFrameLikeElement, isTextElement } from "@excalidraw/element";
isFrameLikeElement,
isTextElement,
} from "@excalidraw/element/typeChecks";
import { import {
getSelectedGroupIds, getSelectedGroupIds,
getElementsInGroup, getElementsInGroup,
isInGroup, isInGroup,
} from "@excalidraw/element/groups"; } from "@excalidraw/element";
import { getFrameChildren } from "@excalidraw/element/frame"; import { getFrameChildren } from "@excalidraw/element";
import { updateBindings } from "@excalidraw/element";
import type { Radians } from "@excalidraw/math"; import type { Radians } from "@excalidraw/math";
@ -22,9 +21,7 @@ import type {
NonDeletedExcalidrawElement, NonDeletedExcalidrawElement,
} from "@excalidraw/element/types"; } from "@excalidraw/element/types";
import type Scene from "@excalidraw/element/Scene"; import type { Scene } from "@excalidraw/element";
import { updateBindings } from "../../../element/src/binding";
import type { AppState } from "../../types"; import type { AppState } from "../../types";

View File

@ -10,16 +10,13 @@ import {
import { EVENT, HYPERLINK_TOOLTIP_DELAY, KEYS } from "@excalidraw/common"; import { EVENT, HYPERLINK_TOOLTIP_DELAY, KEYS } from "@excalidraw/common";
import { getElementAbsoluteCoords } from "@excalidraw/element/bounds"; import { getElementAbsoluteCoords } from "@excalidraw/element";
import { hitElementBoundingBox } from "@excalidraw/element/collision"; import { hitElementBoundingBox } from "@excalidraw/element";
import { isElementLink } from "@excalidraw/element/elementLink"; import { isElementLink } from "@excalidraw/element";
import { import { getEmbedLink, embeddableURLValidator } from "@excalidraw/element";
getEmbedLink,
embeddableURLValidator,
} from "@excalidraw/element/embeddable";
import { import {
sceneCoordsToViewportCoords, sceneCoordsToViewportCoords,
@ -29,9 +26,9 @@ import {
normalizeLink, normalizeLink,
} from "@excalidraw/common"; } from "@excalidraw/common";
import { isEmbeddableElement } from "@excalidraw/element/typeChecks"; import { isEmbeddableElement } from "@excalidraw/element";
import type Scene from "@excalidraw/element/Scene"; import type { Scene } from "@excalidraw/element";
import type { import type {
ElementsMap, ElementsMap,

View File

@ -1,14 +1,14 @@
import { pointFrom, pointRotateRads } from "@excalidraw/math"; import { pointFrom, pointRotateRads } from "@excalidraw/math";
import { MIME_TYPES } from "@excalidraw/common"; import { MIME_TYPES } from "@excalidraw/common";
import { getElementAbsoluteCoords } from "@excalidraw/element/bounds"; import { getElementAbsoluteCoords } from "@excalidraw/element";
import { hitElementBoundingBox } from "@excalidraw/element/collision"; import { hitElementBoundingBox } from "@excalidraw/element";
import { DEFAULT_LINK_SIZE } from "@excalidraw/element/renderElement"; import { DEFAULT_LINK_SIZE } from "@excalidraw/element";
import type { GlobalPoint, Radians } from "@excalidraw/math"; import type { GlobalPoint, Radians } from "@excalidraw/math";
import type { Bounds } from "@excalidraw/element/bounds"; import type { Bounds } from "@excalidraw/element";
import type { import type {
ElementsMap, ElementsMap,
NonDeletedExcalidrawElement, NonDeletedExcalidrawElement,

View File

@ -10,9 +10,9 @@ import {
import { getNonDeletedElements } from "@excalidraw/element"; import { getNonDeletedElements } from "@excalidraw/element";
import { isFrameLikeElement } from "@excalidraw/element/typeChecks"; import { isFrameLikeElement } from "@excalidraw/element";
import { getElementsOverlappingFrame } from "@excalidraw/element/frame"; import { getElementsOverlappingFrame } from "@excalidraw/element";
import type { import type {
ExcalidrawElement, ExcalidrawElement,

View File

@ -19,7 +19,7 @@ import {
import { hashElementsVersion, hashString } from "@excalidraw/element"; import { hashElementsVersion, hashString } from "@excalidraw/element";
import { getCommonBoundingBox } from "@excalidraw/element/bounds"; import { getCommonBoundingBox } from "@excalidraw/element";
import type { ExcalidrawElement } from "@excalidraw/element/types"; import type { ExcalidrawElement } from "@excalidraw/element/types";

View File

@ -6,7 +6,7 @@ import {
orderByFractionalIndex, orderByFractionalIndex,
syncInvalidIndices, syncInvalidIndices,
validateFractionalIndices, validateFractionalIndices,
} from "@excalidraw/element/fractionalIndex"; } from "@excalidraw/element";
import type { OrderedExcalidrawElement } from "@excalidraw/element/types"; import type { OrderedExcalidrawElement } from "@excalidraw/element/types";

View File

@ -19,15 +19,15 @@ import {
getLineHeight, getLineHeight,
} from "@excalidraw/common"; } from "@excalidraw/common";
import { getNonDeletedElements } from "@excalidraw/element"; import { getNonDeletedElements } from "@excalidraw/element";
import { normalizeFixedPoint } from "@excalidraw/element/binding"; import { normalizeFixedPoint } from "@excalidraw/element";
import { import {
updateElbowArrowPoints, updateElbowArrowPoints,
validateElbowPoints, validateElbowPoints,
} from "@excalidraw/element/elbowArrow"; } from "@excalidraw/element";
import { LinearElementEditor } from "@excalidraw/element/linearElementEditor"; import { LinearElementEditor } from "@excalidraw/element";
import { bumpVersion } from "@excalidraw/element/mutateElement"; import { bumpVersion } from "@excalidraw/element";
import { getContainerElement } from "@excalidraw/element/textElement"; import { getContainerElement } from "@excalidraw/element";
import { detectLineHeight } from "@excalidraw/element/textMeasurements"; import { detectLineHeight } from "@excalidraw/element";
import { import {
isArrowBoundToElement, isArrowBoundToElement,
isArrowElement, isArrowElement,
@ -37,15 +37,15 @@ import {
isLineElement, isLineElement,
isTextElement, isTextElement,
isUsingAdaptiveRadius, isUsingAdaptiveRadius,
} from "@excalidraw/element/typeChecks"; } from "@excalidraw/element";
import { syncInvalidIndices } from "@excalidraw/element/fractionalIndex"; import { syncInvalidIndices } from "@excalidraw/element";
import { refreshTextDimensions } from "@excalidraw/element/newElement"; import { refreshTextDimensions } from "@excalidraw/element";
import { getNormalizedDimensions } from "@excalidraw/element/sizeHelpers"; import { getNormalizedDimensions } from "@excalidraw/element";
import { isInvisiblySmallElement } from "@excalidraw/element/sizeHelpers"; import { isInvisiblySmallElement } from "@excalidraw/element";
import type { LocalPoint, Radians } from "@excalidraw/math"; import type { LocalPoint, Radians } from "@excalidraw/math";

View File

@ -16,7 +16,7 @@ import {
getLineHeight, getLineHeight,
} from "@excalidraw/common"; } from "@excalidraw/common";
import { bindLinearElement } from "@excalidraw/element/binding"; import { bindLinearElement } from "@excalidraw/element";
import { import {
newArrowElement, newArrowElement,
newElement, newElement,
@ -25,24 +25,21 @@ import {
newLinearElement, newLinearElement,
newMagicFrameElement, newMagicFrameElement,
newTextElement, newTextElement,
} from "@excalidraw/element/newElement"; } from "@excalidraw/element";
import { import { measureText, normalizeText } from "@excalidraw/element";
measureText, import { isArrowElement } from "@excalidraw/element";
normalizeText,
} from "@excalidraw/element/textMeasurements";
import { isArrowElement } from "@excalidraw/element/typeChecks";
import { syncInvalidIndices } from "@excalidraw/element/fractionalIndex"; import { syncInvalidIndices } from "@excalidraw/element";
import { redrawTextBoundingBox } from "@excalidraw/element/textElement"; import { redrawTextBoundingBox } from "@excalidraw/element";
import { LinearElementEditor } from "@excalidraw/element/linearElementEditor"; import { LinearElementEditor } from "@excalidraw/element";
import { getCommonBounds } from "@excalidraw/element/bounds"; import { getCommonBounds } from "@excalidraw/element";
import Scene from "@excalidraw/element/Scene"; import { Scene } from "@excalidraw/element";
import type { ElementConstructorOpts } from "@excalidraw/element/newElement"; import type { ElementConstructorOpts } from "@excalidraw/element";
import type { import type {
ExcalidrawArrowElement, ExcalidrawArrowElement,

Some files were not shown because too many files have changed in this diff Show More