@etsoo/materialui
Version:
TypeScript Material-UI Implementation
43 lines (42 loc) • 1.66 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import Button from "@mui/material/Button";
import CircularProgress from "@mui/material/CircularProgress";
import React from "react";
/**
* Loading button
* @param props Props
*/
export function LoadingButton(props) {
// Destruct
const { endIcon, loadingIconProps = {}, onClick, ...rest } = props;
// Default size
loadingIconProps.size ??= 12;
// State
// https://stackoverflow.com/questions/55265255/react-usestate-hook-event-handler-using-initial-state
const [loading, setLoading] = React.useState(false);
// Icon
const localEndIcon = loading ? (_jsx(CircularProgress, { ...loadingIconProps })) : (endIcon);
// Check if the component is mounted
const isMounted = React.useRef(true);
React.useEffect(() => {
return () => {
isMounted.current = false;
};
}, []);
// Layout
return (_jsx(Button, { disabled: loading, endIcon: localEndIcon, onClick: async (event) => {
if (onClick) {
// Update state
setLoading(true);
// https://stackoverflow.com/questions/38508420/how-to-know-if-a-function-is-async
// const AsyncFunction = (async () => {}).constructor;
// onClick instanceof AsyncFunction
await onClick(event);
// Warning: Can't perform a React state update on an unmounted component
// It's necessary to check the component is mounted now
if (isMounted.current) {
setLoading(false);
}
}
}, ...rest }));
}