chore: bump Prettier to the latest (#4185)

This commit is contained in:
Lipis 2021-11-01 15:24:05 +02:00 committed by GitHub
parent 277ffaacb9
commit 1c7056bdaa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
43 changed files with 226 additions and 284 deletions

View File

@ -69,7 +69,7 @@
"jest-canvas-mock": "2.3.1", "jest-canvas-mock": "2.3.1",
"lint-staged": "11.2.6", "lint-staged": "11.2.6",
"pepjs": "0.5.3", "pepjs": "0.5.3",
"prettier": "2.2.1", "prettier": "2.4.1",
"rewire": "5.0.0" "rewire": "5.0.0"
}, },
"engines": { "engines": {

View File

@ -110,10 +110,8 @@ export const actionDeleteSelected = register({
}; };
} }
let { let { elements: nextElements, appState: nextAppState } =
elements: nextElements, deleteSelectedElements(elements, appState);
appState: nextAppState,
} = deleteSelectedElements(elements, appState);
fixBindingsAfterDeletion( fixBindingsAfterDeletion(
nextElements, nextElements,
elements.filter(({ id }) => appState.selectedElementIds[id]), elements.filter(({ id }) => appState.selectedElementIds[id]),

View File

@ -19,11 +19,8 @@ export const actionFinalize = register({
name: "finalize", name: "finalize",
perform: (elements, appState, _, { canvas, focusContainer }) => { perform: (elements, appState, _, { canvas, focusContainer }) => {
if (appState.editingLinearElement) { if (appState.editingLinearElement) {
const { const { elementId, startBindingElement, endBindingElement } =
elementId, appState.editingLinearElement;
startBindingElement,
endBindingElement,
} = appState.editingLinearElement;
const element = LinearElementEditor.getElement(elementId); const element = LinearElementEditor.getElement(elementId);
if (element) { if (element) {

View File

@ -99,9 +99,8 @@ export const actionGroup = register({
// to the z order of the highest element in the layer stack // to the z order of the highest element in the layer stack
const elementsInGroup = getElementsInGroup(updatedElements, newGroupId); const elementsInGroup = getElementsInGroup(updatedElements, newGroupId);
const lastElementInGroup = elementsInGroup[elementsInGroup.length - 1]; const lastElementInGroup = elementsInGroup[elementsInGroup.length - 1];
const lastGroupElementIndex = updatedElements.lastIndexOf( const lastGroupElementIndex =
lastElementInGroup, updatedElements.lastIndexOf(lastElementInGroup);
);
const elementsAfterGroup = updatedElements.slice(lastGroupElementIndex + 1); const elementsAfterGroup = updatedElements.slice(lastGroupElementIndex + 1);
const elementsBeforeGroup = updatedElements const elementsBeforeGroup = updatedElements
.slice(0, lastGroupElementIndex) .slice(0, lastGroupElementIndex)

View File

@ -96,10 +96,9 @@ const APP_STATE_STORAGE_CONF = (<
/** server (shareLink/collab/...) */ /** server (shareLink/collab/...) */
server: boolean; server: boolean;
}, },
T extends Record<keyof AppState, Values> T extends Record<keyof AppState, Values>,
>( >(config: { [K in keyof T]: K extends keyof AppState ? T[K] : never }) =>
config: { [K in keyof T]: K extends keyof AppState ? T[K] : never }, config)({
) => config)({
theme: { browser: true, export: false, server: false }, theme: { browser: true, export: false, server: false },
collaborators: { browser: false, export: false, server: false }, collaborators: { browser: false, export: false, server: false },
currentChartType: { browser: true, export: false, server: false }, currentChartType: { browser: true, export: false, server: false },
@ -172,7 +171,7 @@ const APP_STATE_STORAGE_CONF = (<
}); });
const _clearAppStateForStorage = < const _clearAppStateForStorage = <
ExportType extends "export" | "browser" | "server" ExportType extends "export" | "browser" | "server",
>( >(
appState: Partial<AppState>, appState: Partial<AppState>,
exportType: ExportType, exportType: ExportType,

View File

@ -794,7 +794,8 @@ class App extends React.Component<AppProps, AppState> {
}; };
public async componentDidMount() { public async componentDidMount() {
this.excalidrawContainerValue.container = this.excalidrawContainerRef.current; this.excalidrawContainerValue.container =
this.excalidrawContainerRef.current;
if ( if (
process.env.NODE_ENV === ENV.TEST || process.env.NODE_ENV === ENV.TEST ||
@ -836,10 +837,8 @@ class App extends React.Component<AppProps, AppState> {
this.resizeObserver = new ResizeObserver(() => { this.resizeObserver = new ResizeObserver(() => {
// compute isMobile state // compute isMobile state
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
const { const { width, height } =
width, this.excalidrawContainerRef.current!.getBoundingClientRect();
height,
} = this.excalidrawContainerRef.current!.getBoundingClientRect();
this.isMobile = this.isMobile =
width < MQ_MAX_WIDTH_PORTRAIT || width < MQ_MAX_WIDTH_PORTRAIT ||
(height < MQ_MAX_HEIGHT_LANDSCAPE && width < MQ_MAX_WIDTH_LANDSCAPE); (height < MQ_MAX_HEIGHT_LANDSCAPE && width < MQ_MAX_WIDTH_LANDSCAPE);
@ -1243,9 +1242,8 @@ class App extends React.Component<AppProps, AppState> {
async (event: ClipboardEvent | null) => { async (event: ClipboardEvent | null) => {
// #686 // #686
const target = document.activeElement; const target = document.activeElement;
const isExcalidrawActive = this.excalidrawContainerRef.current?.contains( const isExcalidrawActive =
target, this.excalidrawContainerRef.current?.contains(target);
);
if (!isExcalidrawActive) { if (!isExcalidrawActive) {
return; return;
} }
@ -2207,7 +2205,10 @@ class App extends React.Component<AppProps, AppState> {
})); }));
this.resetShouldCacheIgnoreZoomDebounced(); this.resetShouldCacheIgnoreZoomDebounced();
} else { } else {
gesture.lastCenter = gesture.initialDistance = gesture.initialScale = null; gesture.lastCenter =
gesture.initialDistance =
gesture.initialScale =
null;
} }
if (isHoldingSpace || isPanning || isDraggingScrollBar) { if (isHoldingSpace || isPanning || isDraggingScrollBar) {
@ -2516,13 +2517,11 @@ class App extends React.Component<AppProps, AppState> {
); );
} }
const onPointerMove = this.onPointerMoveFromPointerDownHandler( const onPointerMove =
pointerDownState, this.onPointerMoveFromPointerDownHandler(pointerDownState);
);
const onPointerUp = this.onPointerUpFromPointerDownHandler( const onPointerUp =
pointerDownState, this.onPointerUpFromPointerDownHandler(pointerDownState);
);
const onKeyDown = this.onKeyDownFromPointerDownHandler(pointerDownState); const onKeyDown = this.onKeyDownFromPointerDownHandler(pointerDownState);
const onKeyUp = this.onKeyUpFromPointerDownHandler(pointerDownState); const onKeyUp = this.onKeyUpFromPointerDownHandler(pointerDownState);
@ -2727,7 +2726,8 @@ class App extends React.Component<AppProps, AppState> {
allHitElements: [], allHitElements: [],
wasAddedToSelection: false, wasAddedToSelection: false,
hasBeenDuplicated: false, hasBeenDuplicated: false,
hasHitCommonBoundingBoxOfSelectedElements: this.isHittingCommonBoundingBoxOfSelectedElements( hasHitCommonBoundingBoxOfSelectedElements:
this.isHittingCommonBoundingBoxOfSelectedElements(
origin, origin,
selectedElements, selectedElements,
), ),
@ -2807,7 +2807,8 @@ class App extends React.Component<AppProps, AppState> {
const elements = this.scene.getElements(); const elements = this.scene.getElements();
const selectedElements = getSelectedElements(elements, this.state); const selectedElements = getSelectedElements(elements, this.state);
if (selectedElements.length === 1 && !this.state.editingLinearElement) { if (selectedElements.length === 1 && !this.state.editingLinearElement) {
const elementWithTransformHandleType = getElementWithTransformHandleType( const elementWithTransformHandleType =
getElementWithTransformHandleType(
elements, elements,
this.state, this.state,
pointerDownState.origin.x, pointerDownState.origin.x,
@ -2890,8 +2891,9 @@ class App extends React.Component<AppProps, AppState> {
); );
const hitElement = pointerDownState.hit.element; const hitElement = pointerDownState.hit.element;
const someHitElementIsSelected = pointerDownState.hit.allHitElements.some( const someHitElementIsSelected =
(element) => this.isASelectedElement(element), pointerDownState.hit.allHitElements.some((element) =>
this.isASelectedElement(element),
); );
if ( if (
(hitElement === null || !someHitElementIsSelected) && (hitElement === null || !someHitElementIsSelected) &&
@ -3554,8 +3556,8 @@ class App extends React.Component<AppProps, AppState> {
? { ? {
// if using ctrl/cmd, select the hitElement only if we // if using ctrl/cmd, select the hitElement only if we
// haven't box-selected anything else // haven't box-selected anything else
[pointerDownState.hit.element [pointerDownState.hit.element.id]:
.id]: !elementsWithinSelection.length, !elementsWithinSelection.length,
} }
: null), : null),
}, },
@ -4429,7 +4431,9 @@ class App extends React.Component<AppProps, AppState> {
// This will only work as of Chrome 86, // This will only work as of Chrome 86,
// but can be safely ignored on older releases. // but can be safely ignored on older releases.
const item = event.dataTransfer.items[0]; const item = event.dataTransfer.items[0];
(file as any).handle = await (item as any).getAsFileSystemHandle(); (file as any).handle = await (
item as any
).getAsFileSystemHandle();
} catch (error: any) { } catch (error: any) {
console.warn(error.name, error.message); console.warn(error.name, error.message);
} }
@ -4551,10 +4555,8 @@ class App extends React.Component<AppProps, AppState> {
const type = element ? "element" : "canvas"; const type = element ? "element" : "canvas";
const container = this.excalidrawContainerRef.current!; const container = this.excalidrawContainerRef.current!;
const { const { top: offsetTop, left: offsetLeft } =
top: offsetTop, container.getBoundingClientRect();
left: offsetLeft,
} = container.getBoundingClientRect();
const left = event.clientX - offsetLeft; const left = event.clientX - offsetLeft;
const top = event.clientY - offsetTop; const top = event.clientY - offsetTop;

View File

@ -13,9 +13,11 @@ export const CheckboxItem: React.FC<{
className={clsx("Checkbox", { "is-checked": checked })} className={clsx("Checkbox", { "is-checked": checked })}
onClick={(event) => { onClick={(event) => {
onChange(!checked); onChange(!checked);
((event.currentTarget as HTMLDivElement).querySelector( (
(event.currentTarget as HTMLDivElement).querySelector(
".Checkbox-box", ".Checkbox-box",
) as HTMLButtonElement).focus(); ) as HTMLButtonElement
).focus();
}} }}
> >
<button className="Checkbox-box" role="checkbox" aria-checked={checked}> <button className="Checkbox-box" role="checkbox" aria-checked={checked}>

View File

@ -426,9 +426,9 @@ const LayerUI = ({
return null; return null;
} }
const createExporter = (type: ExportType): ExportCB => async ( const createExporter =
exportedElements, (type: ExportType): ExportCB =>
) => { async (exportedElements) => {
const fileHandle = await exportCanvas( const fileHandle = await exportCanvas(
type, type,
exportedElements, exportedElements,
@ -709,7 +709,8 @@ const LayerUI = ({
{!viewModeEnabled && ( {!viewModeEnabled && (
<div <div
className={clsx("undo-redo-buttons zen-mode-transition", { className={clsx("undo-redo-buttons zen-mode-transition", {
"layer-ui__wrapper__footer-left--transition-bottom": zenModeEnabled, "layer-ui__wrapper__footer-left--transition-bottom":
zenModeEnabled,
})} })}
> >
{actionManager.renderAction("undo", { size: "small" })} {actionManager.renderAction("undo", { size: "small" })}
@ -723,7 +724,8 @@ const LayerUI = ({
className={clsx( className={clsx(
"layer-ui__wrapper__footer-center zen-mode-transition", "layer-ui__wrapper__footer-center zen-mode-transition",
{ {
"layer-ui__wrapper__footer-left--transition-bottom": zenModeEnabled, "layer-ui__wrapper__footer-left--transition-bottom":
zenModeEnabled,
}, },
)} )}
> >

View File

@ -34,10 +34,8 @@ const updateTooltip = (
width: itemWidth, width: itemWidth,
} = item.getBoundingClientRect(); } = item.getBoundingClientRect();
const { const { width: labelWidth, height: labelHeight } =
width: labelWidth, tooltip.getBoundingClientRect();
height: labelHeight,
} = tooltip.getBoundingClientRect();
const viewportWidth = window.innerWidth; const viewportWidth = window.innerWidth;
const viewportHeight = window.innerHeight; const viewportHeight = window.innerHeight;

View File

@ -30,8 +30,12 @@ export const createIcon = (
d: string | React.ReactNode, d: string | React.ReactNode,
opts: number | Opts = 512, opts: number | Opts = 512,
) => { ) => {
const { width = 512, height = width, mirror, style } = const {
typeof opts === "number" ? ({ width: opts } as Opts) : opts; width = 512,
height = width,
mirror,
style,
} = typeof opts === "number" ? ({ width: opts } as Opts) : opts;
return ( return (
<svg <svg
aria-hidden="true" aria-hidden="true"

View File

@ -59,7 +59,7 @@ const getFontFamilyByName = (fontFamilyName: string): FontFamilyValues => {
const restoreElementWithProperties = < const restoreElementWithProperties = <
T extends ExcalidrawElement, T extends ExcalidrawElement,
K extends Pick<T, keyof Omit<Required<T>, keyof ExcalidrawElement>> K extends Pick<T, keyof Omit<Required<T>, keyof ExcalidrawElement>>,
>( >(
element: Required<T>, element: Required<T>,
extra: Pick< extra: Pick<
@ -98,11 +98,11 @@ const restoreElementWithProperties = <
boundElementIds: element.boundElementIds ?? [], boundElementIds: element.boundElementIds ?? [],
}; };
return ({ return {
...base, ...base,
...getNormalizedDimensions(base), ...getNormalizedDimensions(base),
...extra, ...extra,
} as unknown) as T; } as unknown as T;
}; };
const restoreElement = ( const restoreElement = (
@ -113,10 +113,9 @@ const restoreElement = (
let fontSize = element.fontSize; let fontSize = element.fontSize;
let fontFamily = element.fontFamily; let fontFamily = element.fontFamily;
if ("font" in element) { if ("font" in element) {
const [fontPx, _fontFamily]: [ const [fontPx, _fontFamily]: [string, string] = (
string, element as any
string, ).font.split(" ");
] = (element as any).font.split(" ");
fontSize = parseInt(fontPx, 10); fontSize = parseInt(fontPx, 10);
fontFamily = getFontFamilyByName(_fontFamily); fontFamily = getFontFamilyByName(_fontFamily);
} }

View File

@ -137,9 +137,8 @@ export const bindOrUnbindSelectedElements = (
const maybeBindBindableElement = ( const maybeBindBindableElement = (
bindableElement: NonDeleted<ExcalidrawBindableElement>, bindableElement: NonDeleted<ExcalidrawBindableElement>,
): void => { ): void => {
getElligibleElementsForBindableElementAndWhere( getElligibleElementsForBindableElementAndWhere(bindableElement).forEach(
bindableElement, ([linearElement, where]) =>
).forEach(([linearElement, where]) =>
bindOrUnbindLinearElement( bindOrUnbindLinearElement(
linearElement, linearElement,
where === "end" ? "keep" : bindableElement, where === "end" ? "keep" : bindableElement,
@ -293,9 +292,11 @@ export const updateBoundElements = (
const simultaneouslyUpdatedElementIds = getSimultaneouslyUpdatedElementIds( const simultaneouslyUpdatedElementIds = getSimultaneouslyUpdatedElementIds(
simultaneouslyUpdated, simultaneouslyUpdated,
); );
(Scene.getScene(changedElement)!.getNonDeletedElements( (
Scene.getScene(changedElement)!.getNonDeletedElements(
boundElementIds, boundElementIds,
) as NonDeleted<ExcalidrawLinearElement>[]).forEach((linearElement) => { ) as NonDeleted<ExcalidrawLinearElement>[]
).forEach((linearElement) => {
const bindableElement = changedElement as ExcalidrawBindableElement; const bindableElement = changedElement as ExcalidrawBindableElement;
// In case the boundElementIds are stale // In case the boundElementIds are stale
if (!doesNeedUpdate(linearElement, bindableElement)) { if (!doesNeedUpdate(linearElement, bindableElement)) {
@ -580,9 +581,11 @@ export const fixBindingsAfterDuplication = (
}); });
// Update the linear elements // Update the linear elements
(sceneElements.filter(({ id }) => (
sceneElements.filter(({ id }) =>
allBoundElementIds.has(id), allBoundElementIds.has(id),
) as ExcalidrawLinearElement[]).forEach((element) => { ) as ExcalidrawLinearElement[]
).forEach((element) => {
const { startBinding, endBinding } = element; const { startBinding, endBinding } = element;
mutateElement(element, { mutateElement(element, {
startBinding: newBindingAfterDuplication( startBinding: newBindingAfterDuplication(
@ -642,17 +645,17 @@ export const fixBindingsAfterDeletion = (
}); });
} }
}); });
(sceneElements.filter(({ id }) => (
sceneElements.filter(({ id }) =>
boundElementIds.has(id), boundElementIds.has(id),
) as ExcalidrawLinearElement[]).forEach( ) as ExcalidrawLinearElement[]
(element: ExcalidrawLinearElement) => { ).forEach((element: ExcalidrawLinearElement) => {
const { startBinding, endBinding } = element; const { startBinding, endBinding } = element;
mutateElement(element, { mutateElement(element, {
startBinding: newBindingAfterDeletion(startBinding, deletedElementIds), startBinding: newBindingAfterDeletion(startBinding, deletedElementIds),
endBinding: newBindingAfterDeletion(endBinding, deletedElementIds), endBinding: newBindingAfterDeletion(endBinding, deletedElementIds),
}); });
}, });
);
}; };
const newBindingAfterDeletion = ( const newBindingAfterDeletion = (

View File

@ -78,7 +78,7 @@ const getMinMaxXYFromCurvePathOps = (
// move, bcurveTo, lineTo, and curveTo // move, bcurveTo, lineTo, and curveTo
if (op === "move") { if (op === "move") {
// change starting point // change starting point
currentP = (data as unknown) as Point; currentP = data as unknown as Point;
// move operation does not draw anything; so, it always // move operation does not draw anything; so, it always
// returns false // returns false
} else if (op === "bcurveTo") { } else if (op === "bcurveTo") {
@ -227,7 +227,7 @@ export const getArrowheadPoints = (
const prevOp = ops[index - 1]; const prevOp = ops[index - 1];
let p0: Point = [0, 0]; let p0: Point = [0, 0];
if (prevOp.op === "move") { if (prevOp.op === "move") {
p0 = (prevOp.data as unknown) as Point; p0 = prevOp.data as unknown as Point;
} else if (prevOp.op === "bcurveTo") { } else if (prevOp.op === "bcurveTo") {
p0 = [prevOp.data[4], prevOp.data[5]]; p0 = [prevOp.data[4], prevOp.data[5]];
} }

View File

@ -866,7 +866,7 @@ const hitTestRoughShape = (
// move, bcurveTo, lineTo, and curveTo // move, bcurveTo, lineTo, and curveTo
if (op === "move") { if (op === "move") {
// change starting point // change starting point
currentP = (data as unknown) as Point; currentP = data as unknown as Point;
// move operation does not draw anything; so, it always // move operation does not draw anything; so, it always
// returns false // returns false
} else if (op === "bcurveTo") { } else if (op === "bcurveTo") {

View File

@ -150,9 +150,8 @@ export class LinearElementEditor {
) )
: null; : null;
binding = { binding = {
[activePointIndex === 0 [activePointIndex === 0 ? "startBindingElement" : "endBindingElement"]:
? "startBindingElement" bindingElement,
: "endBindingElement"]: bindingElement,
}; };
} }
return { return {
@ -236,10 +235,8 @@ export class LinearElementEditor {
// from the end points of the `linearElement` - this is to allow disabling // from the end points of the `linearElement` - this is to allow disabling
// binding (which needs to happen at the point the user finishes moving // binding (which needs to happen at the point the user finishes moving
// the point). // the point).
const { const { startBindingElement, endBindingElement } =
startBindingElement, appState.editingLinearElement;
endBindingElement,
} = appState.editingLinearElement;
if (isBindingEnabled(appState) && isBindingElement(element)) { if (isBindingEnabled(appState) && isBindingElement(element)) {
bindOrUnbindLinearElement( bindOrUnbindLinearElement(
element, element,

View File

@ -464,12 +464,8 @@ export const resizeSingleElement = (
} }
} }
const [ const [newBoundsX1, newBoundsY1, newBoundsX2, newBoundsY2] =
newBoundsX1, getResizedElementAbsoluteCoords(
newBoundsY1,
newBoundsX2,
newBoundsY2,
] = getResizedElementAbsoluteCoords(
stateAtResizeStart, stateAtResizeStart,
eleNewWidth, eleNewWidth,
eleNewHeight, eleNewHeight,

View File

@ -36,10 +36,8 @@ export const resizeTest = (
return false; return false;
} }
const { const { rotation: rotationTransformHandle, ...transformHandles } =
rotation: rotationTransformHandle, getTransformHandles(element, zoom, pointerType);
...transformHandles
} = getTransformHandles(element, zoom, pointerType);
if ( if (
rotationTransformHandle && rotationTransformHandle &&
@ -49,9 +47,8 @@ export const resizeTest = (
} }
const filter = Object.keys(transformHandles).filter((key) => { const filter = Object.keys(transformHandles).filter((key) => {
const transformHandle = transformHandles[ const transformHandle =
key as Exclude<TransformHandleType, "rotation"> transformHandles[key as Exclude<TransformHandleType, "rotation">]!;
]!;
if (!transformHandle) { if (!transformHandle) {
return false; return false;
} }
@ -105,9 +102,8 @@ export const getTransformHandleTypeFromCoords = (
); );
const found = Object.keys(transformHandles).find((key) => { const found = Object.keys(transformHandles).find((key) => {
const transformHandle = transformHandles[ const transformHandle =
key as Exclude<TransformHandleType, "rotation"> transformHandles[key as Exclude<TransformHandleType, "rotation">]!;
]!;
return ( return (
transformHandle && transformHandle &&
isInsideTransformHandle(transformHandle, scenePointerX, scenePointerY) isInsideTransformHandle(transformHandle, scenePointerX, scenePointerY)

View File

@ -17,9 +17,9 @@ export type TransformHandleDirection =
export type TransformHandleType = TransformHandleDirection | "rotation"; export type TransformHandleType = TransformHandleDirection | "rotation";
export type TransformHandle = [number, number, number, number]; export type TransformHandle = [number, number, number, number];
export type TransformHandles = Partial< export type TransformHandles = Partial<{
{ [T in TransformHandleType]: TransformHandle } [T in TransformHandleType]: TransformHandle;
>; }>;
export type MaybeTransformHandleType = TransformHandleType | false; export type MaybeTransformHandleType = TransformHandleType | false;
const transformHandleSizes: { [k in PointerType]: number } = { const transformHandleSizes: { [k in PointerType]: number } = {

View File

@ -419,12 +419,8 @@ class CollabWrapper extends PureComponent<Props, CollabState> {
); );
break; break;
case "MOUSE_LOCATION": { case "MOUSE_LOCATION": {
const { const { pointer, button, username, selectedElementIds } =
pointer, decryptedData.payload;
button,
username,
selectedElementIds,
} = decryptedData.payload;
const socketId: SocketUpdateDataSource["MOUSE_LOCATION"]["payload"]["socketId"] = const socketId: SocketUpdateDataSource["MOUSE_LOCATION"]["payload"]["socketId"] =
decryptedData.payload.socketId || decryptedData.payload.socketId ||
// @ts-ignore legacy, see #2094 (#2097) // @ts-ignore legacy, see #2094 (#2097)
@ -503,10 +499,8 @@ class CollabWrapper extends PureComponent<Props, CollabState> {
}; };
private loadImageFiles = throttle(async () => { private loadImageFiles = throttle(async () => {
const { const { loadedFiles, erroredFiles } =
loadedFiles, await this.fetchImageFilesFromFirebase({
erroredFiles,
} = await this.fetchImageFilesFromFirebase({
elements: this.excalidrawAPI.getSceneElementsIncludingDeleted(), elements: this.excalidrawAPI.getSceneElementsIncludingDeleted(),
}); });
@ -591,9 +585,8 @@ class CollabWrapper extends PureComponent<Props, CollabState> {
setCollaborators(sockets: string[]) { setCollaborators(sockets: string[]) {
this.setState((state) => { this.setState((state) => {
const collaborators: InstanceType< const collaborators: InstanceType<typeof CollabWrapper>["collaborators"] =
typeof CollabWrapper new Map();
>["collaborators"] = new Map();
for (const socketId of sockets) { for (const socketId of sockets) {
if (this.collaborators.has(socketId)) { if (this.collaborators.has(socketId)) {
collaborators.set(socketId, this.collaborators.get(socketId)!); collaborators.set(socketId, this.collaborators.get(socketId)!);
@ -695,7 +688,8 @@ class CollabWrapper extends PureComponent<Props, CollabState> {
this.contextValue.initializeSocketClient = this.initializeSocketClient; this.contextValue.initializeSocketClient = this.initializeSocketClient;
this.contextValue.onCollabButtonClick = this.onCollabButtonClick; this.contextValue.onCollabButtonClick = this.onCollabButtonClick;
this.contextValue.broadcastElements = this.broadcastElements; this.contextValue.broadcastElements = this.broadcastElements;
this.contextValue.fetchImageFilesFromFirebase = this.fetchImageFilesFromFirebase; this.contextValue.fetchImageFilesFromFirebase =
this.fetchImageFilesFromFirebase;
return this.contextValue; return this.contextValue;
}; };

View File

@ -210,8 +210,8 @@ class Portal {
socketId: this.socket.id, socketId: this.socket.id,
pointer: payload.pointer, pointer: payload.pointer,
button: payload.button || "up", button: payload.button || "up",
selectedElementIds: this.collab.excalidrawAPI.getAppState() selectedElementIds:
.selectedElementIds, this.collab.excalidrawAPI.getAppState().selectedElementIds,
username: this.collab.state.username, username: this.collab.state.username,
}, },
}; };

View File

@ -54,9 +54,8 @@ export const reconcileElements = (
remoteElements: readonly BroadcastedExcalidrawElement[], remoteElements: readonly BroadcastedExcalidrawElement[],
localAppState: AppState, localAppState: AppState,
): ReconciledElements => { ): ReconciledElements => {
const localElementsData = getElementsMapWithIndex<ExcalidrawElement>( const localElementsData =
localElements, getElementsMapWithIndex<ExcalidrawElement>(localElements);
);
const reconciledElements: ExcalidrawElement[] = localElements.slice(); const reconciledElements: ExcalidrawElement[] = localElements.slice();

View File

@ -14,9 +14,8 @@ export const GitHubCorner = React.memo(
className="rtl-mirror" className="rtl-mirror"
style={{ style={{
marginTop: "calc(var(--space-factor) * -1)", marginTop: "calc(var(--space-factor) * -1)",
[dir === "rtl" [dir === "rtl" ? "marginLeft" : "marginRight"]:
? "marginLeft" "calc(var(--space-factor) * -1)",
: "marginRight"]: "calc(var(--space-factor) * -1)",
}} }}
> >
<a <a

View File

@ -31,15 +31,11 @@ export class FileManager {
getFiles, getFiles,
saveFiles, saveFiles,
}: { }: {
getFiles: ( getFiles: (fileIds: FileId[]) => Promise<{
fileIds: FileId[],
) => Promise<{
loadedFiles: BinaryFileData[]; loadedFiles: BinaryFileData[];
erroredFiles: Map<FileId, true>; erroredFiles: Map<FileId, true>;
}>; }>;
saveFiles: (data: { saveFiles: (data: { addedFiles: Map<FileId, BinaryFileData> }) => Promise<{
addedFiles: Map<FileId, BinaryFileData>;
}) => Promise<{
savedFiles: Map<FileId, true>; savedFiles: Map<FileId, true>;
erroredFiles: Map<FileId, true>; erroredFiles: Map<FileId, true>;
}>; }>;

View File

@ -13,9 +13,8 @@ import { MIME_TYPES } from "../../constants";
const FIREBASE_CONFIG = JSON.parse(process.env.REACT_APP_FIREBASE_CONFIG); const FIREBASE_CONFIG = JSON.parse(process.env.REACT_APP_FIREBASE_CONFIG);
let firebasePromise: Promise< let firebasePromise: Promise<typeof import("firebase/app").default> | null =
typeof import("firebase/app").default null;
> | null = null;
let firestorePromise: Promise<any> | null | true = null; let firestorePromise: Promise<any> | null | true = null;
let firebaseStoragePromise: Promise<any> | null | true = null; let firebaseStoragePromise: Promise<any> | null | true = null;

View File

@ -78,7 +78,8 @@ export type SocketUpdateDataIncoming =
type: "INVALID_RESPONSE"; type: "INVALID_RESPONSE";
}; };
export type SocketUpdateData = SocketUpdateDataSource[keyof SocketUpdateDataSource] & { export type SocketUpdateData =
SocketUpdateDataSource[keyof SocketUpdateDataSource] & {
_brand: "socketUpdateData"; _brand: "socketUpdateData";
}; };

View File

@ -286,7 +286,8 @@ const ExcalidrawWrapper = () => {
promise: ResolvablePromise<ImportedDataState | null>; promise: ResolvablePromise<ImportedDataState | null>;
}>({ promise: null! }); }>({ promise: null! });
if (!initialStatePromiseRef.current.promise) { if (!initialStatePromiseRef.current.promise) {
initialStatePromiseRef.current.promise = resolvablePromise<ImportedDataState | null>(); initialStatePromiseRef.current.promise =
resolvablePromise<ImportedDataState | null>();
} }
useEffect(() => { useEffect(() => {
@ -296,10 +297,8 @@ const ExcalidrawWrapper = () => {
}, VERSION_TIMEOUT); }, VERSION_TIMEOUT);
}, []); }, []);
const [ const [excalidrawAPI, excalidrawRefCallback] =
excalidrawAPI, useCallbackRefState<ExcalidrawImperativeAPI>();
excalidrawRefCallback,
] = useCallbackRefState<ExcalidrawImperativeAPI>();
const collabAPI = useContext(CollabContext)?.api; const collabAPI = useContext(CollabContext)?.api;

View File

@ -67,7 +67,7 @@ export const nvector = (value: number = 0, index: number = 0): NVector => {
if (value !== 0) { if (value !== 0) {
result[index] = value; result[index] = value;
} }
return (result as unknown) as NVector; return result as unknown as NVector;
}; };
const STRING_EPSILON = 0.000001; const STRING_EPSILON = 0.000001;

View File

@ -36,7 +36,7 @@ export const orthogonalThrough = (against: Point, intersection: Point): Line =>
export const parallel = (line: Line, distance: number): Line => { export const parallel = (line: Line, distance: number): Line => {
const result = line.slice(); const result = line.slice();
result[1] -= distance; result[1] -= distance;
return (result as unknown) as Line; return result as unknown as Line;
}; };
export const parallelThrough = (line: Line, point: Point): Line => export const parallelThrough = (line: Line, point: Point): Line =>

7
src/global.d.ts vendored
View File

@ -49,8 +49,7 @@ type MarkRequired<T, RK extends keyof T> = Exclude<T, RK> &
type MarkNonNullable<T, K extends keyof T> = { type MarkNonNullable<T, K extends keyof T> = {
[P in K]-?: P extends K ? NonNullable<T[P]> : T[P]; [P in K]-?: P extends K ? NonNullable<T[P]> : T[P];
} & } & { [P in keyof T]: T[P] };
{ [P in keyof T]: T[P] };
// PNG encoding/decoding // PNG encoding/decoding
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -102,10 +101,10 @@ declare module "*.scss";
// (due to TS structural typing) // (due to TS structural typing)
// https://github.com/microsoft/TypeScript/issues/31311#issuecomment-490690695 // https://github.com/microsoft/TypeScript/issues/31311#issuecomment-490690695
interface ArrayBuffer { interface ArrayBuffer {
private _brand?: "ArrayBuffer"; _brand?: "ArrayBuffer";
} }
interface Uint8Array { interface Uint8Array {
private _brand?: "Uint8Array"; _brand?: "Uint8Array";
} }
// --------------------------------------------------------------------------— // --------------------------------------------------------------------------—

View File

@ -1,7 +1,7 @@
const path = require("path"); const path = require("path");
const TerserPlugin = require("terser-webpack-plugin"); const TerserPlugin = require("terser-webpack-plugin");
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer") const BundleAnalyzerPlugin =
.BundleAnalyzerPlugin; require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
const autoprefixer = require("autoprefixer"); const autoprefixer = require("autoprefixer");
module.exports = { module.exports = {

View File

@ -1,7 +1,7 @@
const webpack = require("webpack"); const webpack = require("webpack");
const path = require("path"); const path = require("path");
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer") const BundleAnalyzerPlugin =
.BundleAnalyzerPlugin; require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
module.exports = { module.exports = {
mode: "production", mode: "production",

View File

@ -398,16 +398,8 @@ const generateElementShape = (
} }
break; break;
case "diamond": { case "diamond": {
const [ const [topX, topY, rightX, rightY, bottomX, bottomY, leftX, leftY] =
topX, getDiamondPoints(element);
topY,
rightX,
rightY,
bottomX,
bottomY,
leftX,
leftY,
] = getDiamondPoints(element);
shape = generator.polygon( shape = generator.polygon(
[ [
[topX, topY], [topX, topY],

View File

@ -336,12 +336,8 @@ export const renderScene = (
); );
} }
if (selectionColors.length) { if (selectionColors.length) {
const [ const [elementX1, elementY1, elementX2, elementY2] =
elementX1, getElementAbsoluteCoords(element);
elementY1,
elementX2,
elementY2,
] = getElementAbsoluteCoords(element);
acc.push({ acc.push({
angle: element.angle, angle: element.angle,
elementX1, elementX1,
@ -356,9 +352,8 @@ export const renderScene = (
const addSelectionForGroupId = (groupId: GroupId) => { const addSelectionForGroupId = (groupId: GroupId) => {
const groupElements = getElementsInGroup(elements, groupId); const groupElements = getElementsInGroup(elements, groupId);
const [elementX1, elementY1, elementX2, elementY2] = getCommonBounds( const [elementX1, elementY1, elementX2, elementY2] =
groupElements, getCommonBounds(groupElements);
);
selections.push({ selections.push({
angle: 0, angle: 0,
elementX1, elementX1,
@ -630,14 +625,8 @@ const renderSelectionBorder = (
selectionColors: string[]; selectionColors: string[];
}, },
) => { ) => {
const { const { angle, elementX1, elementY1, elementX2, elementY2, selectionColors } =
angle, elementProperties;
elementX1,
elementY1,
elementX2,
elementY2,
selectionColors,
} = elementProperties;
const elementWidth = elementX2 - elementX1; const elementWidth = elementX2 - elementX1;
const elementHeight = elementY2 - elementY1; const elementHeight = elementY2 - elementY1;

View File

@ -180,10 +180,9 @@ export const getExportSize = (
exportPadding: number, exportPadding: number,
scale: number, scale: number,
): [number, number] => { ): [number, number] => {
const [, , width, height] = getCanvasSize( const [, , width, height] = getCanvasSize(elements, exportPadding).map(
elements, (dimension) => Math.trunc(dimension * scale),
exportPadding, );
).map((dimension) => Math.trunc(dimension * scale));
return [width, height]; return [width, height];
}; };

View File

@ -30,12 +30,8 @@ export const getScrollBars = (
}; };
} }
// This is the bounding box of all the elements // This is the bounding box of all the elements
const [ const [elementsMinX, elementsMinY, elementsMaxX, elementsMaxY] =
elementsMinX, getCommonBounds(elements);
elementsMinY,
elementsMaxX,
elementsMaxY,
] = getCommonBounds(elements);
// Apply zoom // Apply zoom
const viewportWidthWithZoom = viewportWidth / zoom.value; const viewportWidthWithZoom = viewportWidth / zoom.value;

View File

@ -9,16 +9,11 @@ export const getElementsWithinSelection = (
elements: readonly NonDeletedExcalidrawElement[], elements: readonly NonDeletedExcalidrawElement[],
selection: NonDeletedExcalidrawElement, selection: NonDeletedExcalidrawElement,
) => { ) => {
const [ const [selectionX1, selectionY1, selectionX2, selectionY2] =
selectionX1, getElementAbsoluteCoords(selection);
selectionY1,
selectionX2,
selectionY2,
] = getElementAbsoluteCoords(selection);
return elements.filter((element) => { return elements.filter((element) => {
const [elementX1, elementY1, elementX2, elementY2] = getElementBounds( const [elementX1, elementY1, elementX2, elementY2] =
element, getElementBounds(element);
);
return ( return (
element.type !== "selection" && element.type !== "selection" &&

View File

@ -91,9 +91,8 @@ describe("contextMenu element", () => {
clientY: 1, clientY: 1,
}); });
const contextMenu = queryContextMenu(); const contextMenu = queryContextMenu();
const contextMenuOptions = contextMenu?.querySelectorAll( const contextMenuOptions =
".context-menu li", contextMenu?.querySelectorAll(".context-menu li");
);
const expectedShortcutNames: ShortcutName[] = [ const expectedShortcutNames: ShortcutName[] = [
"selectAll", "selectAll",
"gridMode", "gridMode",
@ -122,9 +121,8 @@ describe("contextMenu element", () => {
clientY: 1, clientY: 1,
}); });
const contextMenu = queryContextMenu(); const contextMenu = queryContextMenu();
const contextMenuOptions = contextMenu?.querySelectorAll( const contextMenuOptions =
".context-menu li", contextMenu?.querySelectorAll(".context-menu li");
);
const expectedShortcutNames: ShortcutName[] = [ const expectedShortcutNames: ShortcutName[] = [
"copyStyles", "copyStyles",
"pasteStyles", "pasteStyles",
@ -210,9 +208,8 @@ describe("contextMenu element", () => {
}); });
const contextMenu = queryContextMenu(); const contextMenu = queryContextMenu();
const contextMenuOptions = contextMenu?.querySelectorAll( const contextMenuOptions =
".context-menu li", contextMenu?.querySelectorAll(".context-menu li");
);
const expectedShortcutNames: ShortcutName[] = [ const expectedShortcutNames: ShortcutName[] = [
"copyStyles", "copyStyles",
"pasteStyles", "pasteStyles",
@ -261,9 +258,8 @@ describe("contextMenu element", () => {
}); });
const contextMenu = queryContextMenu(); const contextMenu = queryContextMenu();
const contextMenuOptions = contextMenu?.querySelectorAll( const contextMenuOptions =
".context-menu li", contextMenu?.querySelectorAll(".context-menu li");
);
const expectedShortcutNames: ShortcutName[] = [ const expectedShortcutNames: ShortcutName[] = [
"copyStyles", "copyStyles",
"pasteStyles", "pasteStyles",

View File

@ -57,7 +57,7 @@ export class API {
}; };
static createElement = < static createElement = <
T extends Exclude<ExcalidrawElement["type"], "selection"> T extends Exclude<ExcalidrawElement["type"], "selection">,
>({ >({
type, type,
id, id,

View File

@ -75,10 +75,10 @@ const test = <U extends `${string}:${"L" | "R"}`>(
const cache: Cache = {}; const cache: Cache = {};
const _local = idsToElements(local, cache); const _local = idsToElements(local, cache);
const _remote = idsToElements(remote, cache); const _remote = idsToElements(remote, cache);
const _target = (target.map((uid) => { const _target = target.map((uid) => {
const [, id, source] = uid.match(/^(\w+):([LR])$/)!; const [, id, source] = uid.match(/^(\w+):([LR])$/)!;
return (source === "L" ? _local : _remote).find((e) => e.id === id)!; return (source === "L" ? _local : _remote).find((e) => e.id === id)!;
}) as any) as ReconciledElements; }) as any as ReconciledElements;
const remoteReconciled = reconcileElements(_local, _remote, {} as AppState); const remoteReconciled = reconcileElements(_local, _remote, {} as AppState);
expect(cleanElements(remoteReconciled)).deep.equal( expect(cleanElements(remoteReconciled)).deep.equal(
cleanElements(_target), cleanElements(_target),

View File

@ -874,14 +874,10 @@ describe("regression tests", () => {
expect(API.getSelectedElements().length).toBe(2); expect(API.getSelectedElements().length).toBe(2);
const { const { x: firstElementPrevX, y: firstElementPrevY } =
x: firstElementPrevX, API.getSelectedElements()[0];
y: firstElementPrevY, const { x: secondElementPrevX, y: secondElementPrevY } =
} = API.getSelectedElements()[0]; API.getSelectedElements()[1];
const {
x: secondElementPrevX,
y: secondElementPrevY,
} = API.getSelectedElements()[1];
// drag elements from point on common bounding box that doesn't hit any of the elements // drag elements from point on common bounding box that doesn't hit any of the elements
mouse.reset(); mouse.reset();

View File

@ -126,7 +126,8 @@ export const mockBoundingClientRect = () => {
}; };
export const restoreOriginalGetBoundingClientRect = () => { export const restoreOriginalGetBoundingClientRect = () => {
global.window.HTMLDivElement.prototype.getBoundingClientRect = originalGetBoundingClientRect; global.window.HTMLDivElement.prototype.getBoundingClientRect =
originalGetBoundingClientRect;
}; };
export const assertSelectedElements = ( export const assertSelectedElements = (

View File

@ -360,7 +360,7 @@ export const resolvablePromise = <T>() => {
* @param func handler taking at most single parameter (event). * @param func handler taking at most single parameter (event).
*/ */
export const withBatchedUpdates = < export const withBatchedUpdates = <
TFunction extends ((event: any) => void) | (() => void) TFunction extends ((event: any) => void) | (() => void),
>( >(
func: Parameters<TFunction>["length"] extends 0 | 1 ? TFunction : never, func: Parameters<TFunction>["length"] extends 0 | 1 ? TFunction : never,
) => ) =>

View File

@ -11783,10 +11783,10 @@ prettier-linter-helpers@^1.0.0:
dependencies: dependencies:
fast-diff "^1.1.2" fast-diff "^1.1.2"
prettier@2.2.1: prettier@2.4.1:
version "2.2.1" version "2.4.1"
resolved "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.4.1.tgz#671e11c89c14a4cfc876ce564106c4a6726c9f5c"
integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q== integrity sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==
pretty-bytes@^5.3.0: pretty-bytes@^5.3.0:
version "5.6.0" version "5.6.0"