mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-09 10:34:17 +00:00
added FormWithSteps
component
This commit is contained in:
parent
ef658a8b64
commit
5b6d36744c
112
packages/app/src/components/FormWithSteps/index.jsx
Normal file
112
packages/app/src/components/FormWithSteps/index.jsx
Normal file
@ -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 (
|
||||
<div className="steped-form">
|
||||
{typeof header === "function" &&
|
||||
header({
|
||||
step: step,
|
||||
})}
|
||||
|
||||
<div className="steped-form-content">
|
||||
{steps[step].render({
|
||||
updateState: updateState,
|
||||
values: values,
|
||||
})}
|
||||
|
||||
{error && <Alert message={error} type="error" />}
|
||||
|
||||
<div className="steped-form-content-actions">
|
||||
<Button onClick={previousStep}>
|
||||
{step === 0 && cancelable ? "Cancel" : "Back"}
|
||||
</Button>
|
||||
|
||||
<Button onClick={nextStep} disabled={!canNext()}>
|
||||
{step === steps.length - 1 ? "Finish" : "Next"}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default FormWithSteps
|
31
packages/app/src/components/FormWithSteps/index.less
Normal file
31
packages/app/src/components/FormWithSteps/index.less
Normal file
@ -0,0 +1,31 @@
|
||||
.steped-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
gap: 40px;
|
||||
|
||||
width: 100%;
|
||||
|
||||
.steped-form-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.steped-form-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
gap: 10px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.steped-form-content-actions {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
justify-content: flex-end;
|
||||
|
||||
gap: 10px;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user