@saas-ui/forms 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +18 -0
- package/dist/Field.d.ts +79 -0
- package/dist/Field.d.ts.map +1 -0
- package/dist/array-field.d.ts +48 -0
- package/dist/array-field.d.ts.map +1 -0
- package/dist/auto-form.d.ts +10 -0
- package/dist/auto-form.d.ts.map +1 -0
- package/dist/display-field.d.ts +7 -0
- package/dist/display-field.d.ts.map +1 -0
- package/dist/fields.d.ts +6 -0
- package/dist/fields.d.ts.map +1 -0
- package/dist/form.d.ts +16 -0
- package/dist/form.d.ts.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/index.modern.js +2 -0
- package/dist/index.modern.js.map +1 -0
- package/dist/layout.d.ts +5 -0
- package/dist/layout.d.ts.map +1 -0
- package/dist/object-field.d.ts +11 -0
- package/dist/object-field.d.ts.map +1 -0
- package/dist/resolvers/yup.d.ts +12 -0
- package/dist/resolvers/yup.d.ts.map +1 -0
- package/dist/submit-button.d.ts +3 -0
- package/dist/submit-button.d.ts.map +1 -0
- package/dist/use-array-field.d.ts +95 -0
- package/dist/use-array-field.d.ts.map +1 -0
- package/dist/utils.d.ts +3 -0
- package/dist/utils.d.ts.map +1 -0
- package/package.json +75 -0
- package/src/array-field.tsx +196 -0
- package/src/auto-form.tsx +35 -0
- package/src/display-field.tsx +31 -0
- package/src/field.tsx +295 -0
- package/src/fields.tsx +51 -0
- package/src/form.tsx +49 -0
- package/src/index.ts +14 -0
- package/src/layout.tsx +37 -0
- package/src/object-field.tsx +25 -0
- package/src/resolvers/yup.ts +81 -0
- package/src/submit-button.tsx +25 -0
- package/src/use-array-field.tsx +152 -0
- package/src/utils.ts +13 -0
@@ -0,0 +1,152 @@
|
|
1
|
+
import * as React from 'react'
|
2
|
+
import {
|
3
|
+
useFieldArray,
|
4
|
+
useFormContext,
|
5
|
+
UseFieldArrayReturn,
|
6
|
+
} from 'react-hook-form'
|
7
|
+
|
8
|
+
import { createContext } from '@chakra-ui/react-utils'
|
9
|
+
|
10
|
+
export interface UseArrayFieldReturn extends UseFieldArrayReturn {
|
11
|
+
/**
|
12
|
+
* The array field name
|
13
|
+
*/
|
14
|
+
name: string
|
15
|
+
/**
|
16
|
+
* The default value for new items
|
17
|
+
*/
|
18
|
+
defaultValue: Record<string, any>
|
19
|
+
/**
|
20
|
+
* Min amount of items
|
21
|
+
*/
|
22
|
+
min?: number
|
23
|
+
/**
|
24
|
+
* Max amount of items
|
25
|
+
*/
|
26
|
+
max?: number
|
27
|
+
}
|
28
|
+
|
29
|
+
export const [ArrayFieldProvider, useArrayFieldContext] =
|
30
|
+
createContext<UseArrayFieldReturn>({
|
31
|
+
name: 'ArrayFieldContext',
|
32
|
+
})
|
33
|
+
|
34
|
+
export interface UseArrayFieldRowReturn {
|
35
|
+
/**
|
36
|
+
* Name of the array field including the index, eg 'field.0'
|
37
|
+
*/
|
38
|
+
name: string
|
39
|
+
/**
|
40
|
+
* The field index
|
41
|
+
*/
|
42
|
+
index: number
|
43
|
+
/**
|
44
|
+
* Remove this array item
|
45
|
+
*/
|
46
|
+
remove: () => void
|
47
|
+
/**
|
48
|
+
* True if this is the first item
|
49
|
+
*/
|
50
|
+
isFirst: boolean
|
51
|
+
/**
|
52
|
+
* True if this is the last item
|
53
|
+
*/
|
54
|
+
isLast: boolean
|
55
|
+
}
|
56
|
+
|
57
|
+
export const [ArrayFieldRowProvider, useArrayFieldRowContext] =
|
58
|
+
createContext<UseArrayFieldRowReturn>({
|
59
|
+
name: 'ArrayFieldRowContext',
|
60
|
+
})
|
61
|
+
|
62
|
+
export interface ArrayFieldOptions {
|
63
|
+
/**
|
64
|
+
* The field name
|
65
|
+
*/
|
66
|
+
name: string
|
67
|
+
/**
|
68
|
+
* Default value for new values in the array
|
69
|
+
*/
|
70
|
+
defaultValue?: Record<string, any>
|
71
|
+
/**
|
72
|
+
* Default key name for rows, change this if your data uses 'id'
|
73
|
+
* @default "id"
|
74
|
+
*/
|
75
|
+
keyName?: string
|
76
|
+
min?: number
|
77
|
+
max?: number
|
78
|
+
}
|
79
|
+
|
80
|
+
export const useArrayField = ({
|
81
|
+
name,
|
82
|
+
defaultValue = {},
|
83
|
+
keyName,
|
84
|
+
min,
|
85
|
+
max,
|
86
|
+
}: ArrayFieldOptions) => {
|
87
|
+
const { control } = useFormContext()
|
88
|
+
const context = useFieldArray({
|
89
|
+
control,
|
90
|
+
name,
|
91
|
+
keyName,
|
92
|
+
})
|
93
|
+
|
94
|
+
return {
|
95
|
+
...context,
|
96
|
+
name,
|
97
|
+
defaultValue,
|
98
|
+
min,
|
99
|
+
max,
|
100
|
+
}
|
101
|
+
}
|
102
|
+
|
103
|
+
export interface UseArrayFieldRowProps {
|
104
|
+
index: number
|
105
|
+
}
|
106
|
+
|
107
|
+
export const useArrayFieldRow = ({ index }: UseArrayFieldRowProps) => {
|
108
|
+
const { clearErrors } = useFormContext()
|
109
|
+
const { name, remove, fields } = useArrayFieldContext()
|
110
|
+
|
111
|
+
React.useEffect(() => {
|
112
|
+
// reset errors, to make sure min/max errors reset correctly
|
113
|
+
clearErrors(name)
|
114
|
+
}, [])
|
115
|
+
|
116
|
+
return {
|
117
|
+
index,
|
118
|
+
isFirst: index === 0,
|
119
|
+
isLast: index === fields.length - 1,
|
120
|
+
name: `${name}.${index}`,
|
121
|
+
remove: React.useCallback(() => {
|
122
|
+
clearErrors(name)
|
123
|
+
remove(index)
|
124
|
+
}, [index]),
|
125
|
+
}
|
126
|
+
}
|
127
|
+
|
128
|
+
export const useArrayFieldRemoveButton = () => {
|
129
|
+
const { isFirst, remove } = useArrayFieldRowContext()
|
130
|
+
const { min, fields } = useArrayFieldContext()
|
131
|
+
|
132
|
+
const isDisabled = isFirst && !!(min && fields.length <= min)
|
133
|
+
|
134
|
+
return {
|
135
|
+
onClick: () => remove(),
|
136
|
+
isDisabled,
|
137
|
+
}
|
138
|
+
}
|
139
|
+
|
140
|
+
export const useArrayFieldAddButton = () => {
|
141
|
+
const { append, defaultValue, max, fields } = useArrayFieldContext()
|
142
|
+
|
143
|
+
const isDisabled = !!(max && fields.length >= max)
|
144
|
+
|
145
|
+
return {
|
146
|
+
onClick: () =>
|
147
|
+
append(defaultValue, {
|
148
|
+
shouldFocus: false,
|
149
|
+
}),
|
150
|
+
isDisabled,
|
151
|
+
}
|
152
|
+
}
|
package/src/utils.ts
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
import * as React from 'react'
|
2
|
+
|
3
|
+
export const mapNestedFields = (name: string, children: React.ReactNode) => {
|
4
|
+
return React.Children.map(children, (child) => {
|
5
|
+
if (React.isValidElement(child) && child.props.name) {
|
6
|
+
return React.cloneElement(child, {
|
7
|
+
...child.props,
|
8
|
+
name: `${name}.${child.props.name}`,
|
9
|
+
})
|
10
|
+
}
|
11
|
+
return child
|
12
|
+
})
|
13
|
+
}
|