change icon & turn into a state style button
This commit is contained in:
parent
6aea288dcd
commit
a9a2c953b4
@ -24,6 +24,8 @@ import {
|
|||||||
import { t } from "../i18n";
|
import { t } from "../i18n";
|
||||||
import { CaptureUpdateAction } from "../store";
|
import { CaptureUpdateAction } from "../store";
|
||||||
|
|
||||||
|
import { ButtonIcon } from "../components/ButtonIcon";
|
||||||
|
|
||||||
import { register } from "./register";
|
import { register } from "./register";
|
||||||
|
|
||||||
export const actionToggleLinearEditor = register({
|
export const actionToggleLinearEditor = register({
|
||||||
@ -238,8 +240,8 @@ export const actionToggleLoopLock = register({
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
selectedElements.length === 0 ||
|
selectedElements.length === 0 ||
|
||||||
!selectedElements.every(
|
selectedElements.some(
|
||||||
(element) => isLineElement(element) && element.points.length >= 4,
|
(element) => !isLineElement(element) || element.points.length < 3,
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
return null;
|
return null;
|
||||||
@ -255,12 +257,13 @@ export const actionToggleLoopLock = register({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ToolButton
|
<ButtonIcon
|
||||||
type="button"
|
|
||||||
icon={allLocked ? LoopLockedIcon : LoopUnlockedIcon}
|
icon={allLocked ? LoopLockedIcon : LoopUnlockedIcon}
|
||||||
title={label}
|
title={label}
|
||||||
aria-label={label}
|
aria-label={label}
|
||||||
|
active={allLocked}
|
||||||
onClick={() => updateData(null)}
|
onClick={() => updateData(null)}
|
||||||
|
style={{ marginLeft: "auto" }}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -1360,7 +1360,7 @@ export const actionChangeRoundness = register({
|
|||||||
captureUpdate: CaptureUpdateAction.IMMEDIATELY,
|
captureUpdate: CaptureUpdateAction.IMMEDIATELY,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
PanelComponent: ({ elements, appState, updateData }) => {
|
PanelComponent: ({ elements, appState, updateData, renderAction }) => {
|
||||||
const targetElements = getTargetElements(
|
const targetElements = getTargetElements(
|
||||||
getNonDeletedElements(elements),
|
getNonDeletedElements(elements),
|
||||||
appState,
|
appState,
|
||||||
@ -1398,7 +1398,9 @@ export const actionChangeRoundness = register({
|
|||||||
hasSelection ? null : appState.currentItemRoundness,
|
hasSelection ? null : appState.currentItemRoundness,
|
||||||
)}
|
)}
|
||||||
onChange={(value) => updateData(value)}
|
onChange={(value) => updateData(value)}
|
||||||
/>
|
>
|
||||||
|
{renderAction("toggleLoopLock")}
|
||||||
|
</ButtonIconSelect>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -179,6 +179,7 @@ export class ActionManager {
|
|||||||
appProps={this.app.props}
|
appProps={this.app.props}
|
||||||
app={this.app}
|
app={this.app}
|
||||||
data={data}
|
data={data}
|
||||||
|
renderAction={this.renderAction}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -151,6 +151,10 @@ export type PanelComponentProps = {
|
|||||||
appProps: ExcalidrawProps;
|
appProps: ExcalidrawProps;
|
||||||
data?: Record<string, any>;
|
data?: Record<string, any>;
|
||||||
app: AppClassProperties;
|
app: AppClassProperties;
|
||||||
|
renderAction: (
|
||||||
|
name: ActionName,
|
||||||
|
data?: PanelComponentProps["data"],
|
||||||
|
) => React.JSX.Element | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface Action {
|
export interface Action {
|
||||||
|
@ -19,7 +19,6 @@ import {
|
|||||||
isImageElement,
|
isImageElement,
|
||||||
isLinearElement,
|
isLinearElement,
|
||||||
isTextElement,
|
isTextElement,
|
||||||
isLineElement,
|
|
||||||
} from "@excalidraw/element/typeChecks";
|
} from "@excalidraw/element/typeChecks";
|
||||||
|
|
||||||
import { hasStrokeColor, toolIsArrow } from "@excalidraw/element/comparisons";
|
import { hasStrokeColor, toolIsArrow } from "@excalidraw/element/comparisons";
|
||||||
@ -27,7 +26,6 @@ import { hasStrokeColor, toolIsArrow } from "@excalidraw/element/comparisons";
|
|||||||
import type {
|
import type {
|
||||||
ExcalidrawElement,
|
ExcalidrawElement,
|
||||||
ExcalidrawElementType,
|
ExcalidrawElementType,
|
||||||
ExcalidrawLineElement,
|
|
||||||
NonDeletedElementsMap,
|
NonDeletedElementsMap,
|
||||||
NonDeletedSceneElementsMap,
|
NonDeletedSceneElementsMap,
|
||||||
} from "@excalidraw/element/types";
|
} from "@excalidraw/element/types";
|
||||||
@ -147,17 +145,6 @@ export const SelectedShapeActions = ({
|
|||||||
isLinearElement(targetElements[0]) &&
|
isLinearElement(targetElements[0]) &&
|
||||||
!isElbowArrow(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 =
|
const showCropEditorAction =
|
||||||
!appState.croppingElementId &&
|
!appState.croppingElementId &&
|
||||||
targetElements.length === 1 &&
|
targetElements.length === 1 &&
|
||||||
@ -286,7 +273,6 @@ export const SelectedShapeActions = ({
|
|||||||
{showLinkIcon && renderAction("hyperlink")}
|
{showLinkIcon && renderAction("hyperlink")}
|
||||||
{showCropEditorAction && renderAction("cropEditor")}
|
{showCropEditorAction && renderAction("cropEditor")}
|
||||||
{showLineEditorAction && renderAction("toggleLinearEditor")}
|
{showLineEditorAction && renderAction("toggleLinearEditor")}
|
||||||
{showLoopLockAction && renderAction("toggleLoopLock")}
|
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
)}
|
)}
|
||||||
|
@ -15,6 +15,7 @@ interface ButtonIconProps {
|
|||||||
/** include standalone style (could interfere with parent styles) */
|
/** include standalone style (could interfere with parent styles) */
|
||||||
standalone?: boolean;
|
standalone?: boolean;
|
||||||
onClick: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
|
onClick: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void;
|
||||||
|
style?: React.CSSProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ButtonIcon = forwardRef<HTMLButtonElement, ButtonIconProps>(
|
export const ButtonIcon = forwardRef<HTMLButtonElement, ButtonIconProps>(
|
||||||
@ -30,6 +31,7 @@ export const ButtonIcon = forwardRef<HTMLButtonElement, ButtonIconProps>(
|
|||||||
data-testid={testId}
|
data-testid={testId}
|
||||||
className={clsx(className, { standalone, active })}
|
className={clsx(className, { standalone, active })}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
|
style={props.style}
|
||||||
>
|
>
|
||||||
{icon}
|
{icon}
|
||||||
</button>
|
</button>
|
||||||
|
@ -17,6 +17,7 @@ export const ButtonIconSelect = <T extends Object>(
|
|||||||
}[];
|
}[];
|
||||||
value: T | null;
|
value: T | null;
|
||||||
type?: "radio" | "button";
|
type?: "radio" | "button";
|
||||||
|
children?: React.ReactNode;
|
||||||
} & (
|
} & (
|
||||||
| { type?: "radio"; group: string; onChange: (value: T) => void }
|
| { type?: "radio"; group: string; onChange: (value: T) => void }
|
||||||
| {
|
| {
|
||||||
@ -56,5 +57,6 @@ export const ButtonIconSelect = <T extends Object>(
|
|||||||
</label>
|
</label>
|
||||||
),
|
),
|
||||||
)}
|
)}
|
||||||
|
{props.children}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -130,19 +130,34 @@ export const PinIcon = createIcon(
|
|||||||
);
|
);
|
||||||
|
|
||||||
export const LoopLockedIcon = createIcon(
|
export const LoopLockedIcon = createIcon(
|
||||||
<g>
|
<g strokeWidth={1.25}>
|
||||||
<path d="M7.11 11.11h5.17m-5.17 0h5.17m0 0c1.02 0 1.53.51 1.53 1.53m-1.53-1.53c1.02 0 1.53.51 1.53 1.53m0 0v3.07m0-3.07v3.07m0 0c0 1.03-.5 1.54-1.53 1.54m1.53-1.54c0 1.03-.5 1.54-1.53 1.54m0 0H7.11m5.17 0H7.11m0 0c-1.02 0-1.53-.5-1.53-1.54m1.53 1.54c-1.02 0-1.53-.5-1.53-1.54m0 0v-3.07m0 3.07v-3.07m0 0c0-1.02.51-1.53 1.53-1.53m-1.53 1.53c0-1.02.51-1.53 1.53-1.53M7.7 10.86c.07-.57-.1-2.84.43-3.44.55-.6 2.27-.72 2.82-.17.56.55.43 2.9.51 3.47m-3.76.14c.07-.57-.1-2.84.43-3.44.55-.6 2.27-.72 2.82-.17.56.55.43 2.9.51 3.47M10.63 14.55l-.01.06a.16.16 0 0 1-.04.07.43.43 0 0 1-.07.06l-.1.05-.11.04-.13.04-.15.03-.16.01-.16.01-.17-.01-.15-.01-.15-.03a.74.74 0 0 1-.14-.04l-.11-.04-.09-.05-.07-.06a.18.18 0 0 1-.05-.07l-.01-.06.01-.06a.18.18 0 0 1 .05-.07l.07-.05a.35.35 0 0 1 .09-.06l.11-.04a.74.74 0 0 1 .14-.04l.15-.03.15-.01.17-.01.16.01.16.01.15.03.13.04.11.04.1.06.07.05.04.07.01.06c.01.01.01-.01 0 0" />
|
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||||
<path d="M3.13 6.27c.79-.86 2.9-4.72 4.7-5.18 1.8-.46 5.08 2.02 6.09 2.42M3.12 6.27c.8-.86 2.92-4.72 4.72-5.18 1.8-.46 5.07 2.02 6.08 2.42M4.17 8.01l-.02.27-.07.26c-.03.1-.07.17-.12.25-.04.08-.1.15-.15.22l-.2.2c-.07.05-.14.11-.22.15-.08.05-.16.1-.25.12l-.26.07a2.45 2.45 0 0 1-.55 0 1.42 1.42 0 0 1-.51-.19c-.08-.04-.15-.1-.22-.15a1.77 1.77 0 0 1-.35-.42c-.05-.08-.08-.16-.12-.25a1.97 1.97 0 0 1-.07-.26l-.02-.27.02-.28.07-.26c.04-.08.07-.17.12-.25a1.77 1.77 0 0 1 .57-.57c.08-.05.17-.08.25-.12l.26-.07a2.64 2.64 0 0 1 .55 0l.26.07c.09.04.17.07.25.12a1.77 1.77 0 0 1 .42.35c.05.07.11.14.15.22a1.42 1.42 0 0 1 .21.8c.01.03.01-.06 0 0M17.05 4.88l-.02.27-.07.26c-.03.09-.07.17-.12.25-.04.08-.1.15-.15.22l-.2.2-.22.15c-.08.05-.16.09-.25.12l-.26.07a2.45 2.45 0 0 1-.55 0 1.42 1.42 0 0 1-.51-.19c-.08-.04-.15-.1-.22-.15a1.77 1.77 0 0 1-.35-.42c-.05-.08-.08-.16-.12-.25a1.97 1.97 0 0 1-.07-.26l-.02-.27c0-.1 0-.2.02-.28l.07-.26c.04-.08.07-.17.12-.25a1.77 1.77 0 0 1 .57-.57c.08-.05.17-.08.25-.12l.26-.07a2.64 2.64 0 0 1 .55 0l.26.07c.09.04.17.07.25.12a1.77 1.77 0 0 1 .42.35l.15.22a1.42 1.42 0 0 1 .2.79c.02.04.02-.05 0 0M4.4 7.72c3.04-.7 6.06-1.42 9.5-2.22M4.4 7.72l9.5-2.22" />
|
<path d="M12 5m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" />
|
||||||
|
<path d="M19 8m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" />
|
||||||
|
<path d="M5 11m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" />
|
||||||
|
<path d="M15 19m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" />
|
||||||
|
<path d="M6.5 9.5l1.546 -1.311" />
|
||||||
|
<path d="M14 5.5l3 1.5" />
|
||||||
|
<path d="M18.5 10l-1.185 3.318m-1.062 2.972l-.253 .71" />
|
||||||
|
<path d="M13.5 17.5l-7 -5" />
|
||||||
|
<path d="M3 3l18 18" />
|
||||||
</g>,
|
</g>,
|
||||||
modifiedTablerIconProps,
|
tablerIconProps,
|
||||||
);
|
);
|
||||||
|
|
||||||
export const LoopUnlockedIcon = createIcon(
|
export const LoopUnlockedIcon = createIcon(
|
||||||
<g>
|
<g strokeWidth={1.25}>
|
||||||
<path d="M6.74 11.12h5.17m-5.17 0h5.17m0 0c1.02 0 1.53.5 1.53 1.53m-1.53-1.53c1.02 0 1.53.5 1.53 1.53m0 0v3.07m0-3.07v3.07m0 0c0 1.03-.5 1.54-1.53 1.54m1.53-1.54c0 1.03-.5 1.54-1.53 1.54m0 0H6.74m5.17 0H6.74m0 0c-1.02 0-1.53-.51-1.53-1.54m1.53 1.54c-1.02 0-1.53-.51-1.53-1.54m0 0v-3.07m0 3.07v-3.07m0 0c0-1.02.51-1.53 1.53-1.53m-1.53 1.53c0-1.02.51-1.53 1.53-1.53M7.33 10.87c.08-.57-.08-2.8.45-3.44.54-.63 2.2-.53 2.76-.32.57.22.55 1.34.66 1.61m-3.87 2.15c.08-.57-.08-2.8.45-3.44.54-.63 2.2-.53 2.76-.32.57.22.55 1.34.66 1.61M10.26 14.56v.06a.16.16 0 0 1-.05.07.43.43 0 0 1-.07.06c-.03 0-.06.03-.1.05-.03 0-.07.03-.1.04l-.14.04-.15.03H9.5c-.05.02-.1.02-.16.02l-.17-.01-.15-.01-.15-.03a.74.74 0 0 1-.14-.04l-.1-.04-.1-.05-.07-.06a.18.18 0 0 1-.05-.07v-.12a.18.18 0 0 1 .05-.07l.07-.05a.35.35 0 0 1 .1-.06l.1-.04a.74.74 0 0 1 .14-.04l.15-.03.15-.01.17-.01h.16c.05 0 .11 0 .16.02l.15.03c.04 0 .1.02.13.04.04 0 .08.03.11.04l.1.06c.03 0 .05.03.07.05l.04.07.01.06c.01 0 .01-.01 0 0" />
|
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||||
<path d="M3.13 6.28c.79-.86 2.9-4.72 4.7-5.18 1.8-.46 5.08 2.02 6.09 2.42M3.12 6.28c.8-.86 2.92-4.72 4.72-5.18 1.8-.46 5.07 2.02 6.08 2.42M4.17 8.02l-.02.27-.07.26c-.03.09-.07.17-.12.25-.04.08-.1.15-.15.22l-.2.2-.22.15c-.08.05-.16.09-.25.12l-.26.07a2.45 2.45 0 0 1-.55 0 1.42 1.42 0 0 1-.51-.19c-.08-.04-.15-.1-.22-.15a1.77 1.77 0 0 1-.35-.42c-.05-.08-.08-.16-.12-.25a1.97 1.97 0 0 1-.07-.26l-.02-.27.02-.28.07-.26c.04-.08.07-.17.12-.25a1.77 1.77 0 0 1 .57-.57c.08-.05.17-.08.25-.12l.26-.07a2.64 2.64 0 0 1 .55 0l.26.07c.09.04.17.07.25.12a1.77 1.77 0 0 1 .42.35c.05.07.11.14.15.22a1.42 1.42 0 0 1 .21.79c.01.04.01-.05 0 0M17.05 4.89l-.02.27-.07.26c-.03.09-.07.17-.12.25-.04.08-.1.15-.15.22l-.2.2-.22.15c-.08.05-.16.09-.25.12l-.26.07a2.45 2.45 0 0 1-.55 0 1.42 1.42 0 0 1-.51-.19c-.08-.04-.15-.1-.22-.15a1.77 1.77 0 0 1-.35-.42c-.05-.08-.08-.16-.12-.25a1.97 1.97 0 0 1-.07-.26l-.02-.27c0-.1 0-.2.02-.28l.07-.26c.04-.08.07-.17.12-.25a1.77 1.77 0 0 1 .57-.57c.08-.05.17-.08.25-.12l.26-.07a2.64 2.64 0 0 1 .55 0l.26.07c.09.04.17.07.25.12a1.77 1.77 0 0 1 .42.35l.15.22a1.42 1.42 0 0 1 .2.79c.02.04.02-.05 0 0" />
|
<path d="M12 5m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" />
|
||||||
|
<path d="M19 8m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" />
|
||||||
|
<path d="M5 11m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" />
|
||||||
|
<path d="M15 19m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0" />
|
||||||
|
<path d="M6.5 9.5l3.5 -3" />
|
||||||
|
<path d="M14 5.5l3 1.5" />
|
||||||
|
<path d="M18.5 10l-2.5 7" />
|
||||||
|
<path d="M13.5 17.5l-7 -5" />
|
||||||
</g>,
|
</g>,
|
||||||
modifiedTablerIconProps,
|
tablerIconProps,
|
||||||
);
|
);
|
||||||
|
|
||||||
// tabler-icons: lock-open (via Figma)
|
// tabler-icons: lock-open (via Figma)
|
||||||
|
@ -142,8 +142,8 @@
|
|||||||
"editArrow": "Edit arrow"
|
"editArrow": "Edit arrow"
|
||||||
},
|
},
|
||||||
"loopLock": {
|
"loopLock": {
|
||||||
"unlock": "Unlock loop",
|
"unlock": "Disable polygon",
|
||||||
"lock": "Lock loop"
|
"lock": "Make into polygon"
|
||||||
},
|
},
|
||||||
"elementLock": {
|
"elementLock": {
|
||||||
"lock": "Lock",
|
"lock": "Lock",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user