@ttoss/forms 0.15.11 → 0.15.13
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 +111 -0
- package/dist/esm/index.js +26 -2
- package/dist/index.d.ts +6 -1
- package/dist/index.js +26 -2
- package/package.json +2 -2
- package/src/FormFieldSelect.tsx +37 -3
package/README.md
CHANGED
|
@@ -37,4 +37,115 @@ export const FormComponent = () => {
|
|
|
37
37
|
};
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
+
## FormFieldSelect support for Default Value
|
|
41
|
+
|
|
42
|
+
FormFieldSelect has support for default values, by assigning the first option defined or the value passed to it in the parameter `defaultValue`.
|
|
43
|
+
|
|
44
|
+
```tsx
|
|
45
|
+
const RADIO_OPTIONS = [
|
|
46
|
+
{ value: 'Ferrari', label: 'Ferrari' },
|
|
47
|
+
{ value: 'Mercedes', label: 'Mercedes' },
|
|
48
|
+
{ value: 'BMW', label: 'BMW' },
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
// RenderForm gonna use "Ferrari" as defaultValue
|
|
52
|
+
const RenderForm = () => {
|
|
53
|
+
const formMethods = useForm();
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<Form {...formMethods} onSubmit={onSubmit}>
|
|
57
|
+
<FormFieldSelect name="car" label="Cars" options={RADIO_OPTIONS} />
|
|
58
|
+
<Button type="submit">Submit</Button>
|
|
59
|
+
</Form>
|
|
60
|
+
);
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
// RenderForm gonna use "Mercedes" as defaultValue
|
|
64
|
+
const RenderForm = () => {
|
|
65
|
+
const formMethods = useForm();
|
|
66
|
+
|
|
67
|
+
return (
|
|
68
|
+
<Form {...formMethods} onSubmit={onSubmit}>
|
|
69
|
+
<FormFieldSelect
|
|
70
|
+
name="car"
|
|
71
|
+
label="Cars"
|
|
72
|
+
options={RADIO_OPTIONS}
|
|
73
|
+
defaultValue="Mercedes"
|
|
74
|
+
/>
|
|
75
|
+
<Button type="submit">Submit</Button>
|
|
76
|
+
</Form>
|
|
77
|
+
);
|
|
78
|
+
};
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
When a placeholder is set, if in the options don't have an empty value, automatically an empty value gonna be injected.
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
const RenderForm = () => {
|
|
85
|
+
const formMethods = useForm();
|
|
86
|
+
|
|
87
|
+
// automatically injects an empty value on the "RADIO_OPTIONS"
|
|
88
|
+
return (
|
|
89
|
+
<Form {...formMethods} onSubmit={onSubmit}>
|
|
90
|
+
<FormFieldSelect
|
|
91
|
+
name="car"
|
|
92
|
+
label="Cars"
|
|
93
|
+
options={RADIO_OPTIONS}
|
|
94
|
+
placeholder="Select a car"
|
|
95
|
+
/>
|
|
96
|
+
<Button type="submit">Submit</Button>
|
|
97
|
+
</Form>
|
|
98
|
+
);
|
|
99
|
+
};
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**Note that a placeholder cannot be set when an defaultValue is set and vice-versa**
|
|
103
|
+
|
|
104
|
+
```tsx
|
|
105
|
+
// type error!!
|
|
106
|
+
return (
|
|
107
|
+
<Form {...formMethods} onSubmit={onSubmit}>
|
|
108
|
+
<FormFieldSelect
|
|
109
|
+
name="car"
|
|
110
|
+
label="Cars"
|
|
111
|
+
options={RADIO_OPTIONS}
|
|
112
|
+
placeholder="Select a car"
|
|
113
|
+
defaultValue="Ferrari"
|
|
114
|
+
/>
|
|
115
|
+
<Button type="submit">Submit</Button>
|
|
116
|
+
</Form>
|
|
117
|
+
);
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
When your Select options depends on fetched values, the manual defaultValue setting is required.
|
|
121
|
+
|
|
122
|
+
```tsx
|
|
123
|
+
const RenderForm = () => {
|
|
124
|
+
const formMethods = useForm();
|
|
125
|
+
const { resetField } = formMethods;
|
|
126
|
+
const [formOptions, setFormOptions] = useState<
|
|
127
|
+
{
|
|
128
|
+
value: string;
|
|
129
|
+
label: string;
|
|
130
|
+
}[]
|
|
131
|
+
>([]);
|
|
132
|
+
|
|
133
|
+
useEffect(() => {
|
|
134
|
+
// some fetch operation here
|
|
135
|
+
|
|
136
|
+
setFormOptions(RADIO_OPTIONS);
|
|
137
|
+
|
|
138
|
+
// fetch are side effects, so, if the options depends on fetch and have a default value, the field should be reseted in the effect
|
|
139
|
+
resetField('car', { defaultValue: 'Ferrari' });
|
|
140
|
+
}, []);
|
|
141
|
+
|
|
142
|
+
return (
|
|
143
|
+
<Form {...formMethods} onSubmit={onSubmit}>
|
|
144
|
+
<FormFieldSelect name="car" label="Cars" options={formOptions} />
|
|
145
|
+
<Button type="submit">Submit</Button>
|
|
146
|
+
</Form>
|
|
147
|
+
);
|
|
148
|
+
};
|
|
149
|
+
```
|
|
150
|
+
|
|
40
151
|
> NOTE: You can also use yup and all of API from react-hook-form importing `import { yup, useForm } from @ttoss/forms`
|
package/dist/esm/index.js
CHANGED
|
@@ -264,6 +264,22 @@ var FormFieldRadio = ({
|
|
|
264
264
|
import { useController as useController5 } from "react-hook-form";
|
|
265
265
|
import { Flex as Flex5, Label as Label5, Select } from "@ttoss/ui";
|
|
266
266
|
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
267
|
+
var checkDefaultValue = (options, defaultValue, placeholder) => {
|
|
268
|
+
const hasEmptyValue = options.some(opt => {
|
|
269
|
+
return opt.value === "" || opt.value === 0;
|
|
270
|
+
});
|
|
271
|
+
if (placeholder && hasEmptyValue) return "";
|
|
272
|
+
if (placeholder && !hasEmptyValue) {
|
|
273
|
+
options.unshift({
|
|
274
|
+
label: placeholder,
|
|
275
|
+
value: ""
|
|
276
|
+
});
|
|
277
|
+
return "";
|
|
278
|
+
}
|
|
279
|
+
if (!placeholder && defaultValue) return defaultValue;
|
|
280
|
+
if (options.length === 0) return "";
|
|
281
|
+
return options?.[0]?.value;
|
|
282
|
+
};
|
|
267
283
|
var FormFieldSelect = ({
|
|
268
284
|
label,
|
|
269
285
|
name,
|
|
@@ -271,6 +287,11 @@ var FormFieldSelect = ({
|
|
|
271
287
|
sx,
|
|
272
288
|
...selectProps
|
|
273
289
|
}) => {
|
|
290
|
+
const {
|
|
291
|
+
defaultValue,
|
|
292
|
+
placeholder
|
|
293
|
+
} = selectProps;
|
|
294
|
+
const checkedDefaultValue = checkDefaultValue(options, defaultValue, placeholder);
|
|
274
295
|
const {
|
|
275
296
|
field: {
|
|
276
297
|
onChange,
|
|
@@ -280,7 +301,7 @@ var FormFieldSelect = ({
|
|
|
280
301
|
}
|
|
281
302
|
} = useController5({
|
|
282
303
|
name,
|
|
283
|
-
defaultValue:
|
|
304
|
+
defaultValue: checkedDefaultValue
|
|
284
305
|
});
|
|
285
306
|
const id = `form-field-select-${name}`;
|
|
286
307
|
return /* @__PURE__ */jsxs5(Flex5, {
|
|
@@ -299,7 +320,10 @@ var FormFieldSelect = ({
|
|
|
299
320
|
onBlur,
|
|
300
321
|
value,
|
|
301
322
|
id,
|
|
302
|
-
...
|
|
323
|
+
...{
|
|
324
|
+
...selectProps,
|
|
325
|
+
defaultValue: void 0
|
|
326
|
+
},
|
|
303
327
|
children: options.map(option => {
|
|
304
328
|
return /* @__PURE__ */jsx7("option", {
|
|
305
329
|
value: option.value,
|
package/dist/index.d.ts
CHANGED
|
@@ -48,11 +48,16 @@ type FormRadioOption = {
|
|
|
48
48
|
value: string | number;
|
|
49
49
|
label: string;
|
|
50
50
|
};
|
|
51
|
+
type SelectSwitchProps = (SelectProps & {
|
|
52
|
+
placeholder?: never;
|
|
53
|
+
}) | (SelectProps & {
|
|
54
|
+
defaultValue?: never;
|
|
55
|
+
});
|
|
51
56
|
declare const FormFieldSelect: <TFieldValues extends FieldValues = FieldValues>({ label, name, options, sx, ...selectProps }: {
|
|
52
57
|
label?: string | undefined;
|
|
53
58
|
name: FieldPath<TFieldValues>;
|
|
54
59
|
options: FormRadioOption[];
|
|
55
|
-
} &
|
|
60
|
+
} & SelectSwitchProps) => JSX.Element;
|
|
56
61
|
|
|
57
62
|
declare const FormFieldTextarea: <TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>>({ label, name, sx, ...textareaProps }: {
|
|
58
63
|
label?: string | undefined;
|
package/dist/index.js
CHANGED
|
@@ -315,6 +315,22 @@ var FormFieldRadio = ({
|
|
|
315
315
|
var import_react_hook_form7 = require("react-hook-form");
|
|
316
316
|
var import_ui7 = require("@ttoss/ui");
|
|
317
317
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
318
|
+
var checkDefaultValue = (options, defaultValue, placeholder) => {
|
|
319
|
+
const hasEmptyValue = options.some(opt => {
|
|
320
|
+
return opt.value === "" || opt.value === 0;
|
|
321
|
+
});
|
|
322
|
+
if (placeholder && hasEmptyValue) return "";
|
|
323
|
+
if (placeholder && !hasEmptyValue) {
|
|
324
|
+
options.unshift({
|
|
325
|
+
label: placeholder,
|
|
326
|
+
value: ""
|
|
327
|
+
});
|
|
328
|
+
return "";
|
|
329
|
+
}
|
|
330
|
+
if (!placeholder && defaultValue) return defaultValue;
|
|
331
|
+
if (options.length === 0) return "";
|
|
332
|
+
return options?.[0]?.value;
|
|
333
|
+
};
|
|
318
334
|
var FormFieldSelect = ({
|
|
319
335
|
label,
|
|
320
336
|
name,
|
|
@@ -322,6 +338,11 @@ var FormFieldSelect = ({
|
|
|
322
338
|
sx,
|
|
323
339
|
...selectProps
|
|
324
340
|
}) => {
|
|
341
|
+
const {
|
|
342
|
+
defaultValue,
|
|
343
|
+
placeholder
|
|
344
|
+
} = selectProps;
|
|
345
|
+
const checkedDefaultValue = checkDefaultValue(options, defaultValue, placeholder);
|
|
325
346
|
const {
|
|
326
347
|
field: {
|
|
327
348
|
onChange,
|
|
@@ -331,7 +352,7 @@ var FormFieldSelect = ({
|
|
|
331
352
|
}
|
|
332
353
|
} = (0, import_react_hook_form7.useController)({
|
|
333
354
|
name,
|
|
334
|
-
defaultValue:
|
|
355
|
+
defaultValue: checkedDefaultValue
|
|
335
356
|
});
|
|
336
357
|
const id = `form-field-select-${name}`;
|
|
337
358
|
return /* @__PURE__ */(0, import_jsx_runtime7.jsxs)(import_ui7.Flex, {
|
|
@@ -350,7 +371,10 @@ var FormFieldSelect = ({
|
|
|
350
371
|
onBlur,
|
|
351
372
|
value,
|
|
352
373
|
id,
|
|
353
|
-
...
|
|
374
|
+
...{
|
|
375
|
+
...selectProps,
|
|
376
|
+
defaultValue: void 0
|
|
377
|
+
},
|
|
354
378
|
children: options.map(option => {
|
|
355
379
|
return /* @__PURE__ */(0, import_jsx_runtime7.jsx)("option", {
|
|
356
380
|
value: option.value,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ttoss/forms",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.13",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"author": "ttoss",
|
|
6
6
|
"contributors": [
|
|
@@ -44,5 +44,5 @@
|
|
|
44
44
|
"publishConfig": {
|
|
45
45
|
"access": "public"
|
|
46
46
|
},
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "44c75e5b82172e39a2ae9877871db86418a4b9bc"
|
|
48
48
|
}
|
package/src/FormFieldSelect.tsx
CHANGED
|
@@ -7,6 +7,32 @@ type FormRadioOption = {
|
|
|
7
7
|
label: string;
|
|
8
8
|
};
|
|
9
9
|
|
|
10
|
+
type SelectSwitchProps =
|
|
11
|
+
| (SelectProps & { placeholder?: never })
|
|
12
|
+
| (SelectProps & { defaultValue?: never });
|
|
13
|
+
|
|
14
|
+
const checkDefaultValue = (
|
|
15
|
+
options: Array<FormRadioOption>,
|
|
16
|
+
defaultValue?: string | number | readonly string[],
|
|
17
|
+
placeholder?: string
|
|
18
|
+
) => {
|
|
19
|
+
const hasEmptyValue = options.some((opt) => {
|
|
20
|
+
return opt.value === '' || opt.value === 0;
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
if (placeholder && hasEmptyValue) return '';
|
|
24
|
+
if (placeholder && !hasEmptyValue) {
|
|
25
|
+
options.unshift({
|
|
26
|
+
label: placeholder,
|
|
27
|
+
value: '',
|
|
28
|
+
});
|
|
29
|
+
return '';
|
|
30
|
+
}
|
|
31
|
+
if (!placeholder && defaultValue) return defaultValue;
|
|
32
|
+
if (options.length === 0) return '';
|
|
33
|
+
return options?.[0]?.value;
|
|
34
|
+
};
|
|
35
|
+
|
|
10
36
|
export const FormFieldSelect = <
|
|
11
37
|
TFieldValues extends FieldValues = FieldValues
|
|
12
38
|
>({
|
|
@@ -19,12 +45,20 @@ export const FormFieldSelect = <
|
|
|
19
45
|
label?: string;
|
|
20
46
|
name: FieldPath<TFieldValues>;
|
|
21
47
|
options: FormRadioOption[];
|
|
22
|
-
} &
|
|
48
|
+
} & SelectSwitchProps) => {
|
|
49
|
+
const { defaultValue, placeholder } = selectProps;
|
|
50
|
+
|
|
51
|
+
const checkedDefaultValue = checkDefaultValue(
|
|
52
|
+
options,
|
|
53
|
+
defaultValue,
|
|
54
|
+
placeholder
|
|
55
|
+
);
|
|
56
|
+
|
|
23
57
|
const {
|
|
24
58
|
field: { onChange, onBlur, value, ref },
|
|
25
59
|
} = useController<any>({
|
|
26
60
|
name,
|
|
27
|
-
defaultValue:
|
|
61
|
+
defaultValue: checkedDefaultValue,
|
|
28
62
|
});
|
|
29
63
|
|
|
30
64
|
const id = `form-field-select-${name}`;
|
|
@@ -39,7 +73,7 @@ export const FormFieldSelect = <
|
|
|
39
73
|
onBlur={onBlur}
|
|
40
74
|
value={value}
|
|
41
75
|
id={id}
|
|
42
|
-
{...selectProps}
|
|
76
|
+
{...{ ...selectProps, defaultValue: undefined }}
|
|
43
77
|
>
|
|
44
78
|
{options.map((option) => {
|
|
45
79
|
return (
|