@ultraviolet/form 2.0.0-next.9 → 2.0.1
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/README.md +4 -12
- package/dist/components/SelectableCardField/index.js +12 -2
- package/package.json +10 -9
- package/dist/components/FormSpy/index.js +0 -23
- package/dist/helpers/pickValidators.js +0 -5
- package/dist/hooks/useFormField.js +0 -74
- package/dist/hooks/useValidation.js +0 -19
- package/dist/validators/index.js +0 -21
- package/dist/validators/max.js +0 -6
- package/dist/validators/maxLength.js +0 -6
- package/dist/validators/min.js +0 -6
- package/dist/validators/minLength.js +0 -6
- package/dist/validators/regex.js +0 -6
- package/dist/validators/required.js +0 -6
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://badge.fury.io/js/%40ultraviolet%2Fform)
|
|
4
4
|
|
|
5
5
|
Ultraviolet Form is an extension of Ultraviolet UI including everything to build forms using React.
|
|
6
|
-
It is using [React
|
|
6
|
+
It is using [React Hook Form](https://react-hook-form.com/) under the hood.
|
|
7
7
|
|
|
8
8
|
## Installation
|
|
9
9
|
|
|
@@ -19,11 +19,13 @@ To use the library you need to put a `ThemeProvider` from `@emotion/react` with
|
|
|
19
19
|
import { ThemeProvider } from '@emotion/react'
|
|
20
20
|
import { Form, TextInputField } from '@ultraviolet/form'
|
|
21
21
|
import { theme } from '@ultraviolet/ui'
|
|
22
|
+
import { useForm } from '@ultraviolet/form'
|
|
22
23
|
|
|
23
24
|
export default function App() {
|
|
25
|
+
const methods = useForm()
|
|
24
26
|
return (
|
|
25
27
|
<ThemeProvider theme={theme}>
|
|
26
|
-
<Form>
|
|
28
|
+
<Form methods={methods}>
|
|
27
29
|
<TextInputField name="example" />
|
|
28
30
|
</Form>
|
|
29
31
|
</ThemeProvider>
|
|
@@ -31,16 +33,6 @@ export default function App() {
|
|
|
31
33
|
}
|
|
32
34
|
```
|
|
33
35
|
|
|
34
|
-
## Contribute
|
|
35
|
-
|
|
36
|
-
### Add a validator
|
|
37
|
-
|
|
38
|
-
- Create a file under `src/validators/` folder
|
|
39
|
-
- Export a default function with a type : (arg: unknown) => ValidatorObject
|
|
40
|
-
- Export it into `src/validators/index.ts`
|
|
41
|
-
- Add the key into the `ValidatorProps` type in `src/types.ts`
|
|
42
|
-
- Add tests into `src/validators/__tests__` folder
|
|
43
|
-
|
|
44
36
|
## Documentation
|
|
45
37
|
|
|
46
38
|
Checkout our [documentation website](https://storybook.ultraviolet.scaleway.com/).
|
|
@@ -34,14 +34,24 @@ const SelectableCardField = ({
|
|
|
34
34
|
...rules
|
|
35
35
|
}
|
|
36
36
|
});
|
|
37
|
+
const isChecked = type === 'checkbox' && Array.isArray(field.value) && value ? (field.value ?? []).includes(value) : field.value === value;
|
|
37
38
|
return jsx(SelectableCard, {
|
|
38
39
|
isError: !!error,
|
|
39
40
|
showTick: showTick,
|
|
40
|
-
checked:
|
|
41
|
+
checked: isChecked,
|
|
41
42
|
className: className,
|
|
42
43
|
disabled: disabled,
|
|
43
44
|
onChange: event => {
|
|
44
|
-
|
|
45
|
+
if (type === 'checkbox') {
|
|
46
|
+
const fieldValue = field.value ?? [];
|
|
47
|
+
if (fieldValue?.includes(event.currentTarget.value)) {
|
|
48
|
+
field.onChange(fieldValue?.filter(currentValue => currentValue !== event.currentTarget.value));
|
|
49
|
+
} else {
|
|
50
|
+
field.onChange([...fieldValue, event.currentTarget.value]);
|
|
51
|
+
}
|
|
52
|
+
} else {
|
|
53
|
+
field.onChange(event);
|
|
54
|
+
}
|
|
45
55
|
onChange?.(event);
|
|
46
56
|
},
|
|
47
57
|
onBlur: event => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ultraviolet/form",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "Ultraviolet Form",
|
|
5
5
|
"homepage": "https://github.com/scaleway/ultraviolet#readme",
|
|
6
6
|
"repository": {
|
|
@@ -32,14 +32,14 @@
|
|
|
32
32
|
"default": "./dist/index.js"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
|
-
"@emotion/react": "11.11.
|
|
35
|
+
"@emotion/react": "11.11.3",
|
|
36
36
|
"@emotion/styled": "11.11.0",
|
|
37
37
|
"react": "18.x",
|
|
38
38
|
"react-dom": "18.x",
|
|
39
|
-
"react-hook-form": "7.
|
|
39
|
+
"react-hook-form": "7.49.2"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@babel/core": "7.23.
|
|
42
|
+
"@babel/core": "7.23.7",
|
|
43
43
|
"@types/final-form-focus": "1.1.7",
|
|
44
44
|
"@types/react": "18.2.45",
|
|
45
45
|
"@types/react-dom": "18.2.18",
|
|
@@ -47,15 +47,16 @@
|
|
|
47
47
|
"react-dom": "18.2.0"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@babel/runtime": "7.23.
|
|
50
|
+
"@babel/runtime": "7.23.7",
|
|
51
51
|
"@emotion/babel-plugin": "11.11.0",
|
|
52
|
-
"@emotion/react": "11.11.
|
|
52
|
+
"@emotion/react": "11.11.3",
|
|
53
53
|
"@emotion/styled": "11.11.0",
|
|
54
54
|
"react-select": "5.8.0",
|
|
55
|
-
"react-hook-form": "
|
|
56
|
-
"@ultraviolet/ui": "1.29.
|
|
55
|
+
"react-hook-form": "7.49.2",
|
|
56
|
+
"@ultraviolet/ui": "1.29.3"
|
|
57
57
|
},
|
|
58
58
|
"scripts": {
|
|
59
|
-
"build": "rollup -c ../../rollup.config.mjs"
|
|
59
|
+
"build": "rollup -c ../../rollup.config.mjs",
|
|
60
|
+
"typecheck": "tsc --noEmit"
|
|
60
61
|
}
|
|
61
62
|
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { useEffect } from 'react';
|
|
2
|
-
import { useForm } from 'react-hook-form';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @deprecated
|
|
6
|
-
*/
|
|
7
|
-
const FormSpy = _ref => {
|
|
8
|
-
let {
|
|
9
|
-
onChange
|
|
10
|
-
} = _ref;
|
|
11
|
-
const {
|
|
12
|
-
watch
|
|
13
|
-
} = useForm();
|
|
14
|
-
useEffect(() => {
|
|
15
|
-
const subscription = watch(values => onChange?.({
|
|
16
|
-
values
|
|
17
|
-
}));
|
|
18
|
-
return () => subscription.unsubscribe();
|
|
19
|
-
}, [watch, onChange]);
|
|
20
|
-
return null;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
export { FormSpy };
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { useMemo } from 'react';
|
|
2
|
-
import { useField } from 'react-final-form';
|
|
3
|
-
import { useValidation } from './useValidation.js';
|
|
4
|
-
import { pickValidators } from '../helpers/pickValidators.js';
|
|
5
|
-
|
|
6
|
-
const useFormField = (name, {
|
|
7
|
-
afterSubmit,
|
|
8
|
-
disabled,
|
|
9
|
-
allowNull,
|
|
10
|
-
beforeSubmit,
|
|
11
|
-
defaultValue,
|
|
12
|
-
format,
|
|
13
|
-
formatOnBlur,
|
|
14
|
-
initialValue,
|
|
15
|
-
isEqual,
|
|
16
|
-
multiple,
|
|
17
|
-
parse,
|
|
18
|
-
subscription,
|
|
19
|
-
type,
|
|
20
|
-
validate,
|
|
21
|
-
validateFields,
|
|
22
|
-
value,
|
|
23
|
-
max,
|
|
24
|
-
maxLength,
|
|
25
|
-
min,
|
|
26
|
-
minLength,
|
|
27
|
-
regex,
|
|
28
|
-
required,
|
|
29
|
-
maxDate,
|
|
30
|
-
minDate
|
|
31
|
-
}) => {
|
|
32
|
-
const serializedRegex = useMemo(() => regex?.toString(), [regex]);
|
|
33
|
-
const validators = useMemo(() => pickValidators({
|
|
34
|
-
max,
|
|
35
|
-
maxDate,
|
|
36
|
-
maxLength,
|
|
37
|
-
min,
|
|
38
|
-
minDate,
|
|
39
|
-
minLength,
|
|
40
|
-
regex,
|
|
41
|
-
required
|
|
42
|
-
}),
|
|
43
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
44
|
-
[max, maxLength, min, minLength, required, serializedRegex, maxDate, minDate]);
|
|
45
|
-
const validateFn = useValidation({
|
|
46
|
-
validate,
|
|
47
|
-
validators
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
51
|
-
const data = useMemo(() => ({
|
|
52
|
-
key: Math.random()
|
|
53
|
-
}), [validateFn, disabled]);
|
|
54
|
-
return useField(name, {
|
|
55
|
-
afterSubmit,
|
|
56
|
-
allowNull,
|
|
57
|
-
beforeSubmit,
|
|
58
|
-
defaultValue,
|
|
59
|
-
format,
|
|
60
|
-
formatOnBlur,
|
|
61
|
-
initialValue,
|
|
62
|
-
isEqual,
|
|
63
|
-
multiple,
|
|
64
|
-
parse,
|
|
65
|
-
subscription,
|
|
66
|
-
type,
|
|
67
|
-
validate: disabled ? undefined : validateFn,
|
|
68
|
-
validateFields,
|
|
69
|
-
value,
|
|
70
|
-
data
|
|
71
|
-
});
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
export { useFormField };
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { useCallback } from 'react';
|
|
2
|
-
|
|
3
|
-
const useValidation = ({
|
|
4
|
-
validators,
|
|
5
|
-
validate
|
|
6
|
-
}) => useCallback((value, allValues, meta) => {
|
|
7
|
-
if (validate) {
|
|
8
|
-
const validateErr = validate(value, allValues, meta);
|
|
9
|
-
if (validateErr !== undefined && validateErr !== true) {
|
|
10
|
-
return validateErr;
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
const errors = validators.filter(validator => !validator.validate(value, allValues, meta)).map(({
|
|
14
|
-
error
|
|
15
|
-
}) => error);
|
|
16
|
-
return errors.length > 0 ? errors : undefined;
|
|
17
|
-
}, [validate, validators]);
|
|
18
|
-
|
|
19
|
-
export { useValidation };
|
package/dist/validators/index.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { maxValidator } from './max.js';
|
|
2
|
-
import { maxDateValidator } from './maxDate.js';
|
|
3
|
-
import { maxLengthValidator } from './maxLength.js';
|
|
4
|
-
import { minValidator } from './min.js';
|
|
5
|
-
import { minDateValidator } from './minDate.js';
|
|
6
|
-
import { minLengthValidator } from './minLength.js';
|
|
7
|
-
import { regexValidator } from './regex.js';
|
|
8
|
-
import { requiredValidator } from './required.js';
|
|
9
|
-
|
|
10
|
-
var validators = {
|
|
11
|
-
max: maxValidator,
|
|
12
|
-
maxDate: maxDateValidator,
|
|
13
|
-
maxLength: maxLengthValidator,
|
|
14
|
-
min: minValidator,
|
|
15
|
-
minDate: minDateValidator,
|
|
16
|
-
minLength: minLengthValidator,
|
|
17
|
-
regex: regexValidator,
|
|
18
|
-
required: requiredValidator
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export { validators as default };
|
package/dist/validators/max.js
DELETED
package/dist/validators/min.js
DELETED
package/dist/validators/regex.js
DELETED