2025-08-03 23:20:32 +03:00
|
|
|
import { RefObject } from "preact";
|
2025-08-06 16:16:30 +03:00
|
|
|
import { CSSProperties } from "preact/compat";
|
2025-08-03 19:50:39 +03:00
|
|
|
import { useRef } from "preact/hooks";
|
2025-08-03 19:06:21 +03:00
|
|
|
|
|
|
|
|
interface ButtonProps {
|
2025-08-03 23:20:32 +03:00
|
|
|
/** Reference to the button element. Mostly useful for requesting focus. */
|
2025-08-04 12:58:42 +03:00
|
|
|
buttonRef?: RefObject<HTMLButtonElement>;
|
2025-08-03 19:06:21 +03:00
|
|
|
text: string;
|
|
|
|
|
className?: string;
|
2025-08-05 15:39:49 +03:00
|
|
|
icon?: string;
|
2025-08-03 19:06:21 +03:00
|
|
|
keyboardShortcut?: string;
|
2025-08-03 20:01:54 +03:00
|
|
|
/** Called when the button is clicked. If not set, the button will submit the form (if any). */
|
2025-08-03 19:50:39 +03:00
|
|
|
onClick?: () => void;
|
2025-08-05 18:05:41 +03:00
|
|
|
primary?: boolean;
|
2025-08-05 23:03:38 +03:00
|
|
|
disabled?: boolean;
|
2025-08-06 16:16:30 +03:00
|
|
|
small?: boolean;
|
|
|
|
|
style?: CSSProperties;
|
2025-08-03 19:06:21 +03:00
|
|
|
}
|
|
|
|
|
|
2025-08-06 16:16:30 +03:00
|
|
|
export default function Button({ buttonRef: _buttonRef, className, text, onClick, keyboardShortcut, icon, primary, disabled, small, style }: ButtonProps) {
|
2025-08-03 19:06:21 +03:00
|
|
|
const classes: string[] = ["btn"];
|
2025-08-05 18:05:41 +03:00
|
|
|
if (primary) {
|
|
|
|
|
classes.push("btn-primary");
|
|
|
|
|
} else {
|
|
|
|
|
classes.push("btn-secondary");
|
|
|
|
|
}
|
2025-08-03 19:06:21 +03:00
|
|
|
if (className) {
|
|
|
|
|
classes.push(className);
|
|
|
|
|
}
|
2025-08-06 16:16:30 +03:00
|
|
|
if (small) {
|
|
|
|
|
classes.push("btn-sm");
|
|
|
|
|
}
|
2025-08-03 19:06:21 +03:00
|
|
|
|
2025-08-03 23:20:32 +03:00
|
|
|
const buttonRef = _buttonRef ?? useRef<HTMLButtonElement>(null);
|
2025-08-03 19:06:21 +03:00
|
|
|
const splitShortcut = (keyboardShortcut ?? "").split("+");
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<button
|
|
|
|
|
className={classes.join(" ")}
|
2025-08-03 20:01:54 +03:00
|
|
|
type={onClick ? "button" : "submit"}
|
2025-08-03 19:06:21 +03:00
|
|
|
onClick={onClick}
|
|
|
|
|
ref={buttonRef}
|
2025-08-05 23:03:38 +03:00
|
|
|
disabled={disabled}
|
2025-08-06 16:16:30 +03:00
|
|
|
style={style}
|
2025-08-03 19:06:21 +03:00
|
|
|
>
|
2025-08-05 15:39:49 +03:00
|
|
|
{icon && <span className={`bx ${icon}`}></span>}
|
2025-08-03 19:06:21 +03:00
|
|
|
{text} {keyboardShortcut && (
|
|
|
|
|
splitShortcut.map((key, index) => (
|
|
|
|
|
<>
|
|
|
|
|
<kbd key={index}>{key.toUpperCase()}</kbd>{ index < splitShortcut.length - 1 ? "+" : "" }
|
|
|
|
|
</>
|
|
|
|
|
))
|
|
|
|
|
)}
|
|
|
|
|
</button>
|
|
|
|
|
);
|
|
|
|
|
}
|