Partialy fixing element package

This commit is contained in:
Marcel Mraz 2025-03-17 17:01:19 +01:00
parent 5e68895709
commit e2c2218f62
No known key found for this signature in database
GPG key ID: 4EBD6E62DC830CD2
45 changed files with 383 additions and 206 deletions

View file

@ -1,7 +1,9 @@
export * from "./src/binary-heap";
export * from "./src/colors"; export * from "./src/colors";
export * from "./src/constants"; export * from "./src/constants";
export * from "./src/keys"; export * from "./src/keys";
export * from "./src/points"; export * from "./src/points";
export * from "./src/promise-pool";
export * from "./src/random"; export * from "./src/random";
export * from "./src/url"; export * from "./src/url";
export * from "./src/utils"; export * from "./src/utils";

View file

@ -1,4 +1,4 @@
export default class BinaryHeap<T> { export class BinaryHeap<T> {
private content: T[] = []; private content: T[] = [];
constructor(private scoreFunction: (node: T) => number) {} constructor(private scoreFunction: (node: T) => number) {}

9
packages/element/global.d.ts vendored Normal file
View file

@ -0,0 +1,9 @@
interface ImportMetaEnv {
MODE: string;
DEV: string;
PROD: string;
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}

View file

@ -1,11 +1,17 @@
import { isInvisiblySmallElement } from "./sizeHelpers"; import { isInvisiblySmallElement } from "./src/sizeHelpers";
import { isLinearElementType } from "./typeChecks"; import { isLinearElementType } from "./src/typeChecks";
import type { import type {
ExcalidrawElement, ExcalidrawElement,
NonDeletedExcalidrawElement, NonDeletedExcalidrawElement,
NonDeleted, NonDeleted,
} from "./types"; } from "./src/types";
export {
aabbForElement,
getElementShape,
pointInsideBounds,
} from "./src/shapes";
export { export {
newElement, newElement,
@ -15,7 +21,8 @@ export {
newArrowElement, newArrowElement,
newImageElement, newImageElement,
duplicateElement, duplicateElement,
} from "./newElement"; } from "./src/newElement";
export { export {
getElementAbsoluteCoords, getElementAbsoluteCoords,
getElementBounds, getElementBounds,
@ -23,39 +30,48 @@ export {
getDiamondPoints, getDiamondPoints,
getArrowheadPoints, getArrowheadPoints,
getClosestElementBounds, getClosestElementBounds,
} from "./bounds"; } from "./src/bounds";
export { export {
OMIT_SIDES_FOR_MULTIPLE_ELEMENTS, OMIT_SIDES_FOR_MULTIPLE_ELEMENTS,
getTransformHandlesFromCoords, getTransformHandlesFromCoords,
getTransformHandles, getTransformHandles,
} from "./transformHandles"; } from "./src/transformHandles";
export { export {
resizeTest, resizeTest,
getCursorForResizingElement, getCursorForResizingElement,
getElementWithTransformHandleType, getElementWithTransformHandleType,
getTransformHandleTypeFromCoords, getTransformHandleTypeFromCoords,
} from "./resizeTest"; } from "./src/resizeTest";
export { export {
transformElements, transformElements,
getResizeOffsetXY, getResizeOffsetXY,
getResizeArrowDirection, getResizeArrowDirection,
} from "./resizeElements"; } from "./src/resizeElements";
export { export {
dragSelectedElements, dragSelectedElements,
getDragOffsetXY, getDragOffsetXY,
dragNewElement, dragNewElement,
} from "./dragElements"; } from "./src/dragElements";
export { isTextElement, isExcalidrawElement } from "./typeChecks";
export { redrawTextBoundingBox, getTextFromElements } from "./textElement"; export { isTextElement, isExcalidrawElement } from "./src/typeChecks";
export { redrawTextBoundingBox, getTextFromElements } from "./src/textElement";
export { export {
getPerfectElementSize, getPerfectElementSize,
getLockedLinearCursorAlignSize, getLockedLinearCursorAlignSize,
isInvisiblySmallElement, isInvisiblySmallElement,
resizePerfectLineForNWHandler, resizePerfectLineForNWHandler,
getNormalizedDimensions, getNormalizedDimensions,
} from "./sizeHelpers"; } from "./src/sizeHelpers";
export { showSelectedShapeActions } from "./showSelectedShapeActions";
export { showSelectedShapeActions } from "./src/showSelectedShapeActions";
export * from "./src/frame";
export * from "./src/shapes";
/** /**
* @deprecated unsafe, use hashElementsVersion instead * @deprecated unsafe, use hashElementsVersion instead

View file

@ -1,3 +1,10 @@
import {
KEYS,
arrayToMap,
isBindingFallthroughEnabled,
tupleToCoors,
} from "@excalidraw/common";
import { import {
lineSegment, lineSegment,
pointFrom, pointFrom,
@ -16,17 +23,20 @@ import {
round, round,
PRECISION, PRECISION,
} from "@excalidraw/math"; } from "@excalidraw/math";
import {
aabbForElement,
getElementShape,
pointInsideBounds,
} from "@excalidraw/element";
import { isPointOnShape } from "@excalidraw/utils/collision"; import { isPointOnShape } from "@excalidraw/utils/collision";
import type { LocalPoint, Radians } from "@excalidraw/math"; import type { LocalPoint, Radians } from "@excalidraw/math";
import { KEYS } from "../keys"; import type Scene from "@excalidraw/excalidraw/scene/Scene";
import { aabbForElement, getElementShape, pointInsideBounds } from "../shapes";
import { import type { AppState } from "@excalidraw/excalidraw/types";
arrayToMap,
isBindingFallthroughEnabled,
tupleToCoors,
} from "../utils";
import { import {
getCenterForBounds, getCenterForBounds,
@ -79,8 +89,6 @@ import type {
SceneElementsMap, SceneElementsMap,
FixedPointBinding, FixedPointBinding,
} from "./types"; } from "./types";
import type Scene from "../scene/Scene";
import type { AppState } from "../types";
export type SuggestedBinding = export type SuggestedBinding =
| NonDeleted<ExcalidrawBindableElement> | NonDeleted<ExcalidrawBindableElement>

View file

@ -1,3 +1,7 @@
import rough from "roughjs/bin/rough";
import { rescalePoints, arrayToMap, invariant } from "@excalidraw/common";
import { import {
degreesToRadians, degreesToRadians,
lineSegment, lineSegment,
@ -6,8 +10,10 @@ import {
pointFromArray, pointFromArray,
pointRotateRads, pointRotateRads,
} from "@excalidraw/math"; } from "@excalidraw/math";
import { getCurvePathOps } from "@excalidraw/utils/geometry/shape"; import { getCurvePathOps } from "@excalidraw/utils/geometry/shape";
import rough from "roughjs/bin/rough"; import { generateRoughOptions } from "@excalidraw/excalidraw/scene/Shape";
import { ShapeCache } from "@excalidraw/excalidraw/scene/ShapeCache";
import type { import type {
Degrees, Degrees,
@ -17,10 +23,9 @@ import type {
Radians, Radians,
} from "@excalidraw/math"; } from "@excalidraw/math";
import { rescalePoints } from "@excalidraw/excalidraw/points"; import type { AppState } from "@excalidraw/excalidraw/types";
import { generateRoughOptions } from "@excalidraw/excalidraw/scene/Shape";
import { ShapeCache } from "@excalidraw/excalidraw/scene/ShapeCache"; import type { Mutable } from "@excalidraw/excalidraw/utility-types";
import { arrayToMap, invariant } from "@excalidraw/excalidraw/utils";
import { LinearElementEditor } from "./linearElementEditor"; import { LinearElementEditor } from "./linearElementEditor";
import { getBoundTextElement, getContainerElement } from "./textElement"; import { getBoundTextElement, getContainerElement } from "./textElement";
@ -32,8 +37,6 @@ import {
isTextElement, isTextElement,
} from "./typeChecks"; } from "./typeChecks";
import type { AppState } from "../types";
import type { Mutable } from "../utility-types";
import type { import type {
ExcalidrawElement, ExcalidrawElement,
ExcalidrawLinearElement, ExcalidrawLinearElement,

View file

@ -1,3 +1,4 @@
import { isTransparent } from "@excalidraw/common";
import { import {
curveIntersectLineSegment, curveIntersectLineSegment,
isPointWithinBounds, isPointWithinBounds,
@ -8,13 +9,17 @@ import {
pointRotateRads, pointRotateRads,
pointsEqual, pointsEqual,
} from "@excalidraw/math"; } from "@excalidraw/math";
import { import {
ellipse, ellipse,
ellipseLineIntersectionPoints, ellipseLineIntersectionPoints,
} from "@excalidraw/math/ellipse"; } from "@excalidraw/math/ellipse";
import { isPointInShape, isPointOnShape } from "@excalidraw/utils/collision"; import { isPointInShape, isPointOnShape } from "@excalidraw/utils/collision";
import { getPolygonShape } from "@excalidraw/utils/geometry/shape"; import { getPolygonShape } from "@excalidraw/utils/geometry/shape";
import { getBoundTextShape, isPathALoop } from "@excalidraw/element/shapes";
import type { import type {
GlobalPoint, GlobalPoint,
LineSegment, LineSegment,
@ -22,10 +27,10 @@ import type {
Polygon, Polygon,
Radians, Radians,
} from "@excalidraw/math"; } from "@excalidraw/math";
import type { GeometricShape } from "@excalidraw/utils/geometry/shape"; import type { GeometricShape } from "@excalidraw/utils/geometry/shape";
import { getBoundTextShape, isPathALoop } from "../shapes"; import type { FrameNameBounds } from "@excalidraw/excalidraw/types";
import { isTransparent } from "../utils";
import { getElementBounds } from "./bounds"; import { getElementBounds } from "./bounds";
import { import {
@ -47,7 +52,6 @@ import type {
ExcalidrawRectangleElement, ExcalidrawRectangleElement,
ExcalidrawRectanguloidElement, ExcalidrawRectanguloidElement,
} from "./types"; } from "./types";
import type { FrameNameBounds } from "../types";
export const shouldTestInside = (element: ExcalidrawElement) => { export const shouldTestInside = (element: ExcalidrawElement) => {
if (element.type === "arrow") { if (element.type === "arrow") {

View file

@ -4,6 +4,7 @@ import {
pointFrom, pointFrom,
pointRotateRads, pointRotateRads,
} from "@excalidraw/math"; } from "@excalidraw/math";
import { ellipse, ellipseDistanceFromPoint } from "@excalidraw/math/ellipse"; import { ellipse, ellipseDistanceFromPoint } from "@excalidraw/math/ellipse";
import type { GlobalPoint, Radians } from "@excalidraw/math"; import type { GlobalPoint, Radians } from "@excalidraw/math";

View file

@ -1,6 +1,17 @@
import { TEXT_AUTOWRAP_THRESHOLD } from "../constants"; import {
import { getGridPoint } from "../snapping"; TEXT_AUTOWRAP_THRESHOLD,
import { getFontString } from "../utils"; getGridPoint,
getFontString,
} from "@excalidraw/common";
import type {
AppState,
NormalizedZoomValue,
NullableGridSize,
PointerDownState,
} from "@excalidraw/excalidraw/types";
import type Scene from "@excalidraw/excalidraw/scene/Scene";
import { updateBoundElements } from "./binding"; import { updateBoundElements } from "./binding";
import { getCommonBounds } from "./bounds"; import { getCommonBounds } from "./bounds";
@ -18,13 +29,6 @@ import {
import type { Bounds } from "./bounds"; import type { Bounds } from "./bounds";
import type { NonDeletedExcalidrawElement } from "./types"; import type { NonDeletedExcalidrawElement } from "./types";
import type Scene from "../scene/Scene";
import type {
AppState,
NormalizedZoomValue,
NullableGridSize,
PointerDownState,
} from "../types";
export const dragSelectedElements = ( export const dragSelectedElements = (
pointerDownState: PointerDownState, pointerDownState: PointerDownState,

View file

@ -13,10 +13,17 @@ import {
type LocalPoint, type LocalPoint,
} from "@excalidraw/math"; } from "@excalidraw/math";
import BinaryHeap from "../binaryheap"; import {
import { getSizeFromPoints } from "../points"; BinaryHeap,
import { aabbForElement, pointInsideBounds } from "../shapes"; invariant,
import { invariant, isAnyTrue, tupleToCoors } from "../utils"; isAnyTrue,
tupleToCoors,
getSizeFromPoints,
} from "@excalidraw/common";
import { aabbForElement, pointInsideBounds } from "@excalidraw/element";
import type { AppState } from "@excalidraw/excalidraw/types";
import { import {
bindPointToSnapToElementOutline, bindPointToSnapToElementOutline,
@ -57,7 +64,6 @@ import type {
FixedSegment, FixedSegment,
NonDeletedExcalidrawElement, NonDeletedExcalidrawElement,
} from "./types"; } from "./types";
import type { AppState } from "../types";
type GridAddress = [number, number] & { _brand: "gridaddress" }; type GridAddress = [number, number] & { _brand: "gridaddress" };

View file

@ -2,12 +2,14 @@
* Create and link between shapes. * Create and link between shapes.
*/ */
import { ELEMENT_LINK_KEY } from "../constants"; import {
import { normalizeLink } from "../data/url"; ELEMENT_LINK_KEY,
import { elementsAreInSameGroup } from "../groups"; normalizeLink,
elementsAreInSameGroup,
} from "@excalidraw/common";
import type { AppProps, AppState } from "../types"; import type { AppProps, AppState } from "@excalidraw/excalidraw/types";
import type { ExcalidrawElement } from "./types"; import type { ExcalidrawElement } from "@excalidraw/element/types";
export const defaultGetElementLinkFromSelection: Exclude< export const defaultGetElementLinkFromSelection: Exclude<
AppProps["generateLinkForSelection"], AppProps["generateLinkForSelection"],

View file

@ -1,12 +1,17 @@
import { FONT_FAMILY, VERTICAL_ALIGN } from "../constants"; import {
import { escapeDoubleQuotes, getFontString } from "../utils"; FONT_FAMILY,
VERTICAL_ALIGN,
escapeDoubleQuotes,
getFontString,
} from "@excalidraw/common";
import type { ExcalidrawProps } from "@excalidraw/excalidraw/types";
import type { MarkRequired } from "@excalidraw/excalidraw/utility-types";
import { newTextElement } from "./newElement"; import { newTextElement } from "./newElement";
import { wrapText } from "./textWrapping"; import { wrapText } from "./textWrapping";
import { isIframeElement } from "./typeChecks"; import { isIframeElement } from "./typeChecks";
import type { ExcalidrawProps } from "../types";
import type { MarkRequired } from "../utility-types";
import type { import type {
ExcalidrawElement, ExcalidrawElement,
ExcalidrawIframeLikeElement, ExcalidrawIframeLikeElement,

View file

@ -1,9 +1,14 @@
import { pointFrom, type LocalPoint } from "@excalidraw/math"; import {
elementOverlapsWithFrame,
elementsAreInFrameBounds,
} from "@excalidraw/element";
import { KEYS, invariant, toBrandedType } from "@excalidraw/common";
import { aabbForElement } from "@excalidraw/element";
import { elementOverlapsWithFrame, elementsAreInFrameBounds } from "../frame"; import type {
import { KEYS } from "../keys"; AppState,
import { aabbForElement } from "../shapes"; PendingExcalidrawElements,
import { invariant, toBrandedType } from "../utils"; } from "@excalidraw/excalidraw/types";
import { bindLinearElement } from "./binding"; import { bindLinearElement } from "./binding";
import { updateElbowArrowPoints } from "./elbowArrow"; import { updateElbowArrowPoints } from "./elbowArrow";
@ -35,8 +40,6 @@ import {
type OrderedExcalidrawElement, type OrderedExcalidrawElement,
} from "./types"; } from "./types";
import type { AppState, PendingExcalidrawElements } from "../types";
type LinkDirection = "up" | "right" | "down" | "left"; type LinkDirection = "up" | "right" | "down" | "left";
const VERTICAL_OFFSET = 100; const VERTICAL_OFFSET = 100;

View file

@ -1,24 +1,22 @@
import { arrayToMap } from "@excalidraw/common";
import { isPointWithinBounds, pointFrom } from "@excalidraw/math"; import { isPointWithinBounds, pointFrom } from "@excalidraw/math";
import { import {
doLineSegmentsIntersect, doLineSegmentsIntersect,
elementsOverlappingBBox, elementsOverlappingBBox,
getCommonBounds,
} from "@excalidraw/utils"; } from "@excalidraw/utils";
import { import {
getCommonBounds, getElementsInGroup,
getElementAbsoluteCoords, selectGroupsFromGivenElements,
isTextElement, } from "@excalidraw/excalidraw/groups";
} from "./element";
import { getElementLineSegments } from "./element/bounds";
import { mutateElement } from "./element/mutateElement";
import { import {
getBoundTextElement, getElementsWithinSelection,
getContainerElement, getSelectedElements,
} from "./element/textElement"; } from "@excalidraw/excalidraw/scene";
import { isFrameElement, isFrameLikeElement } from "./element/typeChecks";
import { getElementsInGroup, selectGroupsFromGivenElements } from "../excalidraw/groups"; import { getElementAbsoluteCoords, isTextElement } from "@excalidraw/element";
import { getElementsWithinSelection, getSelectedElements } from "../excalidraw/scene";
import { arrayToMap } from "./utils";
import type { import type {
ElementsMap, ElementsMap,
@ -27,14 +25,22 @@ import type {
ExcalidrawFrameLikeElement, ExcalidrawFrameLikeElement,
NonDeleted, NonDeleted,
NonDeletedExcalidrawElement, NonDeletedExcalidrawElement,
} from "./element/types"; } from "@excalidraw/element/types";
import type { ExcalidrawElementsIncludingDeleted } from "../excalidraw/scene/Scene";
import type { ExcalidrawElementsIncludingDeleted } from "@excalidraw/excalidraw/scene/Scene";
import type { import type {
AppClassProperties, AppClassProperties,
AppState, AppState,
StaticCanvasAppState, StaticCanvasAppState,
} from "../excalidraw/types"; } from "@excalidraw/excalidraw/types";
import type { ReadonlySetLike } from "../excalidraw/utility-types";
import type { ReadonlySetLike } from "@excalidraw/excalidraw/utility-types";
import { getElementLineSegments } from "./bounds";
import { mutateElement } from "./mutateElement";
import { getBoundTextElement, getContainerElement } from "./textElement";
import { isFrameElement, isFrameLikeElement } from "./typeChecks";
// --------------------------- Frame State ------------------------------------ // --------------------------- Frame State ------------------------------------
export const bindElementsToFramesAfterDuplication = ( export const bindElementsToFramesAfterDuplication = (
@ -99,6 +105,59 @@ export const getElementsCompletelyInFrame = (
element.frameId === frame.id, element.frameId === frame.id,
); );
export const isElementContainingFrame = (
element: ExcalidrawElement,
frame: ExcalidrawFrameLikeElement,
elementsMap: ElementsMap,
) => {
return getElementsWithinSelection([frame], element, elementsMap).some(
(e) => e.id === frame.id,
);
};
export const getElementsIntersectingFrame = (
elements: readonly ExcalidrawElement[],
frame: ExcalidrawFrameLikeElement,
) => {
const elementsMap = arrayToMap(elements);
return elements.filter((element) =>
isElementIntersectingFrame(element, frame, elementsMap),
);
};
export const elementsAreInFrameBounds = (
elements: readonly ExcalidrawElement[],
frame: ExcalidrawFrameLikeElement,
elementsMap: ElementsMap,
) => {
const [frameX1, frameY1, frameX2, frameY2] = getElementAbsoluteCoords(
frame,
elementsMap,
);
const [elementX1, elementY1, elementX2, elementY2] =
getCommonBounds(elements);
return (
frameX1 <= elementX1 &&
frameY1 <= elementY1 &&
frameX2 >= elementX2 &&
frameY2 >= elementY2
);
};
export const elementOverlapsWithFrame = (
element: ExcalidrawElement,
frame: ExcalidrawFrameLikeElement,
elementsMap: ElementsMap,
) => {
return (
elementsAreInFrameBounds([element], frame, elementsMap) ||
isElementIntersectingFrame(element, frame, elementsMap) ||
isElementContainingFrame(element, frame, elementsMap)
);
};
export const isCursorInFrame = ( export const isCursorInFrame = (
cursorCoords: { cursorCoords: {
x: number; x: number;

View file

@ -2,11 +2,16 @@
// ExcalidrawImageElement & related helpers // ExcalidrawImageElement & related helpers
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
import { MIME_TYPES, SVG_NS } from "../constants"; import { MIME_TYPES, SVG_NS } from "@excalidraw/common";
import type {
AppClassProperties,
DataURL,
BinaryFiles,
} from "@excalidraw/excalidraw/types";
import { isInitializedImageElement } from "./typeChecks"; import { isInitializedImageElement } from "./typeChecks";
import type { AppClassProperties, DataURL, BinaryFiles } from "../types";
import type { import type {
ExcalidrawElement, ExcalidrawElement,
FileId, FileId,

View file

@ -8,22 +8,46 @@ import {
pointDistance, pointDistance,
vectorFromPoint, vectorFromPoint,
} from "@excalidraw/math"; } from "@excalidraw/math";
import { getCurvePathOps } from "@excalidraw/utils/geometry/shape"; import { getCurvePathOps } from "@excalidraw/utils/geometry/shape";
import type { Radians } from "@excalidraw/math"; import {
DRAGGING_THRESHOLD,
KEYS,
shouldRotateWithDiscreteAngle,
getGridPoint,
invariant,
tupleToCoors,
} from "@excalidraw/common";
import { ShapeCache } from "@excalidraw/excalidraw/scene/ShapeCache";
import { DRAGGING_THRESHOLD } from "../constants";
import { KEYS, shouldRotateWithDiscreteAngle } from "../keys";
import { ShapeCache } from "../scene/ShapeCache";
import { import {
getBezierCurveLength, getBezierCurveLength,
getBezierXY, getBezierXY,
getControlPointsForBezierCurve, getControlPointsForBezierCurve,
isPathALoop, isPathALoop,
mapIntervalToBezierT, mapIntervalToBezierT,
} from "../shapes"; } from "@excalidraw/element";
import { getGridPoint } from "../snapping";
import { invariant, tupleToCoors } from "../utils"; import type { Radians } from "@excalidraw/math";
import type Scene from "@excalidraw/excalidraw/scene/Scene";
import type {
AppState,
PointerCoords,
InteractiveCanvasAppState,
AppClassProperties,
NullableGridSize,
Zoom,
} from "@excalidraw/excalidraw/types";
import type { Mutable } from "@excalidraw/excalidraw/utility-types";
import {
getElementAbsoluteCoords,
getLockedLinearCursorAlignSize,
} from "../index";
import { import {
bindOrUnbindLinearElement, bindOrUnbindLinearElement,
@ -40,8 +64,6 @@ import {
isFixedPointBinding, isFixedPointBinding,
} from "./typeChecks"; } from "./typeChecks";
import { getElementAbsoluteCoords, getLockedLinearCursorAlignSize } from ".";
import type { Bounds } from "./bounds"; import type { Bounds } from "./bounds";
import type { import type {
NonDeleted, NonDeleted,
@ -57,17 +79,6 @@ import type {
FixedSegment, FixedSegment,
ExcalidrawElbowArrowElement, ExcalidrawElbowArrowElement,
} from "./types"; } from "./types";
import type Scene from "../scene/Scene";
import type { Store } from "../store";
import type {
AppState,
PointerCoords,
InteractiveCanvasAppState,
AppClassProperties,
NullableGridSize,
Zoom,
} from "../types";
import type { Mutable } from "../utility-types";
const editorMidPointsCache: { const editorMidPointsCache: {
version: number | null; version: number | null;

View file

@ -1,16 +1,21 @@
import {
getSizeFromPoints,
randomInteger,
getUpdatedTimestamp,
toBrandedType,
} from "@excalidraw/common";
import type { Radians } from "@excalidraw/math"; import type { Radians } from "@excalidraw/math";
import { getSizeFromPoints } from "../points"; import type { Mutable } from "@excalidraw/excalidraw/utility-types";
import { randomInteger } from "../random";
import Scene from "../scene/Scene"; import Scene from "../scene/Scene";
import { ShapeCache } from "../scene/ShapeCache"; import { ShapeCache } from "../scene/ShapeCache";
import { getUpdatedTimestamp, toBrandedType } from "../utils";
import { updateElbowArrowPoints } from "./elbowArrow"; import { updateElbowArrowPoints } from "./elbowArrow";
import { isElbowArrow } from "./typeChecks"; import { isElbowArrow } from "./typeChecks";
import type { ExcalidrawElement, NonDeletedSceneElementsMap } from "./types"; import type { ExcalidrawElement, NonDeletedSceneElementsMap } from "./types";
import type { Mutable } from "../utility-types";
export type ElementUpdate<TElement extends ExcalidrawElement> = Omit< export type ElementUpdate<TElement extends ExcalidrawElement> = Omit<
Partial<TElement>, Partial<TElement>,

View file

@ -1,5 +1,3 @@
import type { Radians } from "@excalidraw/math";
import { import {
DEFAULT_ELEMENT_PROPS, DEFAULT_ELEMENT_PROPS,
DEFAULT_FONT_FAMILY, DEFAULT_FONT_FAMILY,
@ -8,16 +6,28 @@ import {
DEFAULT_VERTICAL_ALIGN, DEFAULT_VERTICAL_ALIGN,
ORIG_ID, ORIG_ID,
VERTICAL_ALIGN, VERTICAL_ALIGN,
} from "../constants"; randomInteger,
import { getLineHeight } from "../fonts"; randomId,
import { getNewGroupIdsForDuplication } from "../groups"; getNewGroupIdsForDuplication,
import { randomInteger, randomId } from "../random";
import {
arrayToMap, arrayToMap,
getFontString, getFontString,
getUpdatedTimestamp, getUpdatedTimestamp,
isTestEnv, isTestEnv,
} from "../utils"; } from "@excalidraw/common";
import { getLineHeight } from "@excalidraw/excalidraw/fonts/FontMetadata";
import type { Radians } from "@excalidraw/math";
import type { AppState } from "@excalidraw/excalidraw/types";
import type {
MarkOptional,
Merge,
Mutable,
} from "@excalidraw/excalidraw/utility-types";
import { getElementAbsoluteCoords } from "../index";
import { getResizedElementAbsoluteCoords } from "./bounds"; import { getResizedElementAbsoluteCoords } from "./bounds";
import { bumpVersion, newElementWith } from "./mutateElement"; import { bumpVersion, newElementWith } from "./mutateElement";
@ -25,8 +35,6 @@ import { getBoundTextMaxWidth } from "./textElement";
import { normalizeText, measureText } from "./textMeasurements"; import { normalizeText, measureText } from "./textMeasurements";
import { wrapText } from "./textWrapping"; import { wrapText } from "./textWrapping";
import { getElementAbsoluteCoords } from ".";
import type { import type {
ExcalidrawElement, ExcalidrawElement,
ExcalidrawImageElement, ExcalidrawImageElement,
@ -50,8 +58,6 @@ import type {
FixedSegment, FixedSegment,
ExcalidrawElbowArrowElement, ExcalidrawElbowArrowElement,
} from "./types"; } from "./types";
import type { AppState } from "../types";
import type { MarkOptional, Merge, Mutable } from "../utility-types";
export type ElementConstructorOpts = MarkOptional< export type ElementConstructorOpts = MarkOptional<
Omit<ExcalidrawGenericElement, "id" | "type" | "isDeleted" | "updated">, Omit<ExcalidrawGenericElement, "id" | "type" | "isDeleted" | "updated">,

View file

@ -8,12 +8,21 @@ import {
type LocalPoint, type LocalPoint,
} from "@excalidraw/math"; } from "@excalidraw/math";
import {
MIN_FONT_SIZE,
SHIFT_LOCKING_ANGLE,
isInGroup,
rescalePoints,
getFontString,
} from "@excalidraw/common";
import type { GlobalPoint } from "@excalidraw/math"; import type { GlobalPoint } from "@excalidraw/math";
import { MIN_FONT_SIZE, SHIFT_LOCKING_ANGLE } from "../constants"; import type Scene from "@excalidraw/excalidraw/scene/Scene";
import { isInGroup } from "../groups";
import { rescalePoints } from "../points"; import type { PointerDownState } from "@excalidraw/excalidraw/types";
import { getFontString } from "../utils";
import type { Mutable } from "@excalidraw/excalidraw/utility-types";
import { getArrowLocalFixedPoints, updateBoundElements } from "./binding"; import { getArrowLocalFixedPoints, updateBoundElements } from "./binding";
import { import {
@ -67,9 +76,6 @@ import type {
SceneElementsMap, SceneElementsMap,
ExcalidrawElbowArrowElement, ExcalidrawElbowArrowElement,
} from "./types"; } from "./types";
import type Scene from "../scene/Scene";
import type { PointerDownState } from "../types";
import type { Mutable } from "../utility-types";
// Returns true when transform (resizing/rotation) happened // Returns true when transform (resizing/rotation) happened
export const transformElements = ( export const transformElements = (

View file

@ -5,9 +5,11 @@ import {
type Radians, type Radians,
} from "@excalidraw/math"; } from "@excalidraw/math";
import { SIDE_RESIZING_THRESHOLD } from "@excalidraw/common";
import type { GlobalPoint, LineSegment, LocalPoint } from "@excalidraw/math"; import type { GlobalPoint, LineSegment, LocalPoint } from "@excalidraw/math";
import { SIDE_RESIZING_THRESHOLD } from "../constants"; import type { AppState, Device, Zoom } from "@excalidraw/excalidraw/types";
import { getElementAbsoluteCoords } from "./bounds"; import { getElementAbsoluteCoords } from "./bounds";
import { import {
@ -18,7 +20,6 @@ import {
} from "./transformHandles"; } from "./transformHandles";
import { isImageElement, isLinearElement } from "./typeChecks"; import { isImageElement, isLinearElement } from "./typeChecks";
import type { AppState, Device, Zoom } from "../types";
import type { Bounds } from "./bounds"; import type { Bounds } from "./bounds";
import type { import type {
TransformHandleType, TransformHandleType,

View file

@ -41,7 +41,7 @@ import type {
import type { NormalizedZoomValue, Zoom } from "./types"; import type { NormalizedZoomValue, Zoom } from "./types";
/** /**
* get the pure geometric shape of an excalidraw element * get the pure geometric shape of an excalidraw elementw
* which is then used for hit detection * which is then used for hit detection
*/ */
export const getElementShape = <Point extends GlobalPoint | LocalPoint>( export const getElementShape = <Point extends GlobalPoint | LocalPoint>(

View file

@ -1,6 +1,7 @@
import { getSelectedElements } from "../scene"; import { getSelectedElements } from "@excalidraw/excalidraw/scene";
import type { UIAppState } from "@excalidraw/excalidraw/types";
import type { UIAppState } from "../types";
import type { NonDeletedExcalidrawElement } from "./types"; import type { NonDeletedExcalidrawElement } from "./types";
export const showSelectedShapeActions = ( export const showSelectedShapeActions = (

View file

@ -1,12 +1,15 @@
import { SHIFT_LOCKING_ANGLE } from "../constants"; import {
import { viewportCoordsToSceneCoords } from "../utils"; SHIFT_LOCKING_ANGLE,
viewportCoordsToSceneCoords,
} from "@excalidraw/common";
import type { AppState, Offsets, Zoom } from "@excalidraw/excalidraw/types";
import { getCommonBounds, getElementBounds } from "./bounds"; import { getCommonBounds, getElementBounds } from "./bounds";
import { mutateElement } from "./mutateElement"; import { mutateElement } from "./mutateElement";
import { isFreeDrawElement, isLinearElement } from "./typeChecks"; import { isFreeDrawElement, isLinearElement } from "./typeChecks";
import type { ElementsMap, ExcalidrawElement } from "./types"; import type { ElementsMap, ExcalidrawElement } from "./types";
import type { AppState, Offsets, Zoom } from "../types";
// TODO: remove invisible elements consistently actions, so that invisible elements are not recorded by the store, exported, broadcasted or persisted // TODO: remove invisible elements consistently actions, so that invisible elements are not recorded by the store, exported, broadcasted or persisted
// - perhaps could be as part of a standalone 'cleanup' action, in addition to 'finalize' // - perhaps could be as part of a standalone 'cleanup' action, in addition to 'finalize'

View file

@ -1,4 +1,4 @@
import { arrayToMapWithIndex } from "../utils"; import { arrayToMapWithIndex } from "@excalidraw/common";
import type { ExcalidrawElement } from "./types"; import type { ExcalidrawElement } from "./types";

View file

@ -5,8 +5,15 @@ import {
DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE,
TEXT_ALIGN, TEXT_ALIGN,
VERTICAL_ALIGN, VERTICAL_ALIGN,
} from "../constants"; getFontString,
import { getFontString, arrayToMap } from "../utils"; arrayToMap,
} from "@excalidraw/common";
import type { AppState } from "@excalidraw/excalidraw/types";
import type { ExtractSetType } from "@excalidraw/excalidraw/utility-types";
import { isTextElement } from "../index";
import { import {
resetOriginalContainerCache, resetOriginalContainerCache,
@ -18,8 +25,6 @@ import { measureText } from "./textMeasurements";
import { wrapText } from "./textWrapping"; import { wrapText } from "./textWrapping";
import { isBoundToContainer, isArrowElement } from "./typeChecks"; import { isBoundToContainer, isArrowElement } from "./typeChecks";
import { isTextElement } from ".";
import type { MaybeTransformHandleType } from "./transformHandles"; import type { MaybeTransformHandleType } from "./transformHandles";
import type { import type {
ElementsMap, ElementsMap,
@ -30,8 +35,6 @@ import type {
ExcalidrawTextElementWithContainer, ExcalidrawTextElementWithContainer,
NonDeletedExcalidrawElement, NonDeletedExcalidrawElement,
} from "./types"; } from "./types";
import type { AppState } from "../types";
import type { ExtractSetType } from "../utility-types";
export const redrawTextBoundingBox = ( export const redrawTextBoundingBox = (
textElement: ExcalidrawTextElement, textElement: ExcalidrawTextElement,

View file

@ -2,8 +2,10 @@ import {
BOUND_TEXT_PADDING, BOUND_TEXT_PADDING,
DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE,
DEFAULT_FONT_FAMILY, DEFAULT_FONT_FAMILY,
} from "../constants"; getFontString,
import { getFontString, isTestEnv, normalizeEOL } from "../utils"; isTestEnv,
normalizeEOL,
} from "@excalidraw/common";
import type { FontString, ExcalidrawTextElement } from "./types"; import type { FontString, ExcalidrawTextElement } from "./types";

View file

@ -1,4 +1,4 @@
import { ENV } from "../constants"; import { ENV } from "@excalidraw/common";
import { charWidth, getLineWidth } from "./textMeasurements"; import { charWidth, getLineWidth } from "./textMeasurements";

View file

@ -1,12 +1,18 @@
import { pointFrom, pointRotateRads } from "@excalidraw/math";
import type { Radians } from "@excalidraw/math";
import { import {
DEFAULT_TRANSFORM_HANDLE_SPACING, DEFAULT_TRANSFORM_HANDLE_SPACING,
isAndroid, isAndroid,
isIOS, isIOS,
} from "../constants"; } from "@excalidraw/common";
import { pointFrom, pointRotateRads } from "@excalidraw/math";
import type { Radians } from "@excalidraw/math";
import type {
Device,
InteractiveCanvasAppState,
Zoom,
} from "@excalidraw/excalidraw/types";
import { getElementAbsoluteCoords } from "./bounds"; import { getElementAbsoluteCoords } from "./bounds";
import { import {
@ -16,7 +22,6 @@ import {
isLinearElement, isLinearElement,
} from "./typeChecks"; } from "./typeChecks";
import type { Device, InteractiveCanvasAppState, Zoom } from "../types";
import type { Bounds } from "./bounds"; import type { Bounds } from "./bounds";
import type { import type {
ElementsMap, ElementsMap,

View file

@ -1,8 +1,9 @@
import { ROUNDNESS } from "../constants"; import { ROUNDNESS, assertNever } from "@excalidraw/common";
import { assertNever } from "../utils";
import type { ElementOrToolType } from "@excalidraw/excalidraw/types";
import type { MarkNonNullable } from "@excalidraw/excalidraw/utility-types";
import type { ElementOrToolType } from "../types";
import type { MarkNonNullable } from "../utility-types";
import type { Bounds } from "./bounds"; import type { Bounds } from "./bounds";
import type { import type {
ExcalidrawElement, ExcalidrawElement,

View file

@ -6,13 +6,14 @@ import type {
TEXT_ALIGN, TEXT_ALIGN,
THEME, THEME,
VERTICAL_ALIGN, VERTICAL_ALIGN,
} from "../constants"; } from "@excalidraw/common";
import type { import type {
MakeBrand, MakeBrand,
MarkNonNullable, MarkNonNullable,
Merge, Merge,
ValueOf, ValueOf,
} from "../utility-types"; } from "@excalidraw/excalidraw/utility-types";
export type ChartType = "bar" | "line"; export type ChartType = "bar" | "line";
export type FillStyle = "hachure" | "cross-hatch" | "solid" | "zigzag"; export type FillStyle = "hachure" | "cross-hatch" | "solid" | "zigzag";

View file

@ -12,9 +12,9 @@ import {
import type { Curve, LineSegment } from "@excalidraw/math"; import type { Curve, LineSegment } from "@excalidraw/math";
import { getCornerRadius } from "../shapes"; import { getCornerRadius } from "./shapes";
import { getDiamondPoints } from "."; import { getDiamondPoints } from "./bounds";
import type { import type {
ExcalidrawDiamondElement, ExcalidrawDiamondElement,

View file

@ -1,13 +1,12 @@
import { pointFrom } from "@excalidraw/math"; import { pointFrom } from "@excalidraw/math";
import { arrayToMap, ROUNDNESS } from "@excalidraw/common";
import type { LocalPoint } from "@excalidraw/math"; import type { LocalPoint } from "@excalidraw/math";
import { ROUNDNESS } from "../constants"; import { getElementAbsoluteCoords, getElementBounds } from "../src/bounds";
import { arrayToMap } from "../utils";
import { getElementAbsoluteCoords, getElementBounds } from "./bounds"; import type { ExcalidrawElement, ExcalidrawLinearElement } from "../src/types";
import type { ExcalidrawElement, ExcalidrawLinearElement } from "./types";
const _ce = ({ const _ce = ({
x, x,

View file

@ -1,31 +1,33 @@
import { ARROW_TYPE } from "@excalidraw/common";
import { pointFrom } from "@excalidraw/math"; import { pointFrom } from "@excalidraw/math";
import React from "react"; import { Excalidraw, mutateElement } from "@excalidraw/excalidraw";
import type { LocalPoint } from "@excalidraw/math"; import Scene from "@excalidraw/excalidraw/scene/Scene";
import { actionSelectAll } from "@excalidraw/excalidraw/actions";
import { actionDuplicateSelection } from "@excalidraw/excalidraw/actions/actionDuplicateSelection";
import { API } from "@excalidraw/excalidraw/tests/helpers/api";
import { Pointer, UI } from "@excalidraw/excalidraw/tests/helpers/ui";
import "../../utils/test-utils";
import { actionSelectAll } from "../actions";
import { actionDuplicateSelection } from "../actions/actionDuplicateSelection";
import { ARROW_TYPE } from "../constants";
import { Excalidraw, mutateElement } from "../index";
import Scene from "../scene/Scene";
import { API } from "../tests/helpers/api";
import { Pointer, UI } from "../tests/helpers/ui";
import { import {
act, act,
fireEvent, fireEvent,
GlobalTestState, GlobalTestState,
queryByTestId, queryByTestId,
render, render,
} from "../tests/test-utils"; } from "@excalidraw/excalidraw/tests/test-utils";
import { bindLinearElement } from "./binding"; import { bindLinearElement } from "@excalidraw/element/binding";
import type { LocalPoint } from "@excalidraw/math";
import type { import type {
ExcalidrawArrowElement, ExcalidrawArrowElement,
ExcalidrawBindableElement, ExcalidrawBindableElement,
ExcalidrawElbowArrowElement, ExcalidrawElbowArrowElement,
} from "./types"; } from "@excalidraw/element/types";
import "../../utils/test-utils";
const { h } = window; const { h } = window;

View file

@ -1,9 +1,14 @@
import { Excalidraw } from "../index"; import { KEYS } from "@excalidraw/common";
import { KEYS } from "../keys"; import { reseed } from "@excalidraw/common";
import { reseed } from "../random";
import { API } from "../tests/helpers/api"; import { Excalidraw } from "@excalidraw/excalidraw";
import { UI, Keyboard, Pointer } from "../tests/helpers/ui";
import { render, unmountComponent } from "../tests/test-utils"; import { API } from "@excalidraw/excalidraw/tests/helpers/api";
import { UI, Keyboard, Pointer } from "@excalidraw/excalidraw/tests/helpers/ui";
import {
render,
unmountComponent,
} from "@excalidraw/excalidraw/tests/test-utils";
unmountComponent(); unmountComponent();

View file

@ -1,15 +1,14 @@
import { pointFrom } from "@excalidraw/math"; import { pointFrom } from "@excalidraw/math";
import { FONT_FAMILY, ROUNDNESS, isPrimitive } from "@excalidraw/common";
import { API } from "@excalidraw/excalidraw/tests/helpers/api";
import type { LocalPoint } from "@excalidraw/math"; import type { LocalPoint } from "@excalidraw/math";
import { FONT_FAMILY, ROUNDNESS } from "../constants"; import { mutateElement } from "../src/mutateElement";
import { API } from "../tests/helpers/api"; import { duplicateElement, duplicateElements } from "../src/newElement";
import { isPrimitive } from "../utils";
import { mutateElement } from "./mutateElement"; import type { ExcalidrawLinearElement } from "../src/types";
import { duplicateElement, duplicateElements } from "./newElement";
import type { ExcalidrawLinearElement } from "./types";
const assertCloneObjects = (source: any, clone: any) => { const assertCloneObjects = (source: any, clone: any) => {
for (const key in clone) { for (const key in clone) {

View file

@ -1,8 +1,8 @@
import { vi } from "vitest"; import { vi } from "vitest";
import * as constants from "../constants"; import * as constants from "@excalidraw/common";
import { getPerfectElementSize } from "./sizeHelpers"; import { getPerfectElementSize } from "../src/sizeHelpers";
const EPSILON_DIGITS = 3; const EPSILON_DIGITS = 3;
// Needed so that we can mock the value of constants which is done in // Needed so that we can mock the value of constants which is done in

View file

@ -1,9 +1,9 @@
import { API } from "../tests/helpers/api"; import { API } from "@excalidraw/excalidraw/tests/helpers/api";
import { mutateElement } from "./mutateElement"; import { mutateElement } from "../src/mutateElement";
import { normalizeElementOrder } from "./sortElements"; import { normalizeElementOrder } from "../src/sortElements";
import type { ExcalidrawElement } from "./types"; import type { ExcalidrawElement } from "../src/types";
const assertOrder = ( const assertOrder = (
elements: readonly ExcalidrawElement[], elements: readonly ExcalidrawElement[],

View file

@ -1,17 +1,17 @@
import { getLineHeight } from "@excalidraw/excalidraw/fonts/FontMetadata"; import { getLineHeight } from "@excalidraw/excalidraw/fonts/FontMetadata";
import { API } from "@excalidraw/excalidraw/tests/helpers/api";
import { FONT_FAMILY } from "../constants"; import { FONT_FAMILY } from "@excalidraw/common";
import { API } from "../tests/helpers/api";
import { import {
computeContainerDimensionForBoundText, computeContainerDimensionForBoundText,
getContainerCoords, getContainerCoords,
getBoundTextMaxWidth, getBoundTextMaxWidth,
getBoundTextMaxHeight, getBoundTextMaxHeight,
} from "./textElement"; a} from "../src/textElement";
import { detectLineHeight, getLineHeightInPx } from "./textMeasurements"; import { detectLineHeight, getLineHeightInPx } from "../src/textMeasurements";
import type { ExcalidrawTextElementWithContainer } from "./types"; import type { ExcalidrawTextElementWithContainer } from "../src/types";
describe("Test measureText", () => { describe("Test measureText", () => {
describe("Test getContainerCoords", () => { describe("Test getContainerCoords", () => {

View file

@ -1,6 +1,6 @@
import { wrapText, parseTokens } from "./textWrapping"; import { wrapText, parseTokens } from "../src/textWrapping";
import type { FontString } from "./types"; import type { FontString } from "../src/types";
describe("Test wrapText", () => { describe("Test wrapText", () => {
// font is irrelevant as jsdom does not support FontFace API // font is irrelevant as jsdom does not support FontFace API

View file

@ -1,6 +1,6 @@
import { API } from "../tests/helpers/api"; import { API } from "@excalidraw/excalidraw/tests/helpers/api";
import { hasBoundTextElement } from "./typeChecks"; import { hasBoundTextElement } from "../src/typeChecks";
describe("Test TypeChecks", () => { describe("Test TypeChecks", () => {
describe("Test hasBoundTextElement", () => { describe("Test hasBoundTextElement", () => {

View file

@ -15,7 +15,7 @@
"@excalidraw/common": ["./common/index.ts"], "@excalidraw/common": ["./common/index.ts"],
"@excalidraw/common/*": ["./common/src/*"], "@excalidraw/common/*": ["./common/src/*"],
"@excalidraw/element": ["./element/index.ts"], "@excalidraw/element": ["./element/index.ts"],
"@excalidraw/element/*": ["./element/*"], "@excalidraw/element/*": ["./element/src/*"],
"@excalidraw/excalidraw": ["./excalidraw/index.tsx"], "@excalidraw/excalidraw": ["./excalidraw/index.tsx"],
"@excalidraw/excalidraw/*": ["./excalidraw/*"], "@excalidraw/excalidraw/*": ["./excalidraw/*"],
"@excalidraw/math": ["./math/index.ts"], "@excalidraw/math": ["./math/index.ts"],

View file

@ -24,7 +24,7 @@
"@excalidraw/excalidraw": ["./packages/excalidraw/index.tsx"], "@excalidraw/excalidraw": ["./packages/excalidraw/index.tsx"],
"@excalidraw/excalidraw/*": ["./packages/excalidraw/*"], "@excalidraw/excalidraw/*": ["./packages/excalidraw/*"],
"@excalidraw/element": ["./packages/element/index.ts"], "@excalidraw/element": ["./packages/element/index.ts"],
"@excalidraw/element/*": ["./packages/element/*"], "@excalidraw/element/*": ["./packages/element/src/*"],
"@excalidraw/math": ["./packages/math/index.ts"], "@excalidraw/math": ["./packages/math/index.ts"],
"@excalidraw/math/*": ["./packages/math/src/*"], "@excalidraw/math/*": ["./packages/math/src/*"],
"@excalidraw/utils": ["./packages/utils/index.ts"], "@excalidraw/utils": ["./packages/utils/index.ts"],