diff --git a/packages/excalidraw/actions/actionLinearEditor.tsx b/packages/excalidraw/actions/actionLinearEditor.tsx index 943474313..50d3580e6 100644 --- a/packages/excalidraw/actions/actionLinearEditor.tsx +++ b/packages/excalidraw/actions/actionLinearEditor.tsx @@ -24,6 +24,8 @@ import { import { t } from "../i18n"; import { CaptureUpdateAction } from "../store"; +import { ButtonIcon } from "../components/ButtonIcon"; + import { register } from "./register"; export const actionToggleLinearEditor = register({ @@ -238,8 +240,8 @@ export const actionToggleLoopLock = register({ if ( selectedElements.length === 0 || - !selectedElements.every( - (element) => isLineElement(element) && element.points.length >= 4, + selectedElements.some( + (element) => !isLineElement(element) || element.points.length < 3, ) ) { return null; @@ -255,12 +257,13 @@ export const actionToggleLoopLock = register({ ); return ( - updateData(null)} + style={{ marginLeft: "auto" }} /> ); }, diff --git a/packages/excalidraw/actions/actionProperties.tsx b/packages/excalidraw/actions/actionProperties.tsx index df07960af..1749645ce 100644 --- a/packages/excalidraw/actions/actionProperties.tsx +++ b/packages/excalidraw/actions/actionProperties.tsx @@ -1360,7 +1360,7 @@ export const actionChangeRoundness = register({ captureUpdate: CaptureUpdateAction.IMMEDIATELY, }; }, - PanelComponent: ({ elements, appState, updateData }) => { + PanelComponent: ({ elements, appState, updateData, renderAction }) => { const targetElements = getTargetElements( getNonDeletedElements(elements), appState, @@ -1398,7 +1398,9 @@ export const actionChangeRoundness = register({ hasSelection ? null : appState.currentItemRoundness, )} onChange={(value) => updateData(value)} - /> + > + {renderAction("toggleLoopLock")} + ); }, diff --git a/packages/excalidraw/actions/manager.tsx b/packages/excalidraw/actions/manager.tsx index 171bb5df7..f3314bf35 100644 --- a/packages/excalidraw/actions/manager.tsx +++ b/packages/excalidraw/actions/manager.tsx @@ -179,6 +179,7 @@ export class ActionManager { appProps={this.app.props} app={this.app} data={data} + renderAction={this.renderAction} /> ); } diff --git a/packages/excalidraw/actions/types.ts b/packages/excalidraw/actions/types.ts index cdfdc9131..71cfd7508 100644 --- a/packages/excalidraw/actions/types.ts +++ b/packages/excalidraw/actions/types.ts @@ -151,6 +151,10 @@ export type PanelComponentProps = { appProps: ExcalidrawProps; data?: Record; app: AppClassProperties; + renderAction: ( + name: ActionName, + data?: PanelComponentProps["data"], + ) => React.JSX.Element | null; }; export interface Action { diff --git a/packages/excalidraw/components/Actions.tsx b/packages/excalidraw/components/Actions.tsx index 89dd50ee6..3a7df37a8 100644 --- a/packages/excalidraw/components/Actions.tsx +++ b/packages/excalidraw/components/Actions.tsx @@ -19,7 +19,6 @@ import { isImageElement, isLinearElement, isTextElement, - isLineElement, } from "@excalidraw/element/typeChecks"; import { hasStrokeColor, toolIsArrow } from "@excalidraw/element/comparisons"; @@ -27,7 +26,6 @@ import { hasStrokeColor, toolIsArrow } from "@excalidraw/element/comparisons"; import type { ExcalidrawElement, ExcalidrawElementType, - ExcalidrawLineElement, NonDeletedElementsMap, NonDeletedSceneElementsMap, } from "@excalidraw/element/types"; @@ -147,17 +145,6 @@ export const SelectedShapeActions = ({ isLinearElement(targetElements[0]) && !isElbowArrow(targetElements[0]); - const showLoopLockAction = - targetElements.length > 0 && - isLineElement(targetElements[0]) && - targetElements.every( - (element) => - isLineElement(element) && - element.points.length >= 4 && - element.loopLock === - (targetElements[0] as ExcalidrawLineElement).loopLock, - ); - const showCropEditorAction = !appState.croppingElementId && targetElements.length === 1 && @@ -286,7 +273,6 @@ export const SelectedShapeActions = ({ {showLinkIcon && renderAction("hyperlink")} {showCropEditorAction && renderAction("cropEditor")} {showLineEditorAction && renderAction("toggleLinearEditor")} - {showLoopLockAction && renderAction("toggleLoopLock")} )} diff --git a/packages/excalidraw/components/ButtonIcon.tsx b/packages/excalidraw/components/ButtonIcon.tsx index 27b4dc3d8..77a918b3a 100644 --- a/packages/excalidraw/components/ButtonIcon.tsx +++ b/packages/excalidraw/components/ButtonIcon.tsx @@ -15,6 +15,7 @@ interface ButtonIconProps { /** include standalone style (could interfere with parent styles) */ standalone?: boolean; onClick: (event: React.MouseEvent) => void; + style?: React.CSSProperties; } export const ButtonIcon = forwardRef( @@ -30,6 +31,7 @@ export const ButtonIcon = forwardRef( data-testid={testId} className={clsx(className, { standalone, active })} onClick={onClick} + style={props.style} > {icon} diff --git a/packages/excalidraw/components/ButtonIconSelect.tsx b/packages/excalidraw/components/ButtonIconSelect.tsx index 45665e4ca..6d64396a9 100644 --- a/packages/excalidraw/components/ButtonIconSelect.tsx +++ b/packages/excalidraw/components/ButtonIconSelect.tsx @@ -17,6 +17,7 @@ export const ButtonIconSelect = ( }[]; value: T | null; type?: "radio" | "button"; + children?: React.ReactNode; } & ( | { type?: "radio"; group: string; onChange: (value: T) => void } | { @@ -56,5 +57,6 @@ export const ButtonIconSelect = ( ), )} + {props.children} ); diff --git a/packages/excalidraw/components/icons.tsx b/packages/excalidraw/components/icons.tsx index 2a3a014f8..7ab8e881e 100644 --- a/packages/excalidraw/components/icons.tsx +++ b/packages/excalidraw/components/icons.tsx @@ -130,19 +130,34 @@ export const PinIcon = createIcon( ); export const LoopLockedIcon = createIcon( - - - + + + + + + + + + + + , - modifiedTablerIconProps, + tablerIconProps, ); export const LoopUnlockedIcon = createIcon( - - - + + + + + + + + + + , - modifiedTablerIconProps, + tablerIconProps, ); // tabler-icons: lock-open (via Figma) diff --git a/packages/excalidraw/locales/en.json b/packages/excalidraw/locales/en.json index dda899bb2..445442018 100644 --- a/packages/excalidraw/locales/en.json +++ b/packages/excalidraw/locales/en.json @@ -142,8 +142,8 @@ "editArrow": "Edit arrow" }, "loopLock": { - "unlock": "Unlock loop", - "lock": "Lock loop" + "unlock": "Disable polygon", + "lock": "Make into polygon" }, "elementLock": { "lock": "Lock",