diff --git a/packages/app/src/components/FormWithSteps/index.jsx b/packages/app/src/components/FormWithSteps/index.jsx new file mode 100644 index 00000000..4c31cfe9 --- /dev/null +++ b/packages/app/src/components/FormWithSteps/index.jsx @@ -0,0 +1,112 @@ +import React from "react" +import { Button, Alert } from "antd" + +import "./index.less" + +const FormWithSteps = (props) => { + const { steps, header, onCancel, onFinish, cancelable } = props + + const [step, setStep] = React.useState(0) + const [values, setValues] = React.useState({}) + const [error, setError] = React.useState(null) + + function updateState(key, value) { + setValues((prevValues) => ({ ...prevValues, [key]: value })) + } + + function previousStep() { + if (step === 0) { + if (!cancelable) { + return false + } + + if (typeof onCancel === "function") { + onCancel() + } + } + + setStep((prev) => { + if (step === 0) { + return prev + } + + return prev - 1 + }) + } + + async function nextStep() { + if (!canNext()) { + return false + } + + if (step === steps.length - 1) { + return await onFinish({ + values, + updateState, + setError, + }) + } + + if (typeof steps[step].onNext === "function") { + const result = await steps[step].onNext({ + values, + updateState, + setError, + }) + + if (result) { + if (result.cancel === true) { + return false + } + } + } + + setStep((prev) => { + if (step === steps.length - 1) { + return prev + } + + return prev + 1 + }) + + setError(null) + } + + function canNext() { + if (typeof steps[step].validate === "function") { + return steps[step].validate(values) + } + + return true + } + + return ( +