@saas-ui/forms 1.0.0-rc.9 → 1.0.0

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/src/step-form.tsx CHANGED
@@ -16,7 +16,7 @@ import {
16
16
  } from '@saas-ui/stepper'
17
17
  import { Button, ButtonProps } from '@saas-ui/button'
18
18
 
19
- import { Form, FormProps } from './form'
19
+ import { Form } from './form'
20
20
  import { SubmitButton } from './submit-button'
21
21
 
22
22
  import {
@@ -24,6 +24,7 @@ import {
24
24
  useFormStep,
25
25
  StepFormProvider,
26
26
  UseStepFormProps,
27
+ FormStepSubmitHandler,
27
28
  } from './use-step-form'
28
29
 
29
30
  export interface StepFormProps<TFieldValues extends FieldValues = FieldValues>
@@ -113,11 +114,14 @@ export const FormStepper: React.FC<StepperStepsProps> = (props) => {
113
114
 
114
115
  export interface FormStepProps
115
116
  extends FormStepOptions,
116
- HTMLChakraProps<'div'> {}
117
+ Omit<HTMLChakraProps<'div'>, 'onSubmit'> {
118
+ onSubmit?: FormStepSubmitHandler
119
+ }
117
120
 
118
121
  export const FormStep: React.FC<FormStepProps> = (props) => {
119
- const { name, schema, resolver, children, className, ...rest } = props
120
- const step = useFormStep({ name, schema, resolver })
122
+ const { name, schema, resolver, children, className, onSubmit, ...rest } =
123
+ props
124
+ const step = useFormStep({ name, schema, resolver, onSubmit })
121
125
 
122
126
  const { isActive } = step
123
127
 
@@ -160,11 +164,12 @@ export const NextButton: React.FC<NextButtonProps> = (props) => {
160
164
 
161
165
  return (
162
166
  <SubmitButton
163
- isDisabled={isCompleted}
164
- label={isLastStep || isCompleted ? submitLabel : label}
165
167
  {...rest}
168
+ isDisabled={isCompleted}
166
169
  className={cx('saas-form__next-button', props.className)}
167
- />
170
+ >
171
+ {isLastStep || isCompleted ? submitLabel : label}
172
+ </SubmitButton>
168
173
  )
169
174
  }
170
175
 
@@ -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<SubmitButtonProps, 'button'>(
28
- (props, ref) => {
29
- const { children, disableIfUntouched, disableIfInvalid, ...rest } = props
30
- const { formState } = useFormContext()
31
-
32
- const isDisabled =
33
- (disableIfUntouched && !formState.isDirty) ||
34
- (disableIfInvalid && !formState.isValid)
35
-
36
- return (
37
- <Button
38
- type="submit"
39
- isLoading={formState.isSubmitting}
40
- colorScheme="primary"
41
- ref={ref}
42
- isDisabled={isDisabled}
43
- {...rest}
44
- >
45
- {children}
46
- </Button>
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',
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react'
2
- import { FieldValues, SubmitHandler } from 'react-hook-form'
2
+ import { FieldValues, SubmitHandler, UnpackNestedValue } from 'react-hook-form'
3
3
  import { createContext, MaybeRenderProp } from '@chakra-ui/react-utils'
4
4
  import {
5
5
  useStepper,
@@ -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>
@@ -61,11 +69,12 @@ export function useStepForm<TFieldValues extends FieldValues = FieldValues>(
61
69
 
62
70
  const onSubmitStep: SubmitHandler<TFieldValues> = React.useCallback(
63
71
  async (data) => {
72
+ const step = steps[activeStep]
73
+
64
74
  if (isLastStep) {
65
75
  return props
66
76
  .onSubmit?.(data)
67
77
  .then(() => {
68
- const step = steps[activeStep]
69
78
  updateStep({
70
79
  ...step,
71
80
  isCompleted: true,
@@ -74,9 +83,15 @@ export function useStepForm<TFieldValues extends FieldValues = FieldValues>(
74
83
  .then(nextStep) // Show completed step
75
84
  }
76
85
 
77
- nextStep()
86
+ try {
87
+ await step.onSubmit?.(data, stepper)
88
+
89
+ nextStep()
90
+ } catch (e) {
91
+ // Step submission failed.
92
+ }
78
93
  },
79
- [activeStep, isLastStep]
94
+ [steps, activeStep, isLastStep]
80
95
  )
81
96
 
82
97
  const getFormProps = React.useCallback(() => {
@@ -112,16 +127,17 @@ export interface UseFormStepProps {
112
127
  name: string
113
128
  schema?: any
114
129
  resolver?: any
130
+ onSubmit?: FormStepSubmitHandler
115
131
  }
116
132
 
117
133
  export function useFormStep(props: UseFormStepProps): StepState {
118
- const { name, schema, resolver } = props
134
+ const { name, schema, resolver, onSubmit } = props
119
135
  const step = useStep({ name })
120
136
 
121
137
  const { steps, updateStep } = useStepFormContext()
122
138
 
123
139
  React.useEffect(() => {
124
- updateStep({ name, schema, resolver })
140
+ updateStep({ name, schema, resolver, onSubmit })
125
141
  }, [name, schema])
126
142
 
127
143
  return {