@saas-ui/forms 0.1.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/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
|
+
}
|