@etsoo/materialui
Version:
TypeScript Material-UI Implementation
49 lines (48 loc) • 2.06 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.LoadingButton = LoadingButton;
const jsx_runtime_1 = require("react/jsx-runtime");
const Button_1 = __importDefault(require("@mui/material/Button"));
const CircularProgress_1 = __importDefault(require("@mui/material/CircularProgress"));
const react_1 = __importDefault(require("react"));
/**
* Loading button
* @param props Props
*/
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_1.default.useState(false);
// Icon
const localEndIcon = loading ? ((0, jsx_runtime_1.jsx)(CircularProgress_1.default, { ...loadingIconProps })) : (endIcon);
// Check if the component is mounted
const isMounted = react_1.default.useRef(true);
react_1.default.useEffect(() => {
return () => {
isMounted.current = false;
};
}, []);
// Layout
return ((0, jsx_runtime_1.jsx)(Button_1.default, { 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 }));
}