@ttoss/forms 0.17.4 → 0.17.6

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/dist/esm/index.js CHANGED
@@ -59,14 +59,15 @@ var ErrorMessage = ({
59
59
  // src/FormField.tsx
60
60
  import { useController } from "react-hook-form";
61
61
  import { Flex, Label } from "@ttoss/ui";
62
- import { jsx as jsx3, jsxs } from "react/jsx-runtime";
62
+ import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
63
63
  var FormField = ({
64
64
  label,
65
65
  id: idProp,
66
66
  name,
67
67
  defaultValue,
68
68
  sx,
69
- render
69
+ render,
70
+ ...formFieldProps
70
71
  }) => {
71
72
  const controllerReturn = useController({
72
73
  name,
@@ -75,22 +76,27 @@ var FormField = ({
75
76
  const id = idProp || `form-field-${name}`;
76
77
  const memoizedRender = React2.useMemo(() => {
77
78
  return React2.Children.map(render(controllerReturn), child => {
78
- return /*#__PURE__*/React2.createElement(child.type, {
79
- id,
80
- ...child.props
79
+ return /* @__PURE__ */jsxs(Fragment, {
80
+ children: [label && /* @__PURE__ */jsx3(Label, {
81
+ "aria-disabled": formFieldProps.disabled,
82
+ htmlFor: id,
83
+ tooltip: formFieldProps.tooltip,
84
+ onTooltipClick: formFieldProps.onTooltipClick,
85
+ children: label
86
+ }), /*#__PURE__*/React2.createElement(child.type, {
87
+ id,
88
+ ...child.props
89
+ })]
81
90
  });
82
91
  });
83
- }, [controllerReturn, id, render]);
92
+ }, [controllerReturn, formFieldProps.disabled, formFieldProps.onTooltipClick, formFieldProps.tooltip, id, label, render]);
84
93
  return /* @__PURE__ */jsxs(Flex, {
85
94
  sx: {
86
95
  flexDirection: "column",
87
96
  width: "100%",
88
97
  ...sx
89
98
  },
90
- children: [label && /* @__PURE__ */jsx3(Label, {
91
- htmlFor: id,
92
- children: label
93
- }), memoizedRender, /* @__PURE__ */jsx3(ErrorMessage, {
99
+ children: [memoizedRender, /* @__PURE__ */jsx3(ErrorMessage, {
94
100
  name
95
101
  })]
96
102
  });
@@ -153,9 +159,8 @@ var FormFieldCheckbox = ({
153
159
  };
154
160
 
155
161
  // src/FormFieldInput.tsx
156
- import { useController as useController3 } from "react-hook-form";
157
- import { Flex as Flex3, Input, Label as Label3 } from "@ttoss/ui";
158
- import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
162
+ import { Input } from "@ttoss/ui";
163
+ import { jsx as jsx5 } from "react/jsx-runtime";
159
164
  var FormFieldInput = ({
160
165
  label,
161
166
  name,
@@ -164,53 +169,30 @@ var FormFieldInput = ({
164
169
  sx,
165
170
  ...inputProps
166
171
  }) => {
167
- const {
168
- field: {
169
- onChange,
170
- onBlur,
171
- value,
172
- ref
173
- },
174
- formState: {
175
- errors
176
- }
177
- } = useController3({
172
+ return /* @__PURE__ */jsx5(FormField, {
178
173
  name,
179
- defaultValue: ""
180
- });
181
- const id = `form-field-input-${name}`;
182
- const hasError = !!errors[name]?.message;
183
- return /* @__PURE__ */jsxs3(Flex3, {
184
- sx: {
185
- flexDirection: "column",
186
- width: "100%",
187
- ...sx
188
- },
189
- children: [label && /* @__PURE__ */jsx5(Label3, {
190
- "aria-disabled": inputProps.disabled,
191
- htmlFor: id,
192
- tooltip,
193
- onTooltipClick,
194
- children: label
195
- }), /* @__PURE__ */jsx5(Input, {
196
- ref,
197
- onChange,
198
- className: hasError ? "error" : "",
199
- onBlur,
200
- value,
201
- name,
202
- id,
203
- ...inputProps
204
- }), /* @__PURE__ */jsx5(ErrorMessage, {
205
- name
206
- })]
174
+ label,
175
+ disabled: inputProps.disabled,
176
+ tooltip,
177
+ onTooltipClick,
178
+ sx,
179
+ render: ({
180
+ field,
181
+ formState
182
+ }) => {
183
+ const hasError = !!formState.errors[name]?.message;
184
+ return /* @__PURE__ */jsx5(Input, {
185
+ ...inputProps,
186
+ ...field,
187
+ "aria-invalid": hasError.valueOf()
188
+ });
189
+ }
207
190
  });
208
191
  };
209
192
 
210
193
  // src/FormFieldPassword.tsx
211
- import { useController as useController4 } from "react-hook-form";
212
- import { Flex as Flex4, InputPassword, Label as Label4 } from "@ttoss/ui";
213
- import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
194
+ import { InputPassword } from "@ttoss/ui";
195
+ import { jsx as jsx6 } from "react/jsx-runtime";
214
196
  var FormFieldPassword = ({
215
197
  label,
216
198
  name,
@@ -219,53 +201,31 @@ var FormFieldPassword = ({
219
201
  sx,
220
202
  ...inputProps
221
203
  }) => {
222
- const {
223
- field: {
224
- onChange,
225
- onBlur,
226
- value,
227
- ref
228
- },
229
- formState: {
230
- errors
231
- }
232
- } = useController4({
204
+ return /* @__PURE__ */jsx6(FormField, {
233
205
  name,
234
- defaultValue: ""
235
- });
236
- const id = `form-field-password-${name}`;
237
- const hasError = !!errors[name]?.message;
238
- return /* @__PURE__ */jsxs4(Flex4, {
239
- sx: {
240
- flexDirection: "column",
241
- width: "100%",
242
- ...sx
243
- },
244
- children: [label && /* @__PURE__ */jsx6(Label4, {
245
- "aria-disabled": inputProps.disabled,
246
- htmlFor: id,
247
- tooltip,
248
- onTooltipClick,
249
- children: label
250
- }), /* @__PURE__ */jsx6(InputPassword, {
251
- ref,
252
- onChange,
253
- className: hasError ? "error" : "",
254
- onBlur,
255
- value,
256
- name,
257
- id,
258
- ...inputProps
259
- }), /* @__PURE__ */jsx6(ErrorMessage, {
260
- name
261
- })]
206
+ label,
207
+ disabled: inputProps.disabled,
208
+ tooltip,
209
+ onTooltipClick,
210
+ sx,
211
+ render: ({
212
+ field,
213
+ formState
214
+ }) => {
215
+ const hasError = !!formState.errors[name]?.message;
216
+ return /* @__PURE__ */jsx6(InputPassword, {
217
+ ...inputProps,
218
+ ...field,
219
+ "aria-invalid": hasError.valueOf()
220
+ });
221
+ }
262
222
  });
263
223
  };
264
224
 
265
225
  // src/FormFieldRadio.tsx
266
- import { Box as Box2, Flex as Flex5, Label as Label5, Radio } from "@ttoss/ui";
267
- import { useController as useController5 } from "react-hook-form";
268
- import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
226
+ import { Box as Box2, Flex as Flex3, Label as Label3, Radio } from "@ttoss/ui";
227
+ import { useController as useController3 } from "react-hook-form";
228
+ import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
269
229
  var FormFieldRadio = ({
270
230
  label,
271
231
  name,
@@ -280,22 +240,22 @@ var FormFieldRadio = ({
280
240
  value,
281
241
  ref
282
242
  }
283
- } = useController5({
243
+ } = useController3({
284
244
  name,
285
245
  defaultValue: ""
286
246
  });
287
- return /* @__PURE__ */jsxs5(Flex5, {
247
+ return /* @__PURE__ */jsxs3(Flex3, {
288
248
  sx: {
289
249
  flexDirection: "column",
290
250
  width: "100%",
291
251
  ...sx
292
252
  },
293
- children: [label && /* @__PURE__ */jsx7(Label5, {
253
+ children: [label && /* @__PURE__ */jsx7(Label3, {
294
254
  children: label
295
255
  }), /* @__PURE__ */jsx7(Box2, {
296
256
  children: options.map(option => {
297
257
  const id = `form-field-radio-${name}-${option.value}`;
298
- return /* @__PURE__ */jsxs5(Label5, {
258
+ return /* @__PURE__ */jsxs3(Label3, {
299
259
  htmlFor: id,
300
260
  children: [/* @__PURE__ */jsx7(Radio, {
301
261
  ref,
@@ -316,23 +276,28 @@ var FormFieldRadio = ({
316
276
  };
317
277
 
318
278
  // src/FormFieldSelect.tsx
319
- import { useController as useController6 } from "react-hook-form";
320
- import { Flex as Flex6, Label as Label6, Select } from "@ttoss/ui";
321
- import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
279
+ import { Select } from "@ttoss/ui";
280
+ import { jsx as jsx8 } from "react/jsx-runtime";
322
281
  var checkDefaultValue = (options, defaultValue, placeholder) => {
282
+ if (defaultValue) {
283
+ return defaultValue;
284
+ }
323
285
  const hasEmptyValue = options.some(opt => {
324
286
  return opt.value === "" || opt.value === 0;
325
287
  });
326
- if (placeholder && hasEmptyValue) return "";
288
+ const EMPTY_VALUE = "";
289
+ if (placeholder && hasEmptyValue) {
290
+ return EMPTY_VALUE;
291
+ }
327
292
  if (placeholder && !hasEmptyValue) {
328
293
  options.unshift({
329
294
  label: placeholder,
330
295
  value: ""
331
296
  });
332
- return "";
297
+ return EMPTY_VALUE;
333
298
  }
334
- if (!placeholder && defaultValue) return defaultValue;
335
- if (options.length === 0) return "";
299
+ if (!placeholder && defaultValue) return EMPTY_VALUE;
300
+ if (options.length === 0) return EMPTY_VALUE;
336
301
  return options?.[0]?.value;
337
302
  };
338
303
  var FormFieldSelect = ({
@@ -347,47 +312,32 @@ var FormFieldSelect = ({
347
312
  placeholder
348
313
  } = selectProps;
349
314
  const checkedDefaultValue = checkDefaultValue(options, defaultValue, placeholder);
350
- const {
351
- field: {
352
- onChange,
353
- onBlur,
354
- value,
355
- ref
356
- }
357
- } = useController6({
315
+ return /* @__PURE__ */jsx8(FormField, {
358
316
  name,
359
- defaultValue: checkedDefaultValue
360
- });
361
- const id = `form-field-select-${name}`;
362
- return /* @__PURE__ */jsxs6(Flex6, {
363
- sx: {
364
- flexDirection: "column",
365
- width: "100%",
366
- ...sx
367
- },
368
- children: [label && /* @__PURE__ */jsx8(Label6, {
369
- htmlFor: id,
370
- children: label
371
- }), /* @__PURE__ */jsx8(Select, {
372
- ref,
373
- name,
374
- onChange,
375
- onBlur,
376
- value,
377
- id,
378
- ...{
317
+ label,
318
+ disabled: selectProps.disabled,
319
+ tooltip: selectProps.tooltip,
320
+ onTooltipClick: selectProps.onTooltipClick,
321
+ sx,
322
+ defaultValue: checkedDefaultValue,
323
+ render: ({
324
+ field
325
+ }) => {
326
+ return /* @__PURE__ */jsx8(Select, {
379
327
  ...selectProps,
380
- defaultValue: void 0
381
- },
382
- children: options.map(option => {
383
- return /* @__PURE__ */jsx8("option", {
384
- value: option.value,
385
- children: option.label
386
- }, option.label);
387
- })
388
- }), /* @__PURE__ */jsx8(ErrorMessage, {
389
- name
390
- })]
328
+ ...field,
329
+ ...{
330
+ ...selectProps,
331
+ defaultValue: void 0
332
+ },
333
+ children: options.map(option => {
334
+ return /* @__PURE__ */jsx8("option", {
335
+ value: option.value,
336
+ children: option.label
337
+ }, option.label);
338
+ })
339
+ });
340
+ }
391
341
  });
392
342
  };
393
343
 
@@ -419,8 +369,8 @@ var FormFieldTextarea = ({
419
369
 
420
370
  // src/FormGroup.tsx
421
371
  import * as React3 from "react";
422
- import { Box as Box3, Flex as Flex7, Text } from "@ttoss/ui";
423
- import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
372
+ import { Box as Box3, Flex as Flex4, Text } from "@ttoss/ui";
373
+ import { jsx as jsx10, jsxs as jsxs4 } from "react/jsx-runtime";
424
374
  var FormGroupLevelsManagerContext = /*#__PURE__*/React3.createContext({
425
375
  levelsLength: 1,
426
376
  registerChild: () => {
@@ -479,7 +429,7 @@ var FormGroupWrapper = ({
479
429
  gap: "md",
480
430
  width: "100%"
481
431
  };
482
- return /* @__PURE__ */jsxs7(Box3, {
432
+ return /* @__PURE__ */jsxs4(Box3, {
483
433
  "aria-level": level,
484
434
  ...boxProps,
485
435
  sx: {
@@ -498,7 +448,7 @@ var FormGroupWrapper = ({
498
448
  },
499
449
  children: title
500
450
  })
501
- }), /* @__PURE__ */jsx10(Flex7, {
451
+ }), /* @__PURE__ */jsx10(Flex4, {
502
452
  sx: childrenContainerSx,
503
453
  children
504
454
  })]
package/dist/index.d.ts CHANGED
@@ -5,7 +5,7 @@ export * from 'react-hook-form';
5
5
  import * as yup from 'yup';
6
6
  export { yup };
7
7
  import * as React from 'react';
8
- import { BoxProps, FlexProps, CheckboxProps, InputProps, LabelProps, InputPasswordProps, RadioProps, SelectProps, TextareaProps } from '@ttoss/ui';
8
+ import { BoxProps, FlexProps, CheckboxProps, InputProps, InputPasswordProps, RadioProps, SelectProps, TextareaProps } from '@ttoss/ui';
9
9
 
10
10
  declare const Form: <TFieldValues extends FieldValues = FieldValues>({ children, onSubmit, sx, ...formMethods }: {
11
11
  children?: React.ReactNode;
@@ -15,14 +15,20 @@ declare const Form: <TFieldValues extends FieldValues = FieldValues>({ children,
15
15
  children: React.ReactNode | React.ReactNode[];
16
16
  } & react_hook_form.UseFormReturn<TFieldValues, any>) => JSX.Element;
17
17
 
18
- declare const FormField: <TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>>({ label, id: idProp, name, defaultValue, sx, render, }: {
19
- label?: string | undefined;
20
- id?: string | undefined;
21
- name: TName;
22
- defaultValue?: FieldPathValue<TFieldValues, TName> | undefined;
18
+ type FormFieldProps = {
23
19
  sx?: FlexProps['sx'];
20
+ disabled?: boolean;
21
+ tooltip?: boolean;
22
+ onTooltipClick?: () => void;
23
+ };
24
+ type FormFieldCompleteProps<TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>> = {
25
+ label?: string;
26
+ id?: string;
27
+ name: TName;
28
+ defaultValue?: FieldPathValue<TFieldValues, TName>;
24
29
  render: (props: UseControllerReturn<TFieldValues, TName>) => React.ReactElement;
25
- }) => JSX.Element;
30
+ } & FormFieldProps;
31
+ declare const FormField: <TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>>({ label, id: idProp, name, defaultValue, sx, render, ...formFieldProps }: FormFieldCompleteProps<TFieldValues, TName>) => JSX.Element;
26
32
 
27
33
  declare const FormFieldCheckbox: <TFieldValues extends FieldValues = FieldValues>({ label, name, sx, ...checkboxProps }: {
28
34
  label?: string | undefined;
@@ -32,13 +38,13 @@ declare const FormFieldCheckbox: <TFieldValues extends FieldValues = FieldValues
32
38
  type FormFieldInputProps<TName> = {
33
39
  label?: string;
34
40
  name: TName;
35
- } & InputProps & Pick<LabelProps, 'tooltip' | 'onTooltipClick'>;
41
+ } & InputProps & FormFieldProps;
36
42
  declare const FormFieldInput: <TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>>({ label, name, tooltip, onTooltipClick, sx, ...inputProps }: FormFieldInputProps<TName>) => JSX.Element;
37
43
 
38
44
  type FormFieldPasswordProps<TName> = {
39
45
  label?: string;
40
46
  name: TName;
41
- } & InputPasswordProps & Pick<LabelProps, 'tooltip' | 'onTooltipClick'>;
47
+ } & InputPasswordProps & FormFieldProps;
42
48
  declare const FormFieldPassword: <TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>>({ label, name, tooltip, onTooltipClick, sx, ...inputProps }: FormFieldPasswordProps<TName>) => JSX.Element;
43
49
 
44
50
  type FormRadioOption$1 = {
@@ -60,11 +66,13 @@ type SelectSwitchProps = (SelectProps & {
60
66
  }) | (SelectProps & {
61
67
  defaultValue?: never;
62
68
  });
63
- declare const FormFieldSelect: <TFieldValues extends FieldValues = FieldValues>({ label, name, options, sx, ...selectProps }: {
64
- label?: string | undefined;
69
+ type FormFieldSelectProps<TFieldValues extends FieldValues, TName extends FieldPath<TFieldValues>> = SelectSwitchProps & FormFieldProps & {
70
+ label?: string;
65
71
  name: FieldPath<TFieldValues>;
66
72
  options: FormRadioOption[];
67
- } & SelectSwitchProps) => JSX.Element;
73
+ defaultValue?: FieldPathValue<TFieldValues, TName>;
74
+ };
75
+ declare const FormFieldSelect: <TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>>({ label, name, options, sx, ...selectProps }: FormFieldSelectProps<TFieldValues, TName>) => JSX.Element;
68
76
 
69
77
  declare const FormFieldTextarea: <TFieldValues extends FieldValues = FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>>({ label, name, sx, ...textareaProps }: {
70
78
  label?: string | undefined;
package/dist/index.js CHANGED
@@ -118,7 +118,8 @@ var FormField = ({
118
118
  name,
119
119
  defaultValue,
120
120
  sx,
121
- render
121
+ render,
122
+ ...formFieldProps
122
123
  }) => {
123
124
  const controllerReturn = (0, import_react_hook_form3.useController)({
124
125
  name,
@@ -127,22 +128,27 @@ var FormField = ({
127
128
  const id = idProp || `form-field-${name}`;
128
129
  const memoizedRender = React2.useMemo(() => {
129
130
  return React2.Children.map(render(controllerReturn), child => {
130
- return React2.createElement(child.type, {
131
- id,
132
- ...child.props
131
+ return /* @__PURE__ */(0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, {
132
+ children: [label && /* @__PURE__ */(0, import_jsx_runtime3.jsx)(import_ui3.Label, {
133
+ "aria-disabled": formFieldProps.disabled,
134
+ htmlFor: id,
135
+ tooltip: formFieldProps.tooltip,
136
+ onTooltipClick: formFieldProps.onTooltipClick,
137
+ children: label
138
+ }), React2.createElement(child.type, {
139
+ id,
140
+ ...child.props
141
+ })]
133
142
  });
134
143
  });
135
- }, [controllerReturn, id, render]);
144
+ }, [controllerReturn, formFieldProps.disabled, formFieldProps.onTooltipClick, formFieldProps.tooltip, id, label, render]);
136
145
  return /* @__PURE__ */(0, import_jsx_runtime3.jsxs)(import_ui3.Flex, {
137
146
  sx: {
138
147
  flexDirection: "column",
139
148
  width: "100%",
140
149
  ...sx
141
150
  },
142
- children: [label && /* @__PURE__ */(0, import_jsx_runtime3.jsx)(import_ui3.Label, {
143
- htmlFor: id,
144
- children: label
145
- }), memoizedRender, /* @__PURE__ */(0, import_jsx_runtime3.jsx)(ErrorMessage, {
151
+ children: [memoizedRender, /* @__PURE__ */(0, import_jsx_runtime3.jsx)(ErrorMessage, {
146
152
  name
147
153
  })]
148
154
  });
@@ -205,7 +211,6 @@ var FormFieldCheckbox = ({
205
211
  };
206
212
 
207
213
  // src/FormFieldInput.tsx
208
- var import_react_hook_form5 = require("react-hook-form");
209
214
  var import_ui5 = require("@ttoss/ui");
210
215
  var import_jsx_runtime5 = require("react/jsx-runtime");
211
216
  var FormFieldInput = ({
@@ -216,51 +221,28 @@ var FormFieldInput = ({
216
221
  sx,
217
222
  ...inputProps
218
223
  }) => {
219
- const {
220
- field: {
221
- onChange,
222
- onBlur,
223
- value,
224
- ref
225
- },
226
- formState: {
227
- errors
228
- }
229
- } = (0, import_react_hook_form5.useController)({
224
+ return /* @__PURE__ */(0, import_jsx_runtime5.jsx)(FormField, {
230
225
  name,
231
- defaultValue: ""
232
- });
233
- const id = `form-field-input-${name}`;
234
- const hasError = !!errors[name]?.message;
235
- return /* @__PURE__ */(0, import_jsx_runtime5.jsxs)(import_ui5.Flex, {
236
- sx: {
237
- flexDirection: "column",
238
- width: "100%",
239
- ...sx
240
- },
241
- children: [label && /* @__PURE__ */(0, import_jsx_runtime5.jsx)(import_ui5.Label, {
242
- "aria-disabled": inputProps.disabled,
243
- htmlFor: id,
244
- tooltip,
245
- onTooltipClick,
246
- children: label
247
- }), /* @__PURE__ */(0, import_jsx_runtime5.jsx)(import_ui5.Input, {
248
- ref,
249
- onChange,
250
- className: hasError ? "error" : "",
251
- onBlur,
252
- value,
253
- name,
254
- id,
255
- ...inputProps
256
- }), /* @__PURE__ */(0, import_jsx_runtime5.jsx)(ErrorMessage, {
257
- name
258
- })]
226
+ label,
227
+ disabled: inputProps.disabled,
228
+ tooltip,
229
+ onTooltipClick,
230
+ sx,
231
+ render: ({
232
+ field,
233
+ formState
234
+ }) => {
235
+ const hasError = !!formState.errors[name]?.message;
236
+ return /* @__PURE__ */(0, import_jsx_runtime5.jsx)(import_ui5.Input, {
237
+ ...inputProps,
238
+ ...field,
239
+ "aria-invalid": hasError.valueOf()
240
+ });
241
+ }
259
242
  });
260
243
  };
261
244
 
262
245
  // src/FormFieldPassword.tsx
263
- var import_react_hook_form6 = require("react-hook-form");
264
246
  var import_ui6 = require("@ttoss/ui");
265
247
  var import_jsx_runtime6 = require("react/jsx-runtime");
266
248
  var FormFieldPassword = ({
@@ -271,52 +253,30 @@ var FormFieldPassword = ({
271
253
  sx,
272
254
  ...inputProps
273
255
  }) => {
274
- const {
275
- field: {
276
- onChange,
277
- onBlur,
278
- value,
279
- ref
280
- },
281
- formState: {
282
- errors
283
- }
284
- } = (0, import_react_hook_form6.useController)({
256
+ return /* @__PURE__ */(0, import_jsx_runtime6.jsx)(FormField, {
285
257
  name,
286
- defaultValue: ""
287
- });
288
- const id = `form-field-password-${name}`;
289
- const hasError = !!errors[name]?.message;
290
- return /* @__PURE__ */(0, import_jsx_runtime6.jsxs)(import_ui6.Flex, {
291
- sx: {
292
- flexDirection: "column",
293
- width: "100%",
294
- ...sx
295
- },
296
- children: [label && /* @__PURE__ */(0, import_jsx_runtime6.jsx)(import_ui6.Label, {
297
- "aria-disabled": inputProps.disabled,
298
- htmlFor: id,
299
- tooltip,
300
- onTooltipClick,
301
- children: label
302
- }), /* @__PURE__ */(0, import_jsx_runtime6.jsx)(import_ui6.InputPassword, {
303
- ref,
304
- onChange,
305
- className: hasError ? "error" : "",
306
- onBlur,
307
- value,
308
- name,
309
- id,
310
- ...inputProps
311
- }), /* @__PURE__ */(0, import_jsx_runtime6.jsx)(ErrorMessage, {
312
- name
313
- })]
258
+ label,
259
+ disabled: inputProps.disabled,
260
+ tooltip,
261
+ onTooltipClick,
262
+ sx,
263
+ render: ({
264
+ field,
265
+ formState
266
+ }) => {
267
+ const hasError = !!formState.errors[name]?.message;
268
+ return /* @__PURE__ */(0, import_jsx_runtime6.jsx)(import_ui6.InputPassword, {
269
+ ...inputProps,
270
+ ...field,
271
+ "aria-invalid": hasError.valueOf()
272
+ });
273
+ }
314
274
  });
315
275
  };
316
276
 
317
277
  // src/FormFieldRadio.tsx
318
278
  var import_ui7 = require("@ttoss/ui");
319
- var import_react_hook_form7 = require("react-hook-form");
279
+ var import_react_hook_form5 = require("react-hook-form");
320
280
  var import_jsx_runtime7 = require("react/jsx-runtime");
321
281
  var FormFieldRadio = ({
322
282
  label,
@@ -332,7 +292,7 @@ var FormFieldRadio = ({
332
292
  value,
333
293
  ref
334
294
  }
335
- } = (0, import_react_hook_form7.useController)({
295
+ } = (0, import_react_hook_form5.useController)({
336
296
  name,
337
297
  defaultValue: ""
338
298
  });
@@ -368,23 +328,28 @@ var FormFieldRadio = ({
368
328
  };
369
329
 
370
330
  // src/FormFieldSelect.tsx
371
- var import_react_hook_form8 = require("react-hook-form");
372
331
  var import_ui8 = require("@ttoss/ui");
373
332
  var import_jsx_runtime8 = require("react/jsx-runtime");
374
333
  var checkDefaultValue = (options, defaultValue, placeholder) => {
334
+ if (defaultValue) {
335
+ return defaultValue;
336
+ }
375
337
  const hasEmptyValue = options.some(opt => {
376
338
  return opt.value === "" || opt.value === 0;
377
339
  });
378
- if (placeholder && hasEmptyValue) return "";
340
+ const EMPTY_VALUE = "";
341
+ if (placeholder && hasEmptyValue) {
342
+ return EMPTY_VALUE;
343
+ }
379
344
  if (placeholder && !hasEmptyValue) {
380
345
  options.unshift({
381
346
  label: placeholder,
382
347
  value: ""
383
348
  });
384
- return "";
349
+ return EMPTY_VALUE;
385
350
  }
386
- if (!placeholder && defaultValue) return defaultValue;
387
- if (options.length === 0) return "";
351
+ if (!placeholder && defaultValue) return EMPTY_VALUE;
352
+ if (options.length === 0) return EMPTY_VALUE;
388
353
  return options?.[0]?.value;
389
354
  };
390
355
  var FormFieldSelect = ({
@@ -399,47 +364,32 @@ var FormFieldSelect = ({
399
364
  placeholder
400
365
  } = selectProps;
401
366
  const checkedDefaultValue = checkDefaultValue(options, defaultValue, placeholder);
402
- const {
403
- field: {
404
- onChange,
405
- onBlur,
406
- value,
407
- ref
408
- }
409
- } = (0, import_react_hook_form8.useController)({
367
+ return /* @__PURE__ */(0, import_jsx_runtime8.jsx)(FormField, {
410
368
  name,
411
- defaultValue: checkedDefaultValue
412
- });
413
- const id = `form-field-select-${name}`;
414
- return /* @__PURE__ */(0, import_jsx_runtime8.jsxs)(import_ui8.Flex, {
415
- sx: {
416
- flexDirection: "column",
417
- width: "100%",
418
- ...sx
419
- },
420
- children: [label && /* @__PURE__ */(0, import_jsx_runtime8.jsx)(import_ui8.Label, {
421
- htmlFor: id,
422
- children: label
423
- }), /* @__PURE__ */(0, import_jsx_runtime8.jsx)(import_ui8.Select, {
424
- ref,
425
- name,
426
- onChange,
427
- onBlur,
428
- value,
429
- id,
430
- ...{
369
+ label,
370
+ disabled: selectProps.disabled,
371
+ tooltip: selectProps.tooltip,
372
+ onTooltipClick: selectProps.onTooltipClick,
373
+ sx,
374
+ defaultValue: checkedDefaultValue,
375
+ render: ({
376
+ field
377
+ }) => {
378
+ return /* @__PURE__ */(0, import_jsx_runtime8.jsx)(import_ui8.Select, {
431
379
  ...selectProps,
432
- defaultValue: void 0
433
- },
434
- children: options.map(option => {
435
- return /* @__PURE__ */(0, import_jsx_runtime8.jsx)("option", {
436
- value: option.value,
437
- children: option.label
438
- }, option.label);
439
- })
440
- }), /* @__PURE__ */(0, import_jsx_runtime8.jsx)(ErrorMessage, {
441
- name
442
- })]
380
+ ...field,
381
+ ...{
382
+ ...selectProps,
383
+ defaultValue: void 0
384
+ },
385
+ children: options.map(option => {
386
+ return /* @__PURE__ */(0, import_jsx_runtime8.jsx)("option", {
387
+ value: option.value,
388
+ children: option.label
389
+ }, option.label);
390
+ })
391
+ });
392
+ }
443
393
  });
444
394
  };
445
395
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttoss/forms",
3
- "version": "0.17.4",
3
+ "version": "0.17.6",
4
4
  "license": "UNLICENSED",
5
5
  "author": "ttoss",
6
6
  "contributors": [
@@ -22,7 +22,7 @@
22
22
  },
23
23
  "peerDependencies": {
24
24
  "react": ">=16.8.0",
25
- "@ttoss/ui": "^1.36.4"
25
+ "@ttoss/ui": "^1.36.6"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@types/jest": "^29.5.1",
@@ -35,7 +35,7 @@
35
35
  "yup": "^1.1.1",
36
36
  "@ttoss/config": "^1.30.0",
37
37
  "@ttoss/test-utils": "^1.23.0",
38
- "@ttoss/ui": "^1.36.4"
38
+ "@ttoss/ui": "^1.36.6"
39
39
  },
40
40
  "publishConfig": {
41
41
  "access": "public"
package/src/FormField.tsx CHANGED
@@ -9,6 +9,26 @@ import {
9
9
  } from 'react-hook-form';
10
10
  import { Flex, type FlexProps, Label } from '@ttoss/ui';
11
11
 
12
+ export type FormFieldProps = {
13
+ sx?: FlexProps['sx'];
14
+ disabled?: boolean;
15
+ tooltip?: boolean;
16
+ onTooltipClick?: () => void;
17
+ };
18
+
19
+ type FormFieldCompleteProps<
20
+ TFieldValues extends FieldValues = FieldValues,
21
+ TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
22
+ > = {
23
+ label?: string;
24
+ id?: string;
25
+ name: TName;
26
+ defaultValue?: FieldPathValue<TFieldValues, TName>;
27
+ render: (
28
+ props: UseControllerReturn<TFieldValues, TName>
29
+ ) => React.ReactElement;
30
+ } & FormFieldProps;
31
+
12
32
  export const FormField = <
13
33
  TFieldValues extends FieldValues = FieldValues,
14
34
  TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
@@ -19,16 +39,8 @@ export const FormField = <
19
39
  defaultValue,
20
40
  sx,
21
41
  render,
22
- }: {
23
- label?: string;
24
- id?: string;
25
- name: TName;
26
- defaultValue?: FieldPathValue<TFieldValues, TName>;
27
- sx?: FlexProps['sx'];
28
- render: (
29
- props: UseControllerReturn<TFieldValues, TName>
30
- ) => React.ReactElement;
31
- }) => {
42
+ ...formFieldProps
43
+ }: FormFieldCompleteProps<TFieldValues, TName>) => {
32
44
  const controllerReturn = useController<TFieldValues, TName>({
33
45
  name,
34
46
  defaultValue,
@@ -38,13 +50,35 @@ export const FormField = <
38
50
 
39
51
  const memoizedRender = React.useMemo(() => {
40
52
  return React.Children.map(render(controllerReturn), (child) => {
41
- return React.createElement(child.type, { id, ...child.props });
53
+ return (
54
+ <>
55
+ {label && (
56
+ <Label
57
+ aria-disabled={formFieldProps.disabled}
58
+ htmlFor={id}
59
+ tooltip={formFieldProps.tooltip}
60
+ onTooltipClick={formFieldProps.onTooltipClick}
61
+ >
62
+ {label}
63
+ </Label>
64
+ )}
65
+
66
+ {React.createElement(child.type, { id, ...child.props })}
67
+ </>
68
+ );
42
69
  });
43
- }, [controllerReturn, id, render]);
70
+ }, [
71
+ controllerReturn,
72
+ formFieldProps.disabled,
73
+ formFieldProps.onTooltipClick,
74
+ formFieldProps.tooltip,
75
+ id,
76
+ label,
77
+ render,
78
+ ]);
44
79
 
45
80
  return (
46
81
  <Flex sx={{ flexDirection: 'column', width: '100%', ...sx }}>
47
- {label && <Label htmlFor={id}>{label}</Label>}
48
82
  {memoizedRender}
49
83
  <ErrorMessage name={name} />
50
84
  </Flex>
@@ -1,18 +1,12 @@
1
- import { ErrorMessage } from './ErrorMessage';
2
- import { FieldPath, FieldValues, useController } from 'react-hook-form';
3
- import {
4
- Flex,
5
- Input,
6
- type InputProps,
7
- Label,
8
- type LabelProps,
9
- } from '@ttoss/ui';
1
+ import { FieldPath, FieldValues } from 'react-hook-form';
2
+ import { FormField, type FormFieldProps } from './FormField';
3
+ import { Input, type InputProps } from '@ttoss/ui';
10
4
 
11
5
  export type FormFieldInputProps<TName> = {
12
6
  label?: string;
13
7
  name: TName;
14
8
  } & InputProps &
15
- Pick<LabelProps, 'tooltip' | 'onTooltipClick'>;
9
+ FormFieldProps;
16
10
 
17
11
  export const FormFieldInput = <
18
12
  TFieldValues extends FieldValues = FieldValues,
@@ -25,43 +19,21 @@ export const FormFieldInput = <
25
19
  sx,
26
20
  ...inputProps
27
21
  }: FormFieldInputProps<TName>) => {
28
- const {
29
- field: { onChange, onBlur, value, ref },
30
- formState: { errors },
31
- } = useController<any>({
32
- name,
33
- defaultValue: '',
34
- });
35
-
36
- const id = `form-field-input-${name}`;
37
-
38
- const hasError = !!errors[name]?.message;
39
-
40
22
  return (
41
- <Flex sx={{ flexDirection: 'column', width: '100%', ...sx }}>
42
- {label && (
43
- <Label
44
- aria-disabled={inputProps.disabled}
45
- htmlFor={id}
46
- tooltip={tooltip}
47
- onTooltipClick={onTooltipClick}
48
- >
49
- {label}
50
- </Label>
51
- )}
52
-
53
- <Input
54
- ref={ref}
55
- onChange={onChange}
56
- className={hasError ? 'error' : ''}
57
- onBlur={onBlur}
58
- value={value}
59
- name={name}
60
- id={id}
61
- {...inputProps}
62
- />
23
+ <FormField
24
+ name={name}
25
+ label={label}
26
+ disabled={inputProps.disabled}
27
+ tooltip={tooltip}
28
+ onTooltipClick={onTooltipClick}
29
+ sx={sx}
30
+ render={({ field, formState }) => {
31
+ const hasError = !!formState.errors[name]?.message;
63
32
 
64
- <ErrorMessage name={name} />
65
- </Flex>
33
+ return (
34
+ <Input {...inputProps} {...field} aria-invalid={hasError.valueOf()} />
35
+ );
36
+ }}
37
+ />
66
38
  );
67
39
  };
@@ -1,18 +1,12 @@
1
- import { ErrorMessage } from './ErrorMessage';
2
- import { FieldPath, FieldValues, useController } from 'react-hook-form';
3
- import {
4
- Flex,
5
- InputPassword,
6
- type InputPasswordProps,
7
- Label,
8
- type LabelProps,
9
- } from '@ttoss/ui';
1
+ import { FieldPath, FieldValues } from 'react-hook-form';
2
+ import { FormField, type FormFieldProps } from './FormField';
3
+ import { InputPassword, type InputPasswordProps } from '@ttoss/ui';
10
4
 
11
5
  export type FormFieldPasswordProps<TName> = {
12
6
  label?: string;
13
7
  name: TName;
14
8
  } & InputPasswordProps &
15
- Pick<LabelProps, 'tooltip' | 'onTooltipClick'>;
9
+ FormFieldProps;
16
10
 
17
11
  export const FormFieldPassword = <
18
12
  TFieldValues extends FieldValues = FieldValues,
@@ -25,43 +19,25 @@ export const FormFieldPassword = <
25
19
  sx,
26
20
  ...inputProps
27
21
  }: FormFieldPasswordProps<TName>) => {
28
- const {
29
- field: { onChange, onBlur, value, ref },
30
- formState: { errors },
31
- } = useController<any>({
32
- name,
33
- defaultValue: '',
34
- });
35
-
36
- const id = `form-field-password-${name}`;
37
-
38
- const hasError = !!errors[name]?.message;
39
-
40
22
  return (
41
- <Flex sx={{ flexDirection: 'column', width: '100%', ...sx }}>
42
- {label && (
43
- <Label
44
- aria-disabled={inputProps.disabled}
45
- htmlFor={id}
46
- tooltip={tooltip}
47
- onTooltipClick={onTooltipClick}
48
- >
49
- {label}
50
- </Label>
51
- )}
52
-
53
- <InputPassword
54
- ref={ref}
55
- onChange={onChange}
56
- className={hasError ? 'error' : ''}
57
- onBlur={onBlur}
58
- value={value}
59
- name={name}
60
- id={id}
61
- {...inputProps}
62
- />
23
+ <FormField
24
+ name={name}
25
+ label={label}
26
+ disabled={inputProps.disabled}
27
+ tooltip={tooltip}
28
+ onTooltipClick={onTooltipClick}
29
+ sx={sx}
30
+ render={({ field, formState }) => {
31
+ const hasError = !!formState.errors[name]?.message;
63
32
 
64
- <ErrorMessage name={name} />
65
- </Flex>
33
+ return (
34
+ <InputPassword
35
+ {...inputProps}
36
+ {...field}
37
+ aria-invalid={hasError.valueOf()}
38
+ />
39
+ );
40
+ }}
41
+ />
66
42
  );
67
43
  };
@@ -1,6 +1,6 @@
1
- import { ErrorMessage } from './ErrorMessage';
2
- import { FieldPath, FieldValues, useController } from 'react-hook-form';
3
- import { Flex, Label, Select, type SelectProps } from '@ttoss/ui';
1
+ import { FieldPath, FieldPathValue, FieldValues } from 'react-hook-form';
2
+ import { FormField, FormFieldProps } from './FormField';
3
+ import { Select, type SelectProps } from '@ttoss/ui';
4
4
 
5
5
  type FormRadioOption = {
6
6
  value: string | number;
@@ -11,79 +11,97 @@ type SelectSwitchProps =
11
11
  | (SelectProps & { placeholder?: never })
12
12
  | (SelectProps & { defaultValue?: never });
13
13
 
14
- const checkDefaultValue = (
14
+ const checkDefaultValue = <
15
+ TFieldValues extends FieldValues = FieldValues,
16
+ TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
17
+ >(
15
18
  options: Array<FormRadioOption>,
16
- defaultValue?: string | number | readonly string[],
19
+ defaultValue?: FieldPathValue<TFieldValues, TName>,
17
20
  placeholder?: string
18
- ) => {
21
+ ): FieldPathValue<TFieldValues, TName> => {
22
+ if (defaultValue) {
23
+ return defaultValue;
24
+ }
25
+
19
26
  const hasEmptyValue = options.some((opt) => {
20
27
  return opt.value === '' || opt.value === 0;
21
28
  });
22
29
 
23
- if (placeholder && hasEmptyValue) return '';
30
+ const EMPTY_VALUE = '' as FieldPathValue<TFieldValues, TName>;
31
+
32
+ if (placeholder && hasEmptyValue) {
33
+ return EMPTY_VALUE;
34
+ }
35
+
24
36
  if (placeholder && !hasEmptyValue) {
25
37
  options.unshift({
26
38
  label: placeholder,
27
39
  value: '',
28
40
  });
29
- return '';
41
+ return EMPTY_VALUE;
30
42
  }
31
- if (!placeholder && defaultValue) return defaultValue;
32
- if (options.length === 0) return '';
33
- return options?.[0]?.value;
43
+
44
+ if (!placeholder && defaultValue) return EMPTY_VALUE;
45
+ if (options.length === 0) return EMPTY_VALUE;
46
+
47
+ return options?.[0]?.value as FieldPathValue<TFieldValues, TName>;
34
48
  };
35
49
 
50
+ type FormFieldSelectProps<
51
+ TFieldValues extends FieldValues,
52
+ TName extends FieldPath<TFieldValues>
53
+ > = SelectSwitchProps &
54
+ FormFieldProps & {
55
+ label?: string;
56
+ name: FieldPath<TFieldValues>;
57
+ options: FormRadioOption[];
58
+ defaultValue?: FieldPathValue<TFieldValues, TName>;
59
+ };
60
+
36
61
  export const FormFieldSelect = <
37
- TFieldValues extends FieldValues = FieldValues
62
+ TFieldValues extends FieldValues = FieldValues,
63
+ TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
38
64
  >({
39
65
  label,
40
66
  name,
41
67
  options,
42
68
  sx,
43
69
  ...selectProps
44
- }: {
45
- label?: string;
46
- name: FieldPath<TFieldValues>;
47
- options: FormRadioOption[];
48
- } & SelectSwitchProps) => {
70
+ }: FormFieldSelectProps<TFieldValues, TName>) => {
49
71
  const { defaultValue, placeholder } = selectProps;
50
72
 
51
- const checkedDefaultValue = checkDefaultValue(
73
+ const checkedDefaultValue = checkDefaultValue<TFieldValues, TName>(
52
74
  options,
53
75
  defaultValue,
54
76
  placeholder
55
77
  );
56
78
 
57
- const {
58
- field: { onChange, onBlur, value, ref },
59
- } = useController<any>({
60
- name,
61
- defaultValue: checkedDefaultValue,
62
- });
63
-
64
- const id = `form-field-select-${name}`;
65
-
66
79
  return (
67
- <Flex sx={{ flexDirection: 'column', width: '100%', ...sx }}>
68
- {label && <Label htmlFor={id}>{label}</Label>}
69
- <Select
70
- ref={ref}
71
- name={name}
72
- onChange={onChange}
73
- onBlur={onBlur}
74
- value={value}
75
- id={id}
76
- {...{ ...selectProps, defaultValue: undefined }}
77
- >
78
- {options.map((option) => {
79
- return (
80
- <option key={option.label} value={option.value}>
81
- {option.label}
82
- </option>
83
- );
84
- })}
85
- </Select>
86
- <ErrorMessage name={name} />
87
- </Flex>
80
+ <FormField
81
+ name={name}
82
+ label={label}
83
+ disabled={selectProps.disabled}
84
+ tooltip={selectProps.tooltip}
85
+ onTooltipClick={selectProps.onTooltipClick}
86
+ sx={sx}
87
+ defaultValue={checkedDefaultValue}
88
+ render={({ field }) => {
89
+ return (
90
+ <Select
91
+ {...selectProps}
92
+ {...field}
93
+ {...{ ...selectProps, defaultValue: undefined }}
94
+ >
95
+ {options.map((option) => {
96
+ return (
97
+ <option key={option.label} value={option.value}>
98
+ {option.label}
99
+ </option>
100
+ );
101
+ })}
102
+ </Select>
103
+ );
104
+ }}
105
+ />
88
106
  );
89
107
  };