@saas-ui/forms 1.0.0-rc.0 → 1.0.0-rc.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +130 -0
- package/README.md +29 -0
- package/ajv/package.json +18 -0
- package/dist/ajv/ajv-resolver.d.ts +11 -0
- package/dist/ajv/ajv-resolver.d.ts.map +1 -0
- package/dist/ajv/index.d.ts +2 -0
- package/dist/ajv/index.d.ts.map +1 -0
- package/dist/ajv/index.js +104 -0
- package/dist/ajv/index.js.map +1 -0
- package/dist/ajv/index.modern.mjs +104 -0
- package/dist/ajv/index.modern.mjs.map +1 -0
- package/dist/array-field.d.ts +14 -3
- package/dist/array-field.d.ts.map +1 -1
- package/dist/auto-form.d.ts +13 -1
- package/dist/auto-form.d.ts.map +1 -1
- package/dist/field.d.ts +82 -27
- package/dist/field.d.ts.map +1 -1
- package/dist/form.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.modern.mjs +1 -1
- package/dist/index.modern.mjs.map +1 -1
- package/dist/step-form.d.ts +4 -4
- package/dist/step-form.d.ts.map +1 -1
- package/dist/submit-button.d.ts +2 -1
- package/dist/submit-button.d.ts.map +1 -1
- package/dist/use-step-form.d.ts +7 -3
- package/dist/use-step-form.d.ts.map +1 -1
- package/dist/yup/index.js +1 -1
- package/dist/yup/index.js.map +1 -1
- package/dist/yup/index.modern.mjs +1 -1
- package/dist/yup/index.modern.mjs.map +1 -1
- package/dist/zod/index.js +1 -1
- package/dist/zod/index.js.map +1 -1
- package/dist/zod/index.modern.mjs +1 -1
- package/dist/zod/index.modern.mjs.map +1 -1
- package/dist/zod/zod-resolver.d.ts +2 -2
- package/dist/zod/zod-resolver.d.ts.map +1 -1
- package/package.json +32 -17
- package/src/array-field.tsx +21 -22
- package/src/auto-form.tsx +22 -3
- package/src/field-resolver.ts +2 -2
- package/src/field.tsx +184 -73
- package/src/form.tsx +0 -1
- package/src/object-field.tsx +3 -3
- package/src/step-form.tsx +27 -20
- package/src/submit-button.tsx +32 -24
- package/src/use-step-form.tsx +27 -12
- package/yup/package.json +2 -2
- package/zod/package.json +4 -4
package/src/step-form.tsx
CHANGED
@@ -2,13 +2,7 @@ import * as React from 'react'
|
|
2
2
|
|
3
3
|
import { FieldValues, UseFormReturn } from 'react-hook-form'
|
4
4
|
|
5
|
-
import {
|
6
|
-
chakra,
|
7
|
-
HTMLChakraProps,
|
8
|
-
useMultiStyleConfig,
|
9
|
-
StylesProvider,
|
10
|
-
SystemStyleObject,
|
11
|
-
} from '@chakra-ui/system'
|
5
|
+
import { chakra, HTMLChakraProps } from '@chakra-ui/system'
|
12
6
|
|
13
7
|
import { callAllHandlers, runIfFn, cx, __DEV__ } from '@chakra-ui/utils'
|
14
8
|
|
@@ -18,10 +12,11 @@ import {
|
|
18
12
|
StepperStepsProps,
|
19
13
|
StepperStep,
|
20
14
|
useStepperContext,
|
15
|
+
StepperContainer,
|
21
16
|
} from '@saas-ui/stepper'
|
22
17
|
import { Button, ButtonProps } from '@saas-ui/button'
|
23
18
|
|
24
|
-
import { Form
|
19
|
+
import { Form } from './form'
|
25
20
|
import { SubmitButton } from './submit-button'
|
26
21
|
|
27
22
|
import {
|
@@ -29,7 +24,7 @@ import {
|
|
29
24
|
useFormStep,
|
30
25
|
StepFormProvider,
|
31
26
|
UseStepFormProps,
|
32
|
-
|
27
|
+
FormStepSubmitHandler,
|
33
28
|
} from './use-step-form'
|
34
29
|
|
35
30
|
export interface StepFormProps<TFieldValues extends FieldValues = FieldValues>
|
@@ -59,7 +54,7 @@ export const StepForm = React.forwardRef(
|
|
59
54
|
)
|
60
55
|
}
|
61
56
|
) as <TFieldValues extends FieldValues>(
|
62
|
-
props:
|
57
|
+
props: StepFormProps<TFieldValues> & {
|
63
58
|
ref?: React.ForwardedRef<UseFormReturn<TFieldValues>>
|
64
59
|
}
|
65
60
|
) => React.ReactElement
|
@@ -80,9 +75,9 @@ export interface FormStepOptions {
|
|
80
75
|
}
|
81
76
|
|
82
77
|
export const FormStepper: React.FC<StepperStepsProps> = (props) => {
|
83
|
-
const
|
78
|
+
const { activeIndex, setIndex } = useStepperContext()
|
84
79
|
|
85
|
-
const { children } = props
|
80
|
+
const { children, orientation } = props
|
86
81
|
|
87
82
|
const elements = React.Children.map(children, (child) => {
|
88
83
|
if (React.isValidElement(child) && child?.type === FormStep) {
|
@@ -100,22 +95,33 @@ export const FormStepper: React.FC<StepperStepsProps> = (props) => {
|
|
100
95
|
return child
|
101
96
|
})
|
102
97
|
|
98
|
+
const onChange = React.useCallback((i: number) => {
|
99
|
+
setIndex(i)
|
100
|
+
}, [])
|
101
|
+
|
103
102
|
return (
|
104
|
-
<
|
103
|
+
<StepperContainer
|
104
|
+
orientation={orientation}
|
105
|
+
step={activeIndex}
|
106
|
+
onChange={onChange}
|
107
|
+
>
|
105
108
|
<StepperSteps mb="4" {...props}>
|
106
109
|
{elements}
|
107
110
|
</StepperSteps>
|
108
|
-
</
|
111
|
+
</StepperContainer>
|
109
112
|
)
|
110
113
|
}
|
111
114
|
|
112
115
|
export interface FormStepProps
|
113
116
|
extends FormStepOptions,
|
114
|
-
HTMLChakraProps<'div'> {
|
117
|
+
Omit<HTMLChakraProps<'div'>, 'onSubmit'> {
|
118
|
+
onSubmit?: FormStepSubmitHandler
|
119
|
+
}
|
115
120
|
|
116
121
|
export const FormStep: React.FC<FormStepProps> = (props) => {
|
117
|
-
const { name, schema, resolver, children, className, ...rest } =
|
118
|
-
|
122
|
+
const { name, schema, resolver, children, className, onSubmit, ...rest } =
|
123
|
+
props
|
124
|
+
const step = useFormStep({ name, schema, resolver, onSubmit })
|
119
125
|
|
120
126
|
const { isActive } = step
|
121
127
|
|
@@ -158,11 +164,12 @@ export const NextButton: React.FC<NextButtonProps> = (props) => {
|
|
158
164
|
|
159
165
|
return (
|
160
166
|
<SubmitButton
|
161
|
-
isDisabled={isCompleted}
|
162
|
-
label={isLastStep || isCompleted ? submitLabel : label}
|
163
167
|
{...rest}
|
168
|
+
isDisabled={isCompleted}
|
164
169
|
className={cx('saas-form__next-button', props.className)}
|
165
|
-
|
170
|
+
>
|
171
|
+
{isLastStep || isCompleted ? submitLabel : label}
|
172
|
+
</SubmitButton>
|
166
173
|
)
|
167
174
|
}
|
168
175
|
|
package/src/submit-button.tsx
CHANGED
@@ -4,7 +4,6 @@ import { useFormContext } from 'react-hook-form'
|
|
4
4
|
|
5
5
|
import { Button, ButtonProps } from '@saas-ui/button'
|
6
6
|
|
7
|
-
import { forwardRef } from '@chakra-ui/system'
|
8
7
|
import { __DEV__ } from '@chakra-ui/utils'
|
9
8
|
|
10
9
|
export interface SubmitButtonProps extends ButtonProps {
|
@@ -24,29 +23,38 @@ export interface SubmitButtonProps extends ButtonProps {
|
|
24
23
|
disableIfInvalid?: boolean
|
25
24
|
}
|
26
25
|
|
27
|
-
export const SubmitButton = forwardRef<
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
26
|
+
export const SubmitButton = React.forwardRef<
|
27
|
+
HTMLButtonElement,
|
28
|
+
SubmitButtonProps
|
29
|
+
>((props, ref) => {
|
30
|
+
const {
|
31
|
+
children,
|
32
|
+
disableIfUntouched,
|
33
|
+
disableIfInvalid,
|
34
|
+
isDisabled: isDisabledProp,
|
35
|
+
isLoading,
|
36
|
+
...rest
|
37
|
+
} = props
|
38
|
+
const { formState } = useFormContext()
|
39
|
+
|
40
|
+
const isDisabled =
|
41
|
+
(disableIfUntouched && !formState.isDirty) ||
|
42
|
+
(disableIfInvalid && !formState.isValid) ||
|
43
|
+
isDisabledProp
|
44
|
+
|
45
|
+
return (
|
46
|
+
<Button
|
47
|
+
{...rest}
|
48
|
+
ref={ref}
|
49
|
+
variant="primary"
|
50
|
+
type="submit"
|
51
|
+
isLoading={formState.isSubmitting || isLoading}
|
52
|
+
isDisabled={isDisabled}
|
53
|
+
>
|
54
|
+
{children}
|
55
|
+
</Button>
|
56
|
+
)
|
57
|
+
})
|
50
58
|
|
51
59
|
SubmitButton.defaultProps = {
|
52
60
|
label: 'Submit',
|
package/src/use-step-form.tsx
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import * as React from 'react'
|
2
|
-
import { FieldValues, SubmitHandler } from 'react-hook-form'
|
3
|
-
import { createContext } from '@chakra-ui/react-utils'
|
2
|
+
import { FieldValues, SubmitHandler, UnpackNestedValue } from 'react-hook-form'
|
3
|
+
import { createContext, MaybeRenderProp } from '@chakra-ui/react-utils'
|
4
4
|
import {
|
5
5
|
useStepper,
|
6
6
|
useStep,
|
@@ -14,8 +14,16 @@ export interface StepState {
|
|
14
14
|
resolver?: any
|
15
15
|
isActive?: boolean
|
16
16
|
isCompleted?: boolean
|
17
|
+
onSubmit?: FormStepSubmitHandler
|
17
18
|
}
|
18
19
|
|
20
|
+
export type FormStepSubmitHandler<
|
21
|
+
TFieldValues extends FieldValues = FieldValues
|
22
|
+
> = (
|
23
|
+
data: UnpackNestedValue<TFieldValues>,
|
24
|
+
stepper: UseStepperReturn
|
25
|
+
) => Promise<void>
|
26
|
+
|
19
27
|
export interface StepFormContext extends UseStepperReturn {
|
20
28
|
updateStep(state: StepState): void
|
21
29
|
steps: Record<string, StepState>
|
@@ -32,11 +40,9 @@ import { FormProps } from './form'
|
|
32
40
|
|
33
41
|
export interface UseStepFormProps<
|
34
42
|
TFieldValues extends FieldValues = FieldValues
|
35
|
-
> extends UseStepperProps,
|
43
|
+
> extends Omit<UseStepperProps, 'onChange'>,
|
36
44
|
Omit<FormProps<TFieldValues>, 'children'> {
|
37
|
-
children:
|
38
|
-
| React.ReactNode
|
39
|
-
| ((stepper: UseStepFormReturn<TFieldValues>) => React.ReactElement)
|
45
|
+
children: MaybeRenderProp<UseStepFormReturn<TFieldValues>>
|
40
46
|
}
|
41
47
|
|
42
48
|
export interface UseStepFormReturn<
|
@@ -54,7 +60,8 @@ export interface UseStepFormReturn<
|
|
54
60
|
export function useStepForm<TFieldValues extends FieldValues = FieldValues>(
|
55
61
|
props: UseStepFormProps<TFieldValues>
|
56
62
|
): UseStepFormReturn<TFieldValues> {
|
57
|
-
const
|
63
|
+
const { onChange, ...rest } = props
|
64
|
+
const stepper = useStepper(rest)
|
58
65
|
|
59
66
|
const { activeStep, isLastStep, nextStep } = stepper
|
60
67
|
|
@@ -62,11 +69,12 @@ export function useStepForm<TFieldValues extends FieldValues = FieldValues>(
|
|
62
69
|
|
63
70
|
const onSubmitStep: SubmitHandler<TFieldValues> = React.useCallback(
|
64
71
|
async (data) => {
|
72
|
+
const step = steps[activeStep]
|
73
|
+
|
65
74
|
if (isLastStep) {
|
66
75
|
return props
|
67
76
|
.onSubmit?.(data)
|
68
77
|
.then(() => {
|
69
|
-
const step = steps[activeStep]
|
70
78
|
updateStep({
|
71
79
|
...step,
|
72
80
|
isCompleted: true,
|
@@ -75,9 +83,15 @@ export function useStepForm<TFieldValues extends FieldValues = FieldValues>(
|
|
75
83
|
.then(nextStep) // Show completed step
|
76
84
|
}
|
77
85
|
|
78
|
-
|
86
|
+
try {
|
87
|
+
await step.onSubmit?.(data, stepper)
|
88
|
+
|
89
|
+
nextStep()
|
90
|
+
} catch (e) {
|
91
|
+
// Step submission failed.
|
92
|
+
}
|
79
93
|
},
|
80
|
-
[activeStep, isLastStep]
|
94
|
+
[steps, activeStep, isLastStep]
|
81
95
|
)
|
82
96
|
|
83
97
|
const getFormProps = React.useCallback(() => {
|
@@ -113,16 +127,17 @@ export interface UseFormStepProps {
|
|
113
127
|
name: string
|
114
128
|
schema?: any
|
115
129
|
resolver?: any
|
130
|
+
onSubmit?: FormStepSubmitHandler
|
116
131
|
}
|
117
132
|
|
118
133
|
export function useFormStep(props: UseFormStepProps): StepState {
|
119
|
-
const { name, schema, resolver } = props
|
134
|
+
const { name, schema, resolver, onSubmit } = props
|
120
135
|
const step = useStep({ name })
|
121
136
|
|
122
137
|
const { steps, updateStep } = useStepFormContext()
|
123
138
|
|
124
139
|
React.useEffect(() => {
|
125
|
-
updateStep({ name, schema, resolver })
|
140
|
+
updateStep({ name, schema, resolver, onSubmit })
|
126
141
|
}, [name, schema])
|
127
142
|
|
128
143
|
return {
|
package/yup/package.json
CHANGED
@@ -10,8 +10,8 @@
|
|
10
10
|
"author": "Eelco Wiersma <eelco@appulse.nl>",
|
11
11
|
"license": "MIT",
|
12
12
|
"peerDependencies": {
|
13
|
-
"@hookform/resolvers": "^2.
|
14
|
-
"react-hook-form": "^7.
|
13
|
+
"@hookform/resolvers": "^2.9.0",
|
14
|
+
"react-hook-form": "^7.31.3",
|
15
15
|
"yup": "^0.32.11"
|
16
16
|
}
|
17
17
|
}
|
package/zod/package.json
CHANGED
@@ -10,9 +10,9 @@
|
|
10
10
|
"author": "Eelco Wiersma <eelco@appulse.nl>",
|
11
11
|
"license": "MIT",
|
12
12
|
"peerDependencies": {
|
13
|
-
"@chakra-ui/utils": "^2.0.
|
14
|
-
"@hookform/resolvers": "^2.
|
15
|
-
"react-hook-form": "^7.
|
16
|
-
"zod": "^3.
|
13
|
+
"@chakra-ui/utils": "^2.0.2",
|
14
|
+
"@hookform/resolvers": "^2.9.0",
|
15
|
+
"react-hook-form": "^7.31.3",
|
16
|
+
"zod": "^3.17.3"
|
17
17
|
}
|
18
18
|
}
|