excalidraw/src/components/ToolButton.tsx

85 lines
2.1 KiB
TypeScript
Raw Normal View History

import "./ToolIcon.scss";
import React, { useEffect } from "react";
type ToolIconSize = "s" | "m";
type ToolButtonBaseProps = {
icon?: React.ReactNode;
"aria-label": string;
"aria-keyshortcuts"?: string;
label?: string;
title?: string;
name?: string;
id?: string;
size?: ToolIconSize;
};
type ToolButtonProps =
| (ToolButtonBaseProps & { type: "button"; onClick?(): void })
| (ToolButtonBaseProps & {
type: "radio";
checked: boolean;
onChange?(): void;
});
const DEFAULT_SIZE: ToolIconSize = "m";
export const ToolButton = React.forwardRef(function(
props: ToolButtonProps,
ref,
) {
const innerRef = React.useRef<HTMLInputElement | HTMLButtonElement | null>(
null,
);
React.useImperativeHandle(ref, () => innerRef.current);
const sizeCn = `ToolIcon_size_${props.size || DEFAULT_SIZE}`;
const prevChecked = React.useRef<boolean>(
"checked" in props && props.checked,
);
useEffect(() => {
if (props.type !== "button") {
if (props.checked && !prevChecked.current && innerRef.current) {
innerRef.current.focus();
}
prevChecked.current = props.checked;
}
});
if (props.type === "button")
return (
<button
className={`ToolIcon_type_button ToolIcon ${sizeCn}`}
title={props.title}
aria-label={props["aria-label"]}
type="button"
onClick={props.onClick}
ref={node => (innerRef.current = node)}
>
<div className="ToolIcon__icon" aria-hidden="true">
{props.icon || props.label}
</div>
</button>
);
return (
2020-01-26 20:49:18 +01:00
<label className="ToolIcon" title={props.title}>
<input
className={`ToolIcon_type_radio ${sizeCn}`}
type="radio"
name={props.name}
aria-label={props["aria-label"]}
aria-keyshortcuts={props["aria-keyshortcuts"]}
id={props.id}
onChange={props.onChange}
checked={props.checked}
ref={node => (innerRef.current = node)}
/>
<div className="ToolIcon__icon">{props.icon}</div>
</label>
);
});