@material-ui/core#Step TypeScript Examples
The following examples show how to use
@material-ui/core#Step.
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: StepsProgress.tsx From backstage with Apache License 2.0 | 6 votes |
StepsProgress = ({
currentStepIndex,
aborted,
steps,
}: StepsProgressProps) => {
// If the activeStep is greater/equal to the number of steps
// Then the canary is being promoted
// Increase the step index to mark the 'canary promoted' step as done also
const activeStepIndex =
currentStepIndex >= steps.length ? currentStepIndex + 1 : currentStepIndex;
/*
* When the Rollout is aborted set the active step to -1
* otherwise it appears to always be on the first step
*/
return (
<Stepper activeStep={aborted ? -1 : activeStepIndex} alternativeLabel>
{steps
.map((step, i) => (
<Step key={i}>
<StepLabel data-testid={`step-${i}`}>
{createLabelForStep(step)}
</StepLabel>
</Step>
))
.concat(
<Step key="-1">
<StepLabel data-testid="step--1">Canary promoted</StepLabel>
</Step>,
)}
</Stepper>
);
}
Example #2
Source File: FormSteps.tsx From listo with MIT License | 6 votes |
FormSteps = () => {
const classes = useStyles({});
const { projectMeta, risks, categories } = useContext(AppContext);
const { activeStep, handleGoToStep } = useContext(StepContext);
if (!projectMeta || !risks || !categories) {
// TODO: better empty state handling
return <h1>Loading!</h1>;
}
return (
<React.Fragment>
<Stepper activeStep={activeStep} className={classes.stepper}>
{STEPS.map(label => (
<Step key={label} onClick={() => handleGoToStep(label)}>
<StepLabel className={classes.stepLabels}>{label}</StepLabel>
</Step>
))}
</Stepper>
{activeStep === 0 && <ProjectMetaGathering />}
{activeStep === 1 && <RiskAssessment />}
{activeStep === 2 && <ToolingComponent />}
{activeStep === 3 && <ModuleSelection />}
{activeStep === 4 && <Summary />}
<PaginationButtons />
</React.Fragment>
);
}
Example #3
Source File: TransactionCreateContainer.tsx From End-to-End-Web-Testing-with-Cypress with MIT License | 5 votes |
TransactionCreateContainer: React.FC<Props> = ({ authService, snackbarService }) => {
const [authState] = useService(authService);
const [, sendSnackbar] = useService(snackbarService);
const [createTransactionState, sendCreateTransaction, createTransactionService] = useMachine(
createTransactionMachine
);
// Expose createTransactionService on window for Cypress
// @ts-ignore
window.createTransactionService = createTransactionService;
const [usersState, sendUsers] = useMachine(usersMachine);
useEffect(() => {
sendUsers({ type: "FETCH" });
}, [sendUsers]);
const sender = authState?.context?.user;
const setReceiver = (receiver: User) => {
sendCreateTransaction("SET_USERS", { sender, receiver });
};
const createTransaction = (payload: TransactionPayload) => {
sendCreateTransaction("CREATE", payload);
};
const userListSearch = debounce(200, (payload: any) => sendUsers("FETCH", payload));
const showSnackbar = (payload: SnackbarContext) => sendSnackbar("SHOW", payload);
let activeStep;
if (createTransactionState.matches("stepTwo")) {
activeStep = 1;
} else if (createTransactionState.matches("stepThree")) {
activeStep = 3;
} else {
activeStep = 0;
}
return (
<>
<Stepper activeStep={activeStep}>
<Step key={"stepOne"}>
<StepLabel>Select Contact</StepLabel>
</Step>
<Step key={"stepTwo"}>
<StepLabel>Payment</StepLabel>
</Step>
<Step key={"stepThree"}>
<StepLabel>Complete</StepLabel>
</Step>
</Stepper>
{createTransactionState.matches("stepOne") && (
<TransactionCreateStepOne
setReceiver={setReceiver}
users={usersState.context.results!}
userListSearch={userListSearch}
/>
)}
{sender && createTransactionState.matches("stepTwo") && (
<TransactionCreateStepTwo
receiver={createTransactionState.context.receiver}
sender={sender}
createTransaction={createTransaction}
showSnackbar={showSnackbar}
/>
)}
{createTransactionState.matches("stepThree") && (
<TransactionCreateStepThree createTransactionService={createTransactionService} />
)}
</>
);
}
Example #4
Source File: Stepper.tsx From storefront with MIT License | 5 votes |
Stepper: React.FC<StepperProps> = ({
activeStep: initialActiveStep,
children,
onChangeStep,
steps,
...props
}) => {
const styles = useStyles();
const [activeStep, setActiveStep] = useState(
steps.findIndex((step) => step.path === initialActiveStep),
);
useEffect(() => {
if (onChangeStep != null) {
onChangeStep(steps[activeStep]);
}
}, [activeStep, onChangeStep, steps]);
const handleStep = (step: number) => () => {
setActiveStep(step);
};
const handleNext = () => {
setActiveStep((prevActiveStep) => prevActiveStep + 1);
};
const handlePrevious =
(step = activeStep - 1) =>
() => {
if (step < activeStep && step >= 0) {
setActiveStep(step);
}
};
return (
<>
<MuiStepper
alternativeLabel
activeStep={activeStep}
className={styles.root}
orientation="horizontal"
{...props}
>
{steps.map((step, i) => (
<Step key={step.path}>
<StepButton onClick={handleStep(i)}>{step.title}</StepButton>
</Step>
))}
</MuiStepper>
<Divider />
{children({ handleNext, handlePrevious })[activeStep]}
</>
);
}
Example #5
Source File: ImportStepper.tsx From backstage with Apache License 2.0 | 5 votes |
ImportStepper = (props: ImportStepperProps) => {
const {
initialUrl,
generateStepper = defaultGenerateStepper,
variant,
} = props;
const catalogImportApi = useApi(catalogImportApiRef);
const classes = useStyles();
const state = useImportState({ initialUrl });
const states = useMemo<StepperProvider>(
() => generateStepper(state.activeFlow, defaultStepper),
[generateStepper, state.activeFlow],
);
const render = (step: StepConfiguration) => {
return (
<Step>
{step.stepLabel}
<StepContent>{step.content}</StepContent>
</Step>
);
};
return (
<InfoCard variant={variant}>
<Stepper
classes={{ root: classes.stepperRoot }}
activeStep={state.activeStepNumber}
orientation="vertical"
>
{render(
states.analyze(
state as Extract<ImportState, { activeState: 'analyze' }>,
{ apis: { catalogImportApi } },
),
)}
{render(
states.prepare(
state as Extract<ImportState, { activeState: 'prepare' }>,
{ apis: { catalogImportApi } },
),
)}
{render(
states.review(
state as Extract<ImportState, { activeState: 'review' }>,
{ apis: { catalogImportApi } },
),
)}
{render(
states.finish(
state as Extract<ImportState, { activeState: 'finish' }>,
{ apis: { catalogImportApi } },
),
)}
</Stepper>
</InfoCard>
);
}
Example #6
Source File: index.tsx From youtube-2020-june-material-ui-themes with MIT License | 5 votes |
export function FormikStepper({
children,
...props
}: FormikConfig<FormikValues>) {
const childrenArray = React.Children.toArray(children) as React.ReactElement<
FormikStepProps
>[];
const [step, setStep] = useState(0);
const currentChild = childrenArray[step];
const [completed, setCompleted] = useState(false);
function isLastStep() {
return step === childrenArray.length - 1;
}
return (
<Formik
{...props}
validationSchema={currentChild.props.validationSchema}
onSubmit={async (values, helpers) => {
if (isLastStep()) {
await props.onSubmit(values, helpers);
setCompleted(true);
} else {
setStep(s => s + 1);
}
}}
>
{({ isSubmitting }) => (
<Form autoComplete="off">
<Stepper alternativeLabel activeStep={step}>
{childrenArray.map((child, index) => (
<Step
key={child.props.label}
completed={step > index || completed}
>
<StepLabel>{child.props.label}</StepLabel>
</Step>
))}
</Stepper>
{currentChild}
<Grid container spacing={2}>
{step > 0 ? (
<Grid item>
<Button
disabled={isSubmitting}
variant="contained"
color="primary"
onClick={() => setStep(s => s - 1)}
>
Back
</Button>
</Grid>
) : null}
<Grid item xs={12}>
<Button
startIcon={
isSubmitting ? <CircularProgress size="1rem" /> : null
}
disabled={isSubmitting}
type="submit"
fullWidth
>
{isSubmitting ? "Submitting" : isLastStep() ? "Submit" : "NeXt"}
</Button>
</Grid>
</Grid>
</Form>
)}
</Formik>
);
}
Example #7
Source File: index.tsx From youtube-2020-june-multi-step-form-formik with MIT License | 5 votes |
export function FormikStepper({ children, ...props }: FormikConfig<FormikValues>) {
const childrenArray = React.Children.toArray(children) as React.ReactElement<FormikStepProps>[];
const [step, setStep] = useState(0);
const currentChild = childrenArray[step];
const [completed, setCompleted] = useState(false);
function isLastStep() {
return step === childrenArray.length - 1;
}
return (
<Formik
{...props}
validationSchema={currentChild.props.validationSchema}
onSubmit={async (values, helpers) => {
if (isLastStep()) {
await props.onSubmit(values, helpers);
setCompleted(true);
} else {
setStep((s) => s + 1);
// the next line was not covered in the youtube video
//
// If you have multiple fields on the same step
// we will see they show the validation error all at the same time after the first step!
//
// If you want to keep that behaviour, then, comment the next line :)
// If you want the second/third/fourth/etc steps with the same behaviour
// as the first step regarding validation errors, then the next line is for you! =)
//
// In the example of the video, it doesn't make any difference, because we only
// have one field with validation in the second step :)
helpers.setTouched({});
}
}}
>
{({ isSubmitting }) => (
<Form autoComplete="off">
<Stepper alternativeLabel activeStep={step}>
{childrenArray.map((child, index) => (
<Step key={child.props.label} completed={step > index || completed}>
<StepLabel>{child.props.label}</StepLabel>
</Step>
))}
</Stepper>
{currentChild}
<Grid container spacing={2}>
{step > 0 ? (
<Grid item>
<Button
disabled={isSubmitting}
variant="contained"
color="primary"
onClick={() => setStep((s) => s - 1)}
>
Back
</Button>
</Grid>
) : null}
<Grid item>
<Button
startIcon={isSubmitting ? <CircularProgress size="1rem" /> : null}
disabled={isSubmitting}
variant="contained"
color="primary"
type="submit"
>
{isSubmitting ? 'Submitting' : isLastStep() ? 'Submit' : 'Next'}
</Button>
</Grid>
</Grid>
</Form>
)}
</Formik>
);
}
Example #8
Source File: index.tsx From back-home-safe with GNU General Public License v3.0 | 5 votes |
Tutorial = ({
setFinishedTutorial,
}: {
setFinishedTutorial: (value: boolean) => void;
}) => {
const { t } = useTranslation("tutorial");
const { initPassword } = useData();
const [activeStep, setActiveStep] = useState(0);
const [password, setPassword] = useState("");
const {
activeStepComponent: { component, nextButtonText },
isLastStep,
allStep,
} = useMemo(() => {
const allStep = stepsSettings({ password, setPassword, t });
return {
allStep,
activeStepComponent: allStep[activeStep] || {},
isLastStep: activeStep === allStep.length - 1,
};
}, [activeStep, password, setPassword, t]);
const handleNext = () => {
if (isLastStep) {
!isEmpty(password) && initPassword(password);
setFinishedTutorial(true);
} else {
setActiveStep((prevActiveStep) => prevActiveStep + 1);
}
};
const handleBack = () => {
setActiveStep((prevActiveStep) => prevActiveStep - 1);
};
return (
<PageWrapper>
<Stepper activeStep={activeStep} alternativeLabel>
{allStep.map(({ key, name }) => (
<Step key={key}>
<StepLabel>{name}</StepLabel>
</Step>
))}
</Stepper>
<ContentWrapper>{component}</ContentWrapper>
<ButtonGroup>
<Button disabled={activeStep === 0} onClick={handleBack}>
{t("global:button.last_page")}
</Button>
<Button variant="contained" color="secondary" onClick={handleNext}>
{nextButtonText
? nextButtonText
: isLastStep
? t("global:button.complete")
: t("global:button.next_page")}
</Button>
</ButtonGroup>
</PageWrapper>
);
}
Example #9
Source File: DeploymentLoader.tsx From homebase-app with MIT License | 5 votes |
DeploymentLoader: React.FC<Props> = ({
states,
activeStep,
error,
}) => {
const errorMessage = "Something went wrong, please try again later."
const [focusedState, setFocusedState] = useState(0);
const isFinished = activeStep === states.length;
const isStarted = Number.isInteger(activeStep);
const showActiveText =
isStarted && !isFinished && activeStep === focusedState;
const showCompletedText = isStarted && focusedState < (activeStep as number);
useEffect(() => {
if (activeStep) {
if (isFinished) {
setFocusedState(states.length - 1);
} else {
setFocusedState(activeStep);
}
}
}, [activeStep, isFinished, states.length]);
return (
<Box width={"100%"} marginTop={"-15%"}>
<Grid container justify="center">
<Grid item>
<WaitingText variant="subtitle1" color="textSecondary">
{showActiveText
? error
? errorMessage
: states[focusedState].activeText
: showCompletedText
? states[focusedState].completedText
: ""}
{showActiveText && !error && <SuspenseDots />}
</WaitingText>
</Grid>
</Grid>
<StyledStepper
activeStep={activeStep}
alternativeLabel
nonLinear
connector={<ColorlibConnector />}
>
{states.map((_, index) => (
<Step
key={index}
onClick={() => {
if (!activeStep) {
return;
}
if (index <= activeStep) {
setFocusedState(index);
}
}}
completed={activeStep ? index < activeStep : false}
>
<StyledLabel
hasError={activeStep === index && !!error}
focused={index === focusedState}
/>
</Step>
))}
</StyledStepper>
</Box>
);
}
Example #10
Source File: Wizard.tsx From twilio-voice-notification-app with Apache License 2.0 | 5 votes |
Wizard = ({ data, activeStep }: StepProps) => {
// Info about completition status of each step.
const stepsCompletion = useSelector(stepsCompletionSelector);
return (
<Box>
<Stepper
activeStep={activeStep && routerSteps.indexOf(activeStep)}
alternativeLabel
connector={<CustomConnector />}
style={{ backgroundColor: 'transparent' }}
>
{routerSteps.map((step) => {
const { label } = step;
const completed =
!isStepAhead(activeStep, step) && stepsCompletion[step.key];
return (
<Step key={label} disabled={true}>
<StepButton
icon={
<WizardStepIcon
icon={step.icon}
active={activeStep === step}
completed={completed}
/>
}
>
<StyledStepLabel>{label}</StyledStepLabel>
</StepButton>
</Step>
);
})}
</Stepper>
<Switch>
{routerSteps.map((step) => (
<Route
key={step.key}
path={step.location}
render={() => React.createElement(step.component, { step, data })}
/>
))}
<Redirect from="*" to="/create/configure" />
</Switch>
</Box>
);
}
Example #11
Source File: Wizard.tsx From twilio-voice-notification-app with Apache License 2.0 | 5 votes |
Wizard.Step = WizardStep;
Example #12
Source File: ExperimentForm.tsx From abacus with GNU General Public License v2.0 | 4 votes |
ExperimentForm = ({
indexedMetrics,
indexedSegments,
initialExperiment,
onSubmit,
completionBag,
formSubmissionError,
}: {
indexedMetrics: Record<number, Metric>
indexedSegments: Record<number, Segment>
initialExperiment: ExperimentFormData
completionBag: ExperimentFormCompletionBag
onSubmit: (formData: unknown) => Promise<void>
formSubmissionError?: Error
}): JSX.Element => {
const classes = useStyles()
const rootRef = useRef<HTMLDivElement>(null)
const [currentStageId, setActiveStageId] = useState<StageId>(StageId.Beginning)
const currentStageIndex = stages.findIndex((stage) => stage.id === currentStageId)
const [completeStages, setCompleteStages] = useState<StageId[]>([])
const [errorStages, setErrorStages] = useState<StageId[]>([])
useEffect(() => {
rootRef.current?.scrollIntoView({ behavior: 'smooth', block: 'start', inline: 'start' })
}, [currentStageId])
// Preventing accidental non-react-router navigate-aways:
const preventSubmissionRef = useRef<boolean>(false)
useEffect(() => {
// istanbul ignore next; trivial
// Sure we can test that these lines run but what is really important is how they
// behave in browsers, which IMO is too complicated to write tests for in this case.
const eventListener = (event: BeforeUnloadEvent) => {
if (preventSubmissionRef.current) {
event.preventDefault()
// Chrome requires returnValue to be set
event.returnValue = ''
}
}
window.addEventListener('beforeunload', eventListener)
return () => {
window.removeEventListener('beforeunload', eventListener)
}
}, [])
return (
<Formik
initialValues={{ experiment: initialExperiment }}
onSubmit={onSubmit}
validationSchema={yup.object({ experiment: experimentFullNewSchema })}
>
{(formikProps) => {
const getStageErrors = async (stage: Stage) => {
return _.pick(await formikProps.validateForm(), stage.validatableFields)
}
const isStageValid = async (stage: Stage): Promise<boolean> => {
const errors = await formikProps.validateForm()
return !stage.validatableFields.some((field) => _.get(errors, field))
}
const updateStageState = async (stage: Stage) => {
if (stage.id === StageId.Submit) {
return
}
if (await isStageValid(stage)) {
setErrorStages((prevValue) => _.difference(prevValue, [stage.id]))
setCompleteStages((prevValue) => _.union(prevValue, [stage.id]))
} else {
setErrorStages((prevValue) => _.union(prevValue, [stage.id]))
setCompleteStages((prevValue) => _.difference(prevValue, [stage.id]))
}
}
const changeStage = (stageId: StageId) => {
setActiveStageId(stageId)
void updateStageState(stages[currentStageIndex])
if (errorStages.includes(stageId)) {
void getStageErrors(stages[stageId]).then((stageErrors) =>
formikProps.setTouched(setNestedObjectValues(stageErrors, true)),
)
}
if (stageId === StageId.Submit) {
stages.map(updateStageState)
}
}
const prevStage = () => {
const prevStage = stages[currentStageIndex - 1]
prevStage && changeStage(prevStage.id)
}
const nextStage = () => {
const nextStage = stages[currentStageIndex + 1]
nextStage && changeStage(nextStage.id)
}
preventSubmissionRef.current = formikProps.dirty && !formikProps.isSubmitting
return (
<div className={classes.root}>
{/* This is required for React Router navigate-away prevention */}
<Prompt
when={preventSubmissionRef.current}
message='You have unsaved data, are you sure you want to leave?'
/>
<Paper className={classes.navigation}>
<Stepper nonLinear activeStep={currentStageId} orientation='horizontal'>
{stages.map((stage) => (
<Step key={stage.id} completed={stage.id !== currentStageId && completeStages.includes(stage.id)}>
<StepButton onClick={() => changeStage(stage.id)}>
<StepLabel error={stage.id !== currentStageId && errorStages.includes(stage.id)}>
{stage.title}
</StepLabel>
</StepButton>
</Step>
))}
</Stepper>
</Paper>
<div ref={rootRef}>
{/* Explanation: This should be fine as we aren't hiding behaviour that can't be accessed otherwise. */}
{/* eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions */}
<form className={classes.form} onSubmit={formikProps.handleSubmit} noValidate>
{/* Prevent implicit submission of the form on enter. */}
{/* See https://stackoverflow.com/a/51507806 */}
<button type='submit' disabled style={{ display: 'none' }} aria-hidden='true'></button>
{currentStageId === StageId.Beginning && (
<div className={classes.formPart}>
<Paper className={classes.paper}>
<Beginning />
</Paper>
<div className={classes.formPartActions}>
<Button onClick={nextStage} variant='contained' color='primary'>
Begin
</Button>
</div>
</div>
)}
{currentStageId === StageId.BasicInfo && (
<div className={classes.formPart}>
<Paper className={classes.paper}>
<BasicInfo completionBag={completionBag} />
</Paper>
<div className={classes.formPartActions}>
<Button onClick={prevStage}>Previous</Button>
<Button onClick={nextStage} variant='contained' color='primary'>
Next
</Button>
</div>
</div>
)}
{currentStageId === StageId.Audience && (
<div className={classes.formPart}>
<Paper className={classes.paper}>
<Audience {...{ formikProps, indexedSegments, completionBag }} />
</Paper>
<div className={classes.formPartActions}>
<Button onClick={prevStage}>Previous</Button>
<Button onClick={nextStage} variant='contained' color='primary'>
Next
</Button>
</div>
</div>
)}
{currentStageId === StageId.Metrics && (
<div className={classes.formPart}>
<Paper className={classes.paper}>
<Metrics {...{ indexedMetrics, completionBag, formikProps }} />
</Paper>
<div className={classes.formPartActions}>
<Button onClick={prevStage}>Previous</Button>
<Button onClick={nextStage} variant='contained' color='primary'>
Next
</Button>
</div>
</div>
)}
{currentStageId === StageId.Submit && (
<div className={classes.formPart}>
<Paper className={classes.paper}>
<Typography variant='h4' gutterBottom>
Confirm and Submit Your Experiment
</Typography>
<Typography variant='body2' gutterBottom>
Now is a good time to{' '}
<Link href='https://github.com/Automattic/experimentation-platform/wiki' target='_blank'>
check our wiki's experiment creation checklist
</Link>{' '}
and confirm everything is in place.
</Typography>
<Typography variant='body2' gutterBottom>
Once you submit your experiment it will be set to staging, where it can be edited up until you
set it to running.
</Typography>
<Typography variant='body2' gutterBottom>
<strong> When you are ready, click the Submit button below.</strong>
</Typography>
</Paper>
<GeneralErrorAlert error={formSubmissionError} />
<div className={classes.formPartActions}>
<Button onClick={prevStage}>Previous</Button>
<LoadingButtonContainer isLoading={formikProps.isSubmitting}>
<Button
type='submit'
variant='contained'
color='secondary'
disabled={formikProps.isSubmitting || errorStages.length > 0}
>
Submit
</Button>
</LoadingButtonContainer>
</div>
</div>
)}
</form>
</div>
</div>
)
}}
</Formik>
)
}
Example #13
Source File: SQFormDialogStepper.tsx From SQForm with MIT License | 4 votes |
export function SQFormDialogStepper<Values extends FormikValues>({
cancelButtonText = 'Cancel',
children,
disableBackdropClick = false,
isOpen = false,
isNextDisabled = false,
maxWidth = 'sm',
onClose,
onSubmit,
title,
enableReinitialize = false,
muiGridProps = {},
dialogProps,
setValues,
fullWidth = true,
contentStyle,
initialValues,
...props
}: SQFormDialogStepperProps<Values>): JSX.Element {
const steps = children;
const [activeStep, setActiveStep] = React.useState(0);
const currentChild = steps[activeStep];
const [completed, setCompleted] = React.useState<number[]>([]);
const validationSchema = currentChild.props.validationSchema || null;
const classes = useStyles({steps});
const actionsClasses = useActionsStyles();
const stepperClasses = useStepperStyles();
const isLastStep = React.useMemo(() => {
return activeStep === steps.length - 1;
}, [activeStep, steps]);
const handleNext = () => {
setActiveStep(activeStep + 1);
setCompleted([...completed, activeStep]);
};
const handleStep = (step: number) => () => {
if (completed.includes(step)) {
setActiveStep(step);
}
};
const handleSubmit = async (
values: Values,
helpers: FormikHelpers<Values>
) => {
if (isLastStep) {
await onSubmit(values, helpers);
} else {
setValues && setValues(values);
handleNext();
}
};
function SubmitButton() {
const {errors, values, dirty} = useFormikContext<Record<string, unknown>>();
const isButtonDisabled = React.useMemo(() => {
if (isNextDisabled) {
return true;
}
if (!validationSchema) {
return false;
}
const currentStepKeys = Object.keys(validationSchema.fields);
const stepValues = currentStepKeys.every((step) => {
return !!values[step];
});
if (
!stepValues ||
currentStepKeys.some((step) => Object.keys(errors).includes(step)) ||
!dirty
) {
return true;
}
return false;
}, [errors, values, dirty]);
const primaryButtonText = isLastStep ? 'Submit' : 'Next';
return (
<RoundedButton
type="submit"
isDisabled={isButtonDisabled}
title={primaryButtonText}
>
{primaryButtonText}
</RoundedButton>
);
}
const handleClose = (
event: Record<string, unknown>,
reason: 'backdropClick' | 'escapeKeyDown' | 'cancelClick'
) => {
if (disableBackdropClick && reason === 'backdropClick') {
return;
}
onClose(event, reason);
};
return (
<Formik
{...props}
validationSchema={validationSchema}
onSubmit={handleSubmit}
initialValues={initialValues}
enableReinitialize={enableReinitialize}
>
{() => (
<Dialog
TransitionComponent={Transition}
disableBackdropClick={disableBackdropClick}
maxWidth={maxWidth}
open={isOpen}
onClose={handleClose}
fullWidth={fullWidth}
{...dialogProps}
>
<Form>
<DialogTitle disableTypography={true}>
<Typography variant="h4">{title}</Typography>
</DialogTitle>
<Divider />
{steps.length > 1 && (
<Grid container classes={stepperClasses}>
<Stepper
activeStep={activeStep}
classes={classes}
alternativeLabel={true}
>
{steps.map((child, index) => (
<Step key={`${child.props.label}-${index}`}>
<StepButton onClick={handleStep(index)}>
<Typography
variant="overline"
color={index === activeStep ? 'error' : 'initial'} // sets the color to orange if current step
>
{child?.props.label}
</Typography>
</StepButton>
</Step>
))}
</Stepper>
</Grid>
)}
<DialogContent
dividers
style={{
paddingTop: '40px',
paddingBottom: '40px',
...contentStyle,
}}
>
<Grid
{...muiGridProps}
container
spacing={muiGridProps.spacing ?? 3}
justifyContent="center"
>
{currentChild}
</Grid>
</DialogContent>
<DialogActions classes={actionsClasses}>
<RoundedButton
title={cancelButtonText}
onClick={onClose}
color="secondary"
variant="outlined"
>
{cancelButtonText}
</RoundedButton>
<SubmitButton />
</DialogActions>
</Form>
</Dialog>
)}
</Formik>
);
}
Example #14
Source File: index.tsx From homebase-app with MIT License | 4 votes |
DAOCreate: React.FC = () => {
const creator = useContext(CreatorContext);
const { back, next } = creator.state;
const step = useStepNumber();
const progress = useMemo(() => step * 25, [step]);
const history = useHistory();
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down("sm"));
const goToFAQ = (): void => {
history.push("/faq");
};
useEffect(() => {
mixpanel.unregister("daoAddress");
mixpanel.unregister("daoType");
mixpanel.track("Visited Creator");
}, []);
return (
<PageContainer container direction="row">
{!isMobile && (
<ProgressContainer
item
xs={3}
container
justify="center"
alignItems="center"
direction="column"
>
<Grid
item
container
direction="column"
alignItems="center"
xs={3}
style={{ maxWidth: "unset" }}
>
<Grid item>
<Box
style={
location.pathname === "/creator"
? custom(theme).logo
: undefined
}
onClick={() => history.push("/explorer")}
margin="auto"
marginTop="22px"
>
<Grid
container
alignItems="center"
wrap="nowrap"
justify="center"
>
<Grid item>
<LogoItem src={HomeButton} />
</Grid>
<Grid item>
<Box paddingLeft="10px">
<LogoText color="textSecondary">Homebase</LogoText>
</Box>
</Grid>
</Grid>
</Box>
</Grid>
</Grid>
<Grid item container direction="column" alignItems="center" xs>
<ProgressBar
progress={progress}
radius={62}
strokeWidth={4}
strokeColor={theme.palette.secondary.main}
trackStrokeWidth={2}
trackStrokeColor={theme.palette.primary.light}
>
<Box className="indicator">
<IndicatorValue>
{progress === 0.5 ? 0 : step * 25}%
</IndicatorValue>
</Box>
</ProgressBar>
<Box>
<FAQClickToAction onClick={goToFAQ}>
New to DAOs? Read our FAQ
</FAQClickToAction>
</Box>
<StyledStepper activeStep={step} orientation="vertical">
{STEPS.map(({ title }: StepInfo, index: number) => (
<Step key={title}>
<StepLabel icon={index + 1}>{title}</StepLabel>
</Step>
))}
</StyledStepper>
</Grid>
</ProgressContainer>
)}
<StepContentHeigth item xs={12} md={9} container justify="center">
<Grid
container
direction="column"
alignItems="center"
style={{ width: "100%" }}
>
<Navbar mode="creator" />
<Grid item style={{ width: "100%" }} xs>
<StepContentContainer item container justify="center">
<StepRouter />
</StepContentContainer>
</Grid>
</Grid>
</StepContentHeigth>
{step < 5 && <NavigationBar back={back} next={next} />}
</PageContainer>
);
}
Example #15
Source File: QuickStartView.tsx From SeeQR with MIT License | 4 votes |
QuickStartView = ({ show }: QuickStartViewProps) => {
if (!show) return null;
const classes = useStyles();
const [activeStep, setActiveStep] = useState(0);
const [completed, setCompleted] = useState(new Set<number>());
const [skipped, setSkipped] = useState(new Set<number>());
const steps = getSteps();
const totalSteps = () => getSteps().length;
const isStepOptional = (step: number) => step === null;
const handleSkip = () => {
if (!isStepOptional(activeStep)) {
// You probably want to guard against something like this
// it should never occur unless someone's actively trying to break something.
throw new Error("You can't skip a step that isn't optional.");
}
setActiveStep((prevActiveStep) => prevActiveStep + 1);
setSkipped((prevSkipped) => {
const newSkipped = new Set(prevSkipped.values());
newSkipped.add(activeStep);
return newSkipped;
});
};
const skippedSteps = () => skipped.size;
const completedSteps = () => completed.size;
const allStepsCompleted = () =>
completedSteps() === totalSteps() - skippedSteps();
const isLastStep = () => activeStep === totalSteps() - 1;
const handleNext = () => {
const newActiveStep =
isLastStep() && !allStepsCompleted()
? // It's the last step, but not all steps have been completed
// find the first step that has been completed
steps.findIndex((step, i) => !completed.has(i))
: activeStep + 1;
setActiveStep(newActiveStep);
};
const handleBack = () => {
setActiveStep((prevActiveStep) => prevActiveStep - 1);
};
const handleStep = (step: number) => () => {
setActiveStep(step);
};
const handleComplete = () => {
const newCompleted = new Set(completed);
newCompleted.add(activeStep);
setCompleted(newCompleted);
if (completed.size !== totalSteps() - skippedSteps()) {
handleNext();
}
};
const handleReset = () => {
setActiveStep(0);
setCompleted(new Set<number>());
setSkipped(new Set<number>());
};
const isStepSkipped = (step: number) => skipped.has(step);
function isStepComplete(step: number) {
return completed.has(step);
}
return (
<PageContainer>
<StyledTypographyTitle align="center">
Welcome to SeeQR
</StyledTypographyTitle>
<img className={classes.image} src={logo} alt="Logo" />
<StyledStepper alternativeLabel nonLinear activeStep={activeStep}>
{steps.map((label, index) => {
const stepProps: { completed?: boolean } = {};
const buttonProps: { optional?: React.ReactNode } = {};
if (isStepOptional(index)) {
buttonProps.optional = (
<Typography variant="caption">Optional</Typography>
);
}
if (isStepSkipped(index)) {
stepProps.completed = false;
}
return (
<Step key={label} {...stepProps}>
<StepButton
onClick={handleStep(index)}
completed={isStepComplete(index)}
{...buttonProps}
>
<StyledStepLabel className={classes.stepper}>
{label}
</StyledStepLabel>
</StepButton>
</Step>
);
})}
</StyledStepper>
<div>
{allStepsCompleted() ? (
<div>
<StyledTypographyInstructions className={classes.instructions}>
All steps completed - you're ready to use SeeQr!
</StyledTypographyInstructions>
<Button onClick={handleReset}>Reset</Button>
</div>
) : (
<StepContent>
{getStepContent(activeStep)}
<NavButtons>
<Button
disabled={activeStep === 0}
onClick={handleBack}
className={classes.button}
>
Back
</Button>
<Button
variant="contained"
color="primary"
onClick={handleNext}
className={classes.button}
>
Next
</Button>
{isStepOptional(activeStep) && !completed.has(activeStep) && (
<Button
variant="contained"
color="primary"
onClick={handleSkip}
className={classes.button}
>
Skip
</Button>
)}
{activeStep !== steps.length &&
(completed.has(activeStep) ? (
<Typography variant="caption" className={classes.completed}>
Step
{` ${activeStep + 1} `}
already completed
</Typography>
) : (
<Button
variant="contained"
color="primary"
onClick={handleComplete}
>
{completedSteps() === totalSteps() - 1
? 'Finish'
: 'Complete Step'}
</Button>
))}
</NavButtons>
</StepContent>
)}
</div>
</PageContainer>
);
}