@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 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
- ...selectProps,
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
- } & SelectProps) => JSX.Element;
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
- ...selectProps,
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.11",
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": "c759e6382b5adf6e9d19e98509c2e089246e553d"
47
+ "gitHead": "44c75e5b82172e39a2ae9877871db86418a4b9bc"
48
48
  }
@@ -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
- } & SelectProps) => {
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 (