@mui/lab#LoadingButton TypeScript Examples
The following examples show how to use
@mui/lab#LoadingButton.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Home.tsx From mui-toolpad with MIT License | 6 votes |
function CreateAppDialog({ onClose, ...props }: CreateAppDialogProps) {
const [name, setName] = React.useState('');
const createAppMutation = client.useMutation('createApp');
return (
<Dialog {...props} onClose={onClose}>
<DialogForm
onSubmit={async (event) => {
event.preventDefault();
const app = await createAppMutation.mutateAsync([name]);
window.location.href = `/_toolpad/app/${app.id}/editor`;
}}
>
<DialogTitle>Create a new MUI Toolpad App</DialogTitle>
<DialogContent>
<TextField
sx={{ my: 1 }}
autoFocus
fullWidth
label="name"
value={name}
onChange={(event) => setName(event.target.value)}
/>
</DialogContent>
<DialogActions>
<Button color="inherit" variant="text" onClick={onClose}>
Cancel
</Button>
<LoadingButton type="submit" loading={createAppMutation.isLoading} disabled={!name}>
Create
</LoadingButton>
</DialogActions>
</DialogForm>
</Dialog>
);
}
Example #2
Source File: Home.tsx From mui-toolpad with MIT License | 6 votes |
function AppDeleteDialog({ app, onClose }: AppDeleteDialogProps) {
const latestApp = useLatest(app);
const deleteAppMutation = client.useMutation('deleteApp');
const handleDeleteClick = React.useCallback(async () => {
if (app) {
await deleteAppMutation.mutateAsync([app.id]);
}
await client.refetchQueries('getApps');
onClose();
}, [app, deleteAppMutation, onClose]);
return (
<Dialog open={!!app} onClose={onClose}>
<DialogForm>
<DialogTitle>Confirm delete</DialogTitle>
<DialogContent>
Are you sure you want to delete application "{latestApp?.name}"
</DialogContent>
<DialogActions>
<Button color="inherit" variant="text" onClick={onClose}>
Cancel
</Button>
<LoadingButton
type="submit"
loading={deleteAppMutation.isLoading}
onClick={handleDeleteClick}
color="error"
>
Delete
</LoadingButton>
</DialogActions>
</DialogForm>
</Dialog>
);
}
Example #3
Source File: form-submit.tsx From example with MIT License | 6 votes |
export function FormSubmit({ form, icon, label, state, disabled }: IFormSubmitProps) {
const { formState: { errors, isSubmitting, isValidating } } = form
const isValid = size(errors) === 0
let color
let iconEl
if (!isValid) {
color = "warning"
iconEl = <Icon icon={faExclamationTriangle}/>
} else {
switch (state) {
case "error":
color = "error"
iconEl = <Icon icon={faExclamationTriangle}/>
break
case "success":
color = "success"
iconEl = <Icon icon={faCheckDouble}/>
break
case "normal":
default:
color = "primary"
iconEl = <Icon icon={icon ?? faCheck}/>
}
}
return <LoadingButton
type="submit"
loading={isSubmitting || isValidating}
loadingPosition="start"
startIcon={iconEl}
color={color as any}
variant="contained"
disabled={disabled}
>
{label}
</LoadingButton>
}
Example #4
Source File: PersonSelectDialog.tsx From frontend with MIT License | 5 votes |
function PersonSelectDialog({ onConfirm: confirmCallback, onClose: closeCallback, error }: Props) {
const [person, setPerson] = useState<PersonResponse | null>(null)
const { t } = useTranslation()
const { open, confirmHandler, closeHandler, openHandler, loading } = useConfirm({
onConfirm: async () => {
confirmCallback ? confirmCallback(person) : null
},
onClose: async () => {
closeCallback ? closeCallback(person) : null
},
})
return (
<>
<FormFieldButton
onClick={openHandler}
placeholder={t('person:selectDialog.notSelected')}
value={person ? `${person.firstName} ${person.lastName} (${person.id})` : undefined}
button={{ label: t('person:selectDialog.select') }}
error={error ? translateError(error, t) : undefined}
/>
<Dialog fullWidth open={open} onClose={closeHandler}>
<DialogTitle>{t('person:selectDialog.personSelect')}</DialogTitle>
<DialogContent>
<Box sx={{ marginTop: theme.spacing(2) }}>
<PersonAutocomplete
onSelect={(person) => {
setPerson(person)
}}
showId
autocompleteProps={{ defaultValue: person }}
/>
</Box>
<Box sx={{ marginTop: theme.spacing(2) }}>
{person ? <PersonInfo person={person} /> : t('person:selectDialog.notSelected')}
</Box>
</DialogContent>
<DialogActions>
<CloseModalButton onClose={closeHandler} />
<LoadingButton onClick={confirmHandler} loading={loading}>
{t('person:selectDialog.confirm')}
</LoadingButton>
</DialogActions>
</Dialog>
</>
)
}
Example #5
Source File: index.tsx From Search-Next with GNU General Public License v3.0 | 5 votes |
VersionInfoButton = () => {
const [data, setData] = useState<Latest>({} as Latest);
const [loading, setLoading] = useState(false);
const getLatest = () => {
setLoading(true);
latest()
.then((res) => {
setLoading(false);
if (res.data) {
setData(res.data);
}
})
.catch((err) => {
setLoading(false);
});
};
useEffect(() => {
Object.keys(data).length &&
confirm({
title: '当前版本信息',
type: false,
content: <VersionModalContent data={data} />,
showFooter: false,
});
}, [data]);
return (
<LoadingButton
loading={loading}
onClick={(e) => {
e.stopPropagation();
getLatest();
}}
>
当前版本信息
</LoadingButton>
);
}
Example #6
Source File: ConfirmDialog.tsx From console with GNU Affero General Public License v3.0 | 4 votes |
ConfirmDialog = ({
isOpen = false,
onClose,
onCancel,
onConfirm,
classes = {},
title = "",
isLoading,
confirmationContent,
cancelText = "Cancel",
confirmText = "Confirm",
confirmButtonProps = {},
cancelButtonProps = {},
titleIcon = null,
}: ConfirmDialogProps) => {
return (
<Dialog
open={isOpen}
onClose={(event, reason) => {
if (reason !== "backdropClick") {
onClose(); // close on Esc but not on click outside
}
}}
className={classes.root}
sx={{
"& .MuiPaper-root": {
padding: "1rem 2rem 2rem 1rem",
},
}}
>
<DialogTitle className={classes.title}>
<div className={classes.titleText}>
{titleIcon} {title}
</div>
<div className={classes.closeContainer}>
<IconButton
aria-label="close"
className={classes.closeButton}
onClick={onClose}
disableRipple
size="small"
>
<CloseIcon />
</IconButton>
</div>
</DialogTitle>
<DialogContent className={classes.content}>
{confirmationContent}
</DialogContent>
<DialogActions className={classes.actions}>
<Button
className={classes.cancelButton}
onClick={onCancel || onClose}
disabled={isLoading}
type="button"
{...cancelButtonProps}
variant="outlined"
color="primary"
id={"confirm-cancel"}
>
{cancelText}
</Button>
<LoadingButton
className={classes.confirmButton}
type="button"
onClick={onConfirm}
loading={isLoading}
disabled={isLoading}
variant="outlined"
color="secondary"
loadingPosition="start"
startIcon={<React.Fragment />}
autoFocus
id={"confirm-ok"}
{...confirmButtonProps}
>
{confirmText}
</LoadingButton>
</DialogActions>
</Dialog>
);
}
Example #7
Source File: QueryEditor.tsx From mui-toolpad with MIT License | 4 votes |
function QueryNodeEditorDialog<Q, P>({
open,
node,
onClose,
onRemove,
onSave,
}: QueryNodeEditorProps<Q, P>) {
const { appId } = usePageEditorState();
const [input, setInput] = React.useState(node);
React.useEffect(() => setInput(node), [node]);
const connectionId = input.attributes.connectionId.value;
const dataSourceId = input.attributes.dataSource?.value;
const dataSource = (dataSourceId && dataSources[dataSourceId]) || null;
const handleConnectionChange = React.useCallback((newConnectionId) => {
setInput((existing) =>
update(existing, {
attributes: update(existing.attributes, {
connectionId: appDom.createConst(newConnectionId),
}),
}),
);
}, []);
const handleQueryChange = React.useCallback((newQuery: Q) => {
setInput((existing) =>
update(existing, {
attributes: update(existing.attributes, {
query: appDom.createConst(newQuery),
}),
}),
);
}, []);
const handleTransformFnChange = React.useCallback((newValue: string) => {
setInput((existing) =>
update(existing, {
attributes: update(existing.attributes, {
transform: appDom.createConst(newValue),
}),
}),
);
}, []);
const handleTransformEnabledChange = React.useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
setInput((existing) =>
update(existing, {
attributes: update(existing.attributes, {
transformEnabled: appDom.createConst(event.target.checked),
}),
}),
);
},
[],
);
const handleRefetchOnWindowFocusChange = React.useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
setInput((existing) =>
update(existing, {
attributes: update(existing.attributes, {
refetchOnWindowFocus: appDom.createConst(event.target.checked),
}),
}),
);
},
[],
);
const handleRefetchOnReconnectChange = React.useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
setInput((existing) =>
update(existing, {
attributes: update(existing.attributes, {
refetchOnReconnect: appDom.createConst(event.target.checked),
}),
}),
);
},
[],
);
const handleRefetchIntervalChange = React.useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
const interval = Number(event.target.value);
setInput((existing) =>
update(existing, {
attributes:
Number.isNaN(interval) || interval <= 0
? omit(existing.attributes, 'refetchInterval')
: update(existing.attributes, {
refetchInterval: appDom.createConst(interval * 1000),
}),
}),
);
},
[],
);
const [params, setParams] = React.useState<[string, BindableAttrValue<any>][]>(
Object.entries(input.params || {}),
);
React.useEffect(() => setParams(Object.entries(input.params || {})), [input.params]);
const { pageState } = usePageEditorState();
const liveParams: [string, LiveBinding][] = React.useMemo(() => {
return params.map(([name, bindable]) => [name, evaluateBindable(bindable, pageState)]);
}, [params, pageState]);
const handleParamsChange = React.useCallback((newParams: [string, BindableAttrValue<any>][]) => {
setParams(newParams);
const paramsObj: BindableAttrValues<any> = Object.fromEntries(newParams);
setInput((existing) =>
update(existing, {
params: paramsObj,
}),
);
}, []);
const handleSave = React.useCallback(() => {
onSave(input);
}, [onSave, input]);
const handleRemove = React.useCallback(() => {
onRemove(node);
onClose();
}, [onRemove, node, onClose]);
const paramsObject: Record<string, any> = React.useMemo(() => {
const liveParamValues: [string, any][] = liveParams.map(([name, result]) => [
name,
result?.value,
]);
return Object.fromEntries(liveParamValues);
}, [liveParams]);
const [previewQuery, setPreviewQuery] = React.useState<appDom.QueryNode<Q, P> | null>(null);
const [previewParams, setPreviewParams] = React.useState(paramsObject);
const queryPreview = client.useQuery(
'execQuery',
previewQuery ? [appId, previewQuery, previewParams] : null,
{ retry: false },
);
const handleUpdatePreview = React.useCallback(() => {
setPreviewQuery(input);
setPreviewParams(paramsObject);
}, [input, paramsObject]);
const isInputSaved = node === input;
const handleClose = React.useCallback(() => {
const ok = isInputSaved
? true
: // eslint-disable-next-line no-alert
window.confirm(
'Are you sure you want to close the editor. All unsaved progress will be lost.',
);
if (ok) {
onClose();
}
}, [onClose, isInputSaved]);
if (!dataSourceId || !dataSource) {
throw new Error(`DataSource "${dataSourceId}" not found`);
}
return (
<Dialog fullWidth maxWidth="lg" open={open} onClose={handleClose} scroll="body">
<DialogTitle>Edit Query ({node.id})</DialogTitle>
<DialogContent>
<Stack spacing={1} py={1} gap={2}>
<Stack direction="row" gap={2}>
<NodeNameEditor node={node} />
<ConnectionSelect
dataSource={dataSourceId}
value={input.attributes.connectionId.value || null}
onChange={handleConnectionChange}
/>
</Stack>
<Divider />
<Typography>Parameters</Typography>
<ParametersEditor
value={params}
onChange={handleParamsChange}
globalScope={pageState}
liveValue={liveParams}
/>
<Divider />
<Typography>Build query:</Typography>
<dataSource.QueryEditor
appId={appId}
connectionId={connectionId}
value={input.attributes.query.value}
onChange={handleQueryChange}
globalScope={{ query: paramsObject }}
/>
<Divider />
<Typography>Options:</Typography>
<Grid container direction="row" spacing={1}>
<Grid item xs={4}>
<Stack direction="column">
<FormControlLabel
control={
<Checkbox
checked={input.attributes.refetchOnWindowFocus?.value ?? true}
onChange={handleRefetchOnWindowFocusChange}
/>
}
label="Refetch on window focus"
/>
<FormControlLabel
control={
<Checkbox
checked={input.attributes.refetchOnReconnect?.value ?? true}
onChange={handleRefetchOnReconnectChange}
/>
}
label="Refetch on network reconnect"
/>
<TextField
InputProps={{
startAdornment: <InputAdornment position="start">s</InputAdornment>,
}}
sx={{ maxWidth: 300 }}
type="number"
label="Refetch interval"
value={refetchIntervalInSeconds(input.attributes.refetchInterval?.value) ?? ''}
onChange={handleRefetchIntervalChange}
/>
</Stack>
</Grid>
<Grid item xs={6}>
<Stack>
<FormControlLabel
label="Transform API response"
control={
<Checkbox
checked={input.attributes.transformEnabled?.value ?? false}
onChange={handleTransformEnabledChange}
inputProps={{ 'aria-label': 'controlled' }}
/>
}
/>
<JsExpressionEditor
globalScope={{}}
value={input.attributes.transform?.value ?? '(data) => {\n return data;\n}'}
onChange={handleTransformFnChange}
disabled={!input.attributes.transformEnabled?.value}
/>
</Stack>
</Grid>
</Grid>
<Divider />
<Toolbar disableGutters>
preview
<LoadingButton
sx={{ ml: 2 }}
disabled={previewParams === paramsObject && previewQuery === input}
loading={queryPreview.isLoading}
loadingPosition="start"
onClick={handleUpdatePreview}
startIcon={<PlayArrowIcon />}
>
Run
</LoadingButton>
</Toolbar>
{queryPreview.error ? <ErrorAlert error={queryPreview.error} /> : null}
{queryPreview.isSuccess ? <JsonView src={queryPreview.data} /> : null}
</Stack>
</DialogContent>
<DialogActions>
<Button color="inherit" variant="text" onClick={handleClose}>
Cancel
</Button>
<Button onClick={handleRemove}>Remove</Button>
<Button disabled={isInputSaved} onClick={handleSave}>
Save
</Button>
</DialogActions>
</Dialog>
);
}
Example #8
Source File: FormikStepper.tsx From frontend with MIT License | 4 votes |
export function FormikStepper({ children, ...props }: GenericFormProps<OneTimeDonation>) {
const childrenArray = React.Children.toArray(children) as React.ReactElement<FormikStepProps>[]
const { step, setStep } = useContext(StepsContext)
const router = useRouter()
useEffect(() => {
router.query.success === 'false' || router.query.success === 'true' ? setStep(3) : null
}, [router.query.success])
const currentChild = childrenArray[step]
const { data: currentPerson } = useCurrentPerson()
function isLastStep() {
return step === childrenArray.length - 2
}
function isFirstStep() {
return step === 0
}
function isLogged() {
if (currentPerson === undefined) {
return false
}
if (currentPerson?.status && currentPerson.status !== 'unauthenticated') {
return false
}
return true
}
const { t } = useTranslation('one-time-donation')
return (
<Formik
{...props}
validationSchema={currentChild.props.validationSchema}
onSubmit={async (values, helpers) => {
if (isLastStep()) {
await props.onSubmit(values, helpers)
} else if (isFirstStep() && isLogged()) {
if (values.payment === 'bank') {
router.push({
pathname: router.route,
query: {
slug: router.query.slug,
success: true,
},
})
} else {
setStep((s) => s + 2)
}
} else {
setStep((s) => s + 1)
helpers.setTouched({})
}
}}
validateOnMount
validateOnBlur>
{({ isSubmitting, handleSubmit, isValid }) => (
<Form
onSubmit={handleSubmit}
style={{
maxWidth: '662px',
marginLeft: 'auto',
marginRight: 'auto',
}}
autoComplete="off">
<StyledStepper>
<Stepper alternativeLabel activeStep={step}>
{childrenArray.map((child, index) => (
<Step key={index}>
<StepLabel classes={{ alternativeLabel: classes.stepIcon }}>
{child.props.label}
</StepLabel>
</Step>
))}
</Stepper>
</StyledStepper>
<Box marginY={8}>{currentChild}</Box>
{/* Controls of the form */}
{step === 3 ? null : (
<Grid container rowSpacing={2} columnSpacing={2}>
<Grid item xs={12} md={6}>
<Button
fullWidth
type="button"
variant="text"
disabled={step === 0 || isSubmitting}
color="error"
size="large"
onClick={() => {
if (step === 2 && isLogged()) {
setStep((s) => s - 2)
return
}
setStep((s) => s - 1)
}}>
{t('btns.back')}
</Button>
</Grid>
<Grid item xs={12} md={6}>
<LoadingButton
disabled={!isValid}
fullWidth
type="submit"
variant="contained"
loading={isSubmitting}
color="info"
size="large">
{isSubmitting ? 'Потвърждение' : isLastStep() ? t('btns.end') : t('btns.next')}
</LoadingButton>
</Grid>
</Grid>
)}
</Form>
)}
</Formik>
)
}
Example #9
Source File: AppEditorShell.tsx From mui-toolpad with MIT License | 2 votes |
function CreateReleaseDialog({ appId, open, onClose }: CreateReleaseDialogProps) {
const navigate = useNavigate();
const lastRelease = client.useQuery('findLastRelease', [appId]);
const { handleSubmit, register, formState, reset } = useForm({
defaultValues: {
description: '',
},
});
const createReleaseMutation = client.useMutation('createRelease');
const doSubmit = handleSubmit(async (releaseParams) => {
const newRelease = await createReleaseMutation.mutateAsync([appId, releaseParams]);
reset();
navigate(`/app/${appId}/releases/${newRelease.version}`);
});
return (
<Dialog open={open} onClose={onClose}>
<DialogForm autoComplete="off" onSubmit={doSubmit}>
<DialogTitle>Create new release</DialogTitle>
<DialogContent>
{lastRelease.isSuccess ? (
<Stack spacing={1}>
<Typography>
You are about to create a snapshot of your application under a unique url. You will
be able to verify whether everything is working correctly before deploying this
release to production.
</Typography>
<Typography>
The new version to be created is "
{lastRelease.data ? lastRelease.data.version + 1 : 1}".
</Typography>
<Typography>
Please summarize the changes you have made to the application since the last
release:
</Typography>
<TextField
label="description"
autoFocus
fullWidth
multiline
rows={5}
{...register('description')}
error={Boolean(formState.errors.description)}
helperText={formState.errors.description?.message}
/>
</Stack>
) : null}
{createReleaseMutation.isError ? (
<Alert severity="error">{(createReleaseMutation.error as Error).message}</Alert>
) : null}
</DialogContent>
<DialogActions>
<Button color="inherit" variant="text" onClick={onClose}>
Cancel
</Button>
<LoadingButton
disabled={!lastRelease.isSuccess}
loading={createReleaseMutation.isLoading}
type="submit"
>
Create
</LoadingButton>
</DialogActions>
</DialogForm>
</Dialog>
);
}
Example #10
Source File: connect-options.tsx From example with MIT License | 2 votes |
export function ConnectOptions() {
const { environment, setEnvironment } = useContext(EnvironmentContext)
const connection = useContext(ConnectorContext)
const { connector, state } = connection
const options$ = useMemo(() => connector ? from(connector.getOptions()) : from([]), [connector])
const envSelectHandler = useCallback((e: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>) => {
setEnvironment?.(e.target.value as RaribleSdkEnvironment)
}, [setEnvironment])
if (!connector) {
return null
}
const style = {
justifyContent: "start",
pl: "3rem",
"& .MuiButton-startIcon": {
position: "absolute",
left: "1.25rem"
}
}
return <Box sx={{
maxWidth: 300
}}>
<Rx value$={options$}>
{options => (
<Stack spacing={1}>
<TextField
select
size="small"
label="Environment"
disabled={state?.status === "connected"}
value={environment}
onChange={envSelectHandler}
>
{ENVIRONMENTS.map((option) => (
<MenuItem key={option.value} value={option.value}>
{option.label}
</MenuItem>
))}
</TextField>
{
options.map(o => {
const walletInfo = getWalletInfo(o.option)
return <LoadingButton
key={o.option}
onClick={() => connector.connect(o)}
loading={state.status === "connecting" && state.providerId === o.provider.getId()}
loadingPosition="start"
startIcon={<Icon icon={faChevronRight}/>}
sx={style}
variant="outlined"
disabled={state?.status === "connected"}
fullWidth
>
{walletInfo.label}
</LoadingButton>
})
}
<Button
onClick={(state as StateConnected<any>).disconnect}
startIcon={<Icon icon={faLinkSlash}/>}
color="error"
sx={style}
variant="outlined"
disabled={state?.status !== "connected"}
fullWidth
>
Disconnect
</Button>
</Stack>
)}
</Rx>
</Box>
}