import { getNonDeletedElements } from "@excalidraw/element"; import { isFrameLikeElement } from "@excalidraw/element"; import { updateFrameMembershipOfSelectedElements } from "@excalidraw/element"; import { KEYS, arrayToMap, getShortcutKey } from "@excalidraw/common"; import { alignElements } from "@excalidraw/element"; import { CaptureUpdateAction } from "@excalidraw/element"; import type { ExcalidrawElement } from "@excalidraw/element/types"; import type { Alignment } from "@excalidraw/element"; import { ToolButton } from "../components/ToolButton"; import { AlignBottomIcon, AlignLeftIcon, AlignRightIcon, AlignTopIcon, CenterHorizontallyIcon, CenterVerticallyIcon, } from "../components/icons"; import { t } from "../i18n"; import { isSomeElementSelected } from "../scene"; import { register } from "./register"; import type { AppClassProperties, AppState, UIAppState } from "../types"; export const alignActionsPredicate = ( appState: UIAppState, app: AppClassProperties, ) => { const selectedElements = app.scene.getSelectedElements(appState); return ( selectedElements.length > 1 && // TODO enable aligning frames when implemented properly !selectedElements.some((el) => isFrameLikeElement(el)) ); }; const alignSelectedElements = ( elements: readonly ExcalidrawElement[], appState: Readonly, app: AppClassProperties, alignment: Alignment, ) => { const selectedElements = app.scene.getSelectedElements(appState); const updatedElements = alignElements(selectedElements, alignment, app.scene); const updatedElementsMap = arrayToMap(updatedElements); return updateFrameMembershipOfSelectedElements( elements.map((element) => updatedElementsMap.get(element.id) || element), appState, app, ); }; export const actionAlignTop = register({ name: "alignTop", label: "labels.alignTop", icon: AlignTopIcon, trackEvent: { category: "element" }, predicate: (elements, appState, appProps, app) => alignActionsPredicate(appState, app), perform: (elements, appState, _, app) => { return { appState, elements: alignSelectedElements(elements, appState, app, { position: "start", axis: "y", }), captureUpdate: CaptureUpdateAction.IMMEDIATELY, }; }, keyTest: (event) => event[KEYS.CTRL_OR_CMD] && event.shiftKey && event.key === KEYS.ARROW_UP, PanelComponent: ({ elements, appState, updateData, app }) => (