bazarr/frontend/src/components/header/Button.tsx

79 lines
2.0 KiB
TypeScript

import { IconDefinition } from "@fortawesome/fontawesome-svg-core";
import { faSpinner } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
FunctionComponent,
MouseEvent,
PropsWithChildren,
useCallback,
useState,
} from "react";
import { Button } from "react-bootstrap";
interface CHButtonProps {
disabled?: boolean;
hidden?: boolean;
icon: IconDefinition;
updating?: boolean;
updatingIcon?: IconDefinition;
onClick?: (e: MouseEvent) => void;
}
const ContentHeaderButton: FunctionComponent<CHButtonProps> = (props) => {
const { children, icon, disabled, updating, updatingIcon, onClick } = props;
let displayIcon = icon;
if (updating) {
displayIcon = updatingIcon ? updatingIcon : faSpinner;
}
return (
<Button
variant="dark"
className="d-flex flex-column text-nowrap py-1"
disabled={disabled || updating}
onClick={onClick}
>
<FontAwesomeIcon
className="mx-auto my-1"
icon={displayIcon}
spin={updating}
></FontAwesomeIcon>
<span className="align-bottom text-themecolor small text-center">
{children}
</span>
</Button>
);
};
type CHAsyncButtonProps<R, T extends () => Promise<R>> = {
promise: T;
onSuccess?: (item: R) => void;
} & Omit<CHButtonProps, "updating" | "updatingIcon" | "onClick">;
export function ContentHeaderAsyncButton<R, T extends () => Promise<R>>(
props: PropsWithChildren<CHAsyncButtonProps<R, T>>
): JSX.Element {
const { promise, onSuccess, ...button } = props;
const [updating, setUpdate] = useState(false);
const click = useCallback(() => {
setUpdate(true);
promise().then((val) => {
setUpdate(false);
onSuccess && onSuccess(val);
});
}, [onSuccess, promise]);
return (
<ContentHeaderButton
updating={updating}
onClick={click}
{...button}
></ContentHeaderButton>
);
}
export default ContentHeaderButton;