@nwon/react-mui-hook-form 1.3.0 → 1.3.2

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.
Files changed (27) hide show
  1. package/dist/formFields/HookFormProvider.d.ts +1 -2
  2. package/dist/formFields/InputEmail/InputEmail.d.ts +2 -3
  3. package/dist/formFields/baseTypes/BaseInputProps.d.ts +33 -0
  4. package/dist/formFields/baseTypes/InputAutocomplete/InputAutocomplete.d.ts +2 -1
  5. package/dist/formFields/baseTypes/InputAutocomplete/InputAutocompleteInterfaces.d.ts +1 -2
  6. package/dist/formFields/baseTypes/InputCheckbox/InputCheckbox.d.ts +2 -3
  7. package/dist/formFields/baseTypes/InputDatePicker/InputDatePicker.d.ts +2 -3
  8. package/dist/formFields/baseTypes/InputDateTimePicker/InputDateTimePicker.d.ts +2 -3
  9. package/dist/formFields/baseTypes/InputNumber/InputNumber.d.ts +2 -3
  10. package/dist/formFields/baseTypes/InputOutlinedInput/InputOutlinedInput.d.ts +2 -3
  11. package/dist/formFields/baseTypes/InputRadio/InputRadio.d.ts +3 -3
  12. package/dist/formFields/baseTypes/InputSelect/InputSelect.d.ts +3 -3
  13. package/dist/formFields/baseTypes/InputSelectFromEnum/InputSelectFromEnum.d.ts +2 -1
  14. package/dist/formFields/baseTypes/InputSlider/InputSlider.d.ts +2 -3
  15. package/dist/formFields/baseTypes/InputSwitch/InputSwitch.d.ts +2 -3
  16. package/dist/formFields/baseTypes/InputTextField/InputTextField.d.ts +3 -4
  17. package/dist/formFields/baseTypes/InputTimePicker/InputTimePicker.d.ts +2 -3
  18. package/dist/formFields/baseTypes/InputToggleButton/InputToggleButton.d.ts +2 -3
  19. package/dist/formFields/baseTypes/InputToggleButtonGroup/InputToggleButtonGroup.d.ts +2 -3
  20. package/dist/formFields/baseTypes/useEffectFieldUnregisterOnUnmount.d.ts +12 -0
  21. package/dist/formFields/formHelper/useHookForm.d.ts +7 -2
  22. package/dist/formFields/index.d.ts +1 -0
  23. package/dist/formFields/inputTypes.d.ts +1 -1
  24. package/dist/packageExports.d.ts +1 -1
  25. package/dist/packageExports.js +229 -66
  26. package/dist/packageExports.js.map +1 -1
  27. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  import { CheckBoxOutlineBlank, CheckBox } from '@mui/icons-material';
2
2
  import { FormHelperText, useFormControl, Checkbox, FormControl, Autocomplete, TextField, FormControlLabel, Box, InputLabel, OutlinedInput, FormLabel, RadioGroup, Radio, Select, MenuItem, Stack, Tooltip, ListSubheader, Slider, Switch, ToggleButton, ToggleButtonGroup, Typography } from '@mui/material';
3
3
  import { filterNoUndefinedNoNull, uppercaseFirstLetter, assertTruthy, objectHasKey, rethrow } from '@nvon/baseline';
4
- import { useCallback, useMemo, useState } from 'react';
4
+ import { useCallback, useMemo, useState, useEffect } from 'react';
5
5
  import { useFormContext, useWatch, Controller, useForm, FormProvider } from 'react-hook-form';
6
6
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
7
  import { identity } from 'lodash-es';
@@ -173,6 +173,38 @@ formFieldDefaults) => {
173
173
  return withPlainStrings;
174
174
  };
175
175
 
176
+ /**
177
+ * An effect that unregisters a field from the form when the component unmounts.
178
+ *
179
+ * @throws Error when FormContext is null.
180
+ */
181
+ const useEffectFieldUnregisterOnUnmount = ({
182
+ name,
183
+ unregisterOptions,
184
+ isUnregisteringOnUnmount
185
+ }) => {
186
+ const form = useHookFormContext();
187
+ /**
188
+ * Default options for unregistering the field.
189
+ *
190
+ * Needed to wrap this in a state in order to prevent infinite rerenders.
191
+ */
192
+ const [options] = useState(unregisterOptions);
193
+ if (!form) {
194
+ throw Error(formContextNull);
195
+ }
196
+ const {
197
+ unregister
198
+ } = form;
199
+ useEffect(() => {
200
+ return () => {
201
+ if (isUnregisteringOnUnmount) {
202
+ unregister(name, options);
203
+ }
204
+ };
205
+ }, [isUnregisteringOnUnmount, name, unregister, options]);
206
+ };
207
+
176
208
  var GroupLabelSorting;
177
209
  (function (GroupLabelSorting) {
178
210
  GroupLabelSorting["Alphabetical"] = "alphabetical";
@@ -234,6 +266,7 @@ const icon = /*#__PURE__*/jsx(CheckBoxOutlineBlank, {
234
266
  const checkedIcon = /*#__PURE__*/jsx(CheckBox, {
235
267
  fontSize: "small"
236
268
  });
269
+ const defaultNonMultiselectValue = "";
237
270
  /**
238
271
  * Renders a MUI autocomplete input that is embedded in a react hook form context.
239
272
  *
@@ -246,7 +279,9 @@ const InputAutocomplete = ({
246
279
  autoCompleteProps,
247
280
  checkboxesForMultiselect: renderCheckboxes,
248
281
  groupSorting,
249
- inputTextFieldProps
282
+ inputTextFieldProps,
283
+ unregisterOptions,
284
+ isUnregisteringOnUnmount
250
285
  }) => {
251
286
  const form = useHookFormContext();
252
287
  if (!form) {
@@ -266,16 +301,42 @@ const InputAutocomplete = ({
266
301
  requiredErrorMessage,
267
302
  validate
268
303
  } = useMergedFormField(formField, formField.t);
269
- const sortedOptions = useSortedOptionsWithGroup$1(selectableOptions, groupSorting);
270
- const value = useWatch({
304
+ useEffectFieldUnregisterOnUnmount({
271
305
  name,
272
- control
306
+ unregisterOptions,
307
+ isUnregisteringOnUnmount
273
308
  });
274
309
  const multiSelect = !!autoCompleteProps?.multiple;
275
- let valueToUse = value;
276
- if (!value) {
277
- valueToUse = multiSelect ? [] : "";
278
- }
310
+ const value = useWatch({
311
+ name,
312
+ control,
313
+ exact: true
314
+ });
315
+ const {
316
+ value: valueToUse,
317
+ hasValue
318
+ } = useMemo(() => {
319
+ if (value) {
320
+ return {
321
+ value,
322
+ hasValue: true
323
+ };
324
+ }
325
+ return {
326
+ value: multiSelect ? [] : defaultNonMultiselectValue,
327
+ hasValue: false
328
+ };
329
+ }, [multiSelect, value]);
330
+ const adjustedSelectableOptions = useMemo(() => {
331
+ if (hasValue || multiSelect) {
332
+ return selectableOptions;
333
+ }
334
+ return [...selectableOptions, {
335
+ value: defaultNonMultiselectValue,
336
+ label: ""
337
+ }];
338
+ }, [hasValue, multiSelect, selectableOptions]);
339
+ const sortedOptions = useSortedOptionsWithGroup$1(adjustedSelectableOptions, groupSorting);
279
340
  assertTruthy(["string", "number", "object"].includes(typeof valueToUse), `Value (Field: ${name}, value: ${valueToUse?.toString() || "undefined"}) for select input has unexpected type`);
280
341
  const isRequired = required || muiFormControl?.required;
281
342
  const isDisabled = muiFormControl?.disabled || autoCompleteProps?.disabled;
@@ -285,28 +346,30 @@ const InputAutocomplete = ({
285
346
  disabled: isDisabled
286
347
  });
287
348
  const currentValue = useMemo(() => {
288
- return multiSelect ? selectableOptions.filter(o => {
349
+ return multiSelect ? adjustedSelectableOptions.filter(o => {
289
350
  if (Array.isArray(valueToUse)) {
290
351
  return valueToUse.includes(o.value);
291
352
  }
292
- return selectableOptions.find(option => option.value === valueToUse);
293
- }) : selectableOptions.find(option => option.value === valueToUse);
294
- }, [multiSelect, selectableOptions, valueToUse]);
353
+ return adjustedSelectableOptions.find(option => option.value === valueToUse);
354
+ }) : adjustedSelectableOptions.find(option => option.value === valueToUse);
355
+ }, [multiSelect, adjustedSelectableOptions, valueToUse]);
295
356
  const renderOption = useMemo(() => {
296
357
  if (autoCompleteProps?.renderOption) {
297
358
  return autoCompleteProps.renderOption;
298
359
  }
299
- return multiSelect && renderCheckboxes ? (liProps, option) => /*#__PURE__*/jsxs("li", {
300
- ...liProps,
301
- children: [/*#__PURE__*/jsx(Checkbox, {
302
- icon: icon,
303
- checkedIcon: checkedIcon,
304
- sx: {
305
- mr: 2
306
- },
307
- checked: Array.isArray(currentValue) ? !!currentValue.find(item => item.value === option.value) : false
308
- }), option.label]
309
- }) : undefined;
360
+ return multiSelect && renderCheckboxes ? (liProps, option) => {
361
+ return /*#__PURE__*/jsxs("li", {
362
+ ...liProps,
363
+ children: [/*#__PURE__*/jsx(Checkbox, {
364
+ icon: icon,
365
+ checkedIcon: checkedIcon,
366
+ sx: {
367
+ mr: 2
368
+ },
369
+ checked: Array.isArray(currentValue) ? !!currentValue.find(item => item.value === option.value) : false
370
+ }), option.label]
371
+ });
372
+ } : undefined;
310
373
  }, [autoCompleteProps?.renderOption, currentValue, multiSelect, renderCheckboxes]);
311
374
  return /*#__PURE__*/jsxs(FormControl, {
312
375
  error: hasError,
@@ -314,7 +377,7 @@ const InputAutocomplete = ({
314
377
  disabled: isDisabled,
315
378
  children: [/*#__PURE__*/jsx(Autocomplete, {
316
379
  options: sortedOptions,
317
- value: currentValue || "",
380
+ value: currentValue,
318
381
  ...props,
319
382
  required: isRequired,
320
383
  label: label,
@@ -342,15 +405,20 @@ const InputAutocomplete = ({
342
405
  }
343
406
  },
344
407
  noOptionsText: noOptions,
345
- renderInput: params => /*#__PURE__*/jsx(TextField, {
346
- ...params,
347
- label: label,
348
- variant: "outlined",
349
- ...inputTextFieldProps,
350
- required: isRequired,
351
- disabled: isDisabled,
352
- error: hasError
353
- }),
408
+ filterOptions: options => {
409
+ return options.filter(o => o.value !== defaultNonMultiselectValue);
410
+ },
411
+ renderInput: params => {
412
+ return /*#__PURE__*/jsx(TextField, {
413
+ ...params,
414
+ label: label,
415
+ variant: "outlined",
416
+ ...inputTextFieldProps,
417
+ required: isRequired,
418
+ disabled: isDisabled,
419
+ error: hasError
420
+ });
421
+ },
354
422
  groupBy: option => option.group || "Choose"
355
423
  // need to parse this as any in order to get no typing errors
356
424
  // for multiselect
@@ -367,7 +435,9 @@ const InputCheckbox = ({
367
435
  formField,
368
436
  jsxLabel,
369
437
  checkboxProps,
370
- formControlLabelProps
438
+ formControlLabelProps,
439
+ unregisterOptions,
440
+ isUnregisteringOnUnmount
371
441
  }) => {
372
442
  const {
373
443
  control,
@@ -382,6 +452,11 @@ const InputCheckbox = ({
382
452
  requiredErrorMessage,
383
453
  validate
384
454
  } = useMergedFormField(formField);
455
+ useEffectFieldUnregisterOnUnmount({
456
+ name,
457
+ unregisterOptions,
458
+ isUnregisteringOnUnmount
459
+ });
385
460
  const id = `hook-form-input-checkbox-${name}`;
386
461
  const disabled = muiFormControl?.disabled || checkboxProps?.disabled;
387
462
  const isRequired = required || muiFormControl?.required;
@@ -433,7 +508,9 @@ const InputCheckbox = ({
433
508
 
434
509
  const InputDatePicker = ({
435
510
  formField,
436
- datePickerProps
511
+ datePickerProps,
512
+ unregisterOptions,
513
+ isUnregisteringOnUnmount
437
514
  }) => {
438
515
  const {
439
516
  control
@@ -446,6 +523,11 @@ const InputDatePicker = ({
446
523
  required,
447
524
  requiredErrorMessage
448
525
  } = useMergedFormField(formField);
526
+ useEffectFieldUnregisterOnUnmount({
527
+ name,
528
+ unregisterOptions,
529
+ isUnregisteringOnUnmount
530
+ });
449
531
  const [date, setDate] = useState(dayjs());
450
532
  const isRequired = required || muiFormControl?.required;
451
533
  const isDisabled = muiFormControl?.disabled || datePickerProps?.disabled;
@@ -494,7 +576,9 @@ const InputDatePicker = ({
494
576
 
495
577
  const InputDateTimePicker = ({
496
578
  formField,
497
- dateTimePickerProps
579
+ dateTimePickerProps,
580
+ unregisterOptions,
581
+ isUnregisteringOnUnmount
498
582
  }) => {
499
583
  const {
500
584
  control
@@ -507,6 +591,11 @@ const InputDateTimePicker = ({
507
591
  required,
508
592
  requiredErrorMessage
509
593
  } = useMergedFormField(formField);
594
+ useEffectFieldUnregisterOnUnmount({
595
+ name,
596
+ unregisterOptions,
597
+ isUnregisteringOnUnmount
598
+ });
510
599
  const [date, setDate] = useState(dayjs());
511
600
  const isRequired = required || muiFormControl?.required;
512
601
  const isDisabled = muiFormControl?.disabled || dateTimePickerProps?.disabled;
@@ -558,7 +647,9 @@ const InputDateTimePicker = ({
558
647
  const InputNumber = ({
559
648
  formField,
560
649
  textFieldProps,
561
- numericFormatProps
650
+ numericFormatProps,
651
+ unregisterOptions,
652
+ isUnregisteringOnUnmount
562
653
  }) => {
563
654
  const form = useHookFormContext();
564
655
  const {
@@ -572,6 +663,11 @@ const InputNumber = ({
572
663
  requiredErrorMessage,
573
664
  validate
574
665
  } = useMergedFormField(formField, formField.t);
666
+ useEffectFieldUnregisterOnUnmount({
667
+ name,
668
+ unregisterOptions,
669
+ isUnregisteringOnUnmount
670
+ });
575
671
  if (!form) {
576
672
  throw Error(formContextNull);
577
673
  }
@@ -622,7 +718,9 @@ const InputNumber = ({
622
718
 
623
719
  const InputOutlinedInput = ({
624
720
  formField,
625
- outlinedInputProps
721
+ outlinedInputProps,
722
+ unregisterOptions,
723
+ isUnregisteringOnUnmount
626
724
  }) => {
627
725
  const form = useHookFormContext();
628
726
  const muiFormControl = useFormControl();
@@ -633,6 +731,11 @@ const InputOutlinedInput = ({
633
731
  requiredErrorMessage,
634
732
  validate
635
733
  } = useMergedFormField(formField, formField.t);
734
+ useEffectFieldUnregisterOnUnmount({
735
+ name,
736
+ unregisterOptions,
737
+ isUnregisteringOnUnmount
738
+ });
636
739
  if (!form) {
637
740
  throw Error(formContextNull);
638
741
  }
@@ -684,7 +787,9 @@ const InputRadio = ({
684
787
  formField,
685
788
  selectableOptions,
686
789
  formControlLabelProps,
687
- radioGroupProps
790
+ radioGroupProps,
791
+ unregisterOptions,
792
+ isUnregisteringOnUnmount
688
793
  }) => {
689
794
  const {
690
795
  control
@@ -698,6 +803,11 @@ const InputRadio = ({
698
803
  requiredErrorMessage,
699
804
  validate
700
805
  } = useMergedFormField(formField);
806
+ useEffectFieldUnregisterOnUnmount({
807
+ name,
808
+ unregisterOptions,
809
+ isUnregisteringOnUnmount
810
+ });
701
811
  const id = `hook-form-input-radio-${name}`;
702
812
  const isRequired = required || muiFormControl?.required;
703
813
  const isDisabled = muiFormControl?.disabled || formControlLabelProps?.disabled;
@@ -740,7 +850,7 @@ const InputRadio = ({
740
850
  label: option.label,
741
851
  ...formControlLabelProps,
742
852
  disabled: isDisabled
743
- }, option.value);
853
+ }, typeof option.value === "boolean" ? option.value.toString() : option.value);
744
854
  })
745
855
  });
746
856
  }
@@ -773,7 +883,9 @@ const InputSelect = ({
773
883
  selectableOptions,
774
884
  optionsTitle,
775
885
  selectComponentProps,
776
- tooltipHolder
886
+ tooltipHolder,
887
+ unregisterOptions,
888
+ isUnregisteringOnUnmount
777
889
  }) => {
778
890
  const form = useHookFormContext();
779
891
  if (!form) {
@@ -790,19 +902,18 @@ const InputSelect = ({
790
902
  requiredErrorMessage,
791
903
  validate
792
904
  } = useMergedFormField(formField, formField.t);
793
- const defaultValue = selectComponentProps?.multiple ? [] : "";
794
- const valueFromForm = useWatch({
905
+ useEffectFieldUnregisterOnUnmount({
795
906
  name,
796
- control,
797
- defaultValue
907
+ unregisterOptions,
908
+ isUnregisteringOnUnmount
798
909
  });
799
- if (selectComponentProps?.multiple && valueFromForm) {
800
- assertTruthy(Array.isArray(valueFromForm), `Value (Field: ${name}, value: ${valueFromForm?.toString() || "undefined"}) for multiple select need to be an array or undefined`);
801
- } else if (valueFromForm) {
802
- assertTruthy(["string", "number"].includes(typeof valueFromForm), `Value (Field: ${name}, value: ${valueFromForm?.toString() || "undefined"}) for select input has unexpected type`);
803
- }
910
+ const defaultValue = useMemo(() => selectComponentProps?.multiple ? [] : "", [selectComponentProps?.multiple]);
804
911
  const id = `input-select-${name}`;
805
- const sortedOptions = useSortedOptionsWithGroup(selectableOptions);
912
+ const adjustedOptions = useMemo(() => selectComponentProps?.multiple || Array.isArray(defaultValue) ? selectableOptions : [...selectableOptions, {
913
+ value: defaultValue,
914
+ label: ""
915
+ }], [defaultValue, selectComponentProps?.multiple, selectableOptions]);
916
+ const sortedOptions = useSortedOptionsWithGroup(adjustedOptions);
806
917
  const hasErrors = useFormFieldHasError(formField.name);
807
918
  const isRequired = required || muiFormControl?.required;
808
919
  const isDisabled = muiFormControl?.disabled || selectComponentProps?.disabled;
@@ -850,16 +961,16 @@ const InputSelect = ({
850
961
  children: /*#__PURE__*/jsx("em", {
851
962
  children: optionsTitle
852
963
  })
853
- }), sortedOptions?.map((option, index) => {
964
+ }), sortedOptions?.filter(o => o.value !== "").map((option, index) => {
854
965
  const optionBefore = sortedOptions[index - 1];
855
966
  const showGroup = (optionBefore || index == 0) && option.group && optionBefore?.group !== option.group;
856
967
  const disabledText = typeof option.disabled === "string" ? option.disabled : undefined;
857
968
  const isDisabledToUse = !!disabledText || !!option.disabled || isDisabled;
858
969
  const menuItem = /*#__PURE__*/jsx(MenuItem, {
859
- value: option.value,
970
+ value: typeof option.value === "boolean" ? option.value.toString() : option.value,
860
971
  disabled: isDisabledToUse,
861
972
  title: typeof option.disabled === "string" ? option.disabled : undefined,
862
- selected: value === option.value,
973
+ selected: typeof option.value === "boolean" ? option.value.toString() === value : value === option.value,
863
974
  children: option.label
864
975
  }, option.label);
865
976
  const wrappedMenuItem = disabledText ? /*#__PURE__*/jsxs(Box, {
@@ -901,8 +1012,8 @@ const InputSelectFromEnum = props => {
901
1012
  } = props;
902
1013
  const translateFunction = formField.t;
903
1014
  const options = useMemo(() => {
904
- return Object.entries(enumData.enumToUse).map(([, value]) => {
905
- const label = enumData.labelsForEnum[value];
1015
+ return Object.entries(enumData.enumToUse).map(([key, value]) => {
1016
+ const label = enumData.labelsForEnum[key];
906
1017
  assertTruthy(label, "Could not find a label for value: " + value + " in Field " + formField.name);
907
1018
  if (typeof label === "string") {
908
1019
  return {
@@ -926,7 +1037,9 @@ const InputSelectFromEnum = props => {
926
1037
 
927
1038
  const InputSlider = ({
928
1039
  formField,
929
- sliderProps
1040
+ sliderProps,
1041
+ unregisterOptions,
1042
+ isUnregisteringOnUnmount
930
1043
  }) => {
931
1044
  const form = useHookFormContext();
932
1045
  const muiFormControl = useFormControl();
@@ -937,6 +1050,11 @@ const InputSlider = ({
937
1050
  requiredErrorMessage,
938
1051
  validate
939
1052
  } = useMergedFormField(formField, formField.t);
1053
+ useEffectFieldUnregisterOnUnmount({
1054
+ name,
1055
+ unregisterOptions,
1056
+ isUnregisteringOnUnmount
1057
+ });
940
1058
  if (!form) {
941
1059
  throw Error(formContextNull);
942
1060
  }
@@ -987,7 +1105,9 @@ const InputSlider = ({
987
1105
  const InputSwitch = ({
988
1106
  formField,
989
1107
  switchProps,
990
- formControlLabelProps
1108
+ formControlLabelProps,
1109
+ unregisterOptions,
1110
+ isUnregisteringOnUnmount
991
1111
  }) => {
992
1112
  const {
993
1113
  control,
@@ -1001,6 +1121,11 @@ const InputSwitch = ({
1001
1121
  requiredErrorMessage,
1002
1122
  validate
1003
1123
  } = useMergedFormField(formField);
1124
+ useEffectFieldUnregisterOnUnmount({
1125
+ name,
1126
+ unregisterOptions,
1127
+ isUnregisteringOnUnmount
1128
+ });
1004
1129
  const isRequired = required || muiFormControl?.required;
1005
1130
  const isDisabled = muiFormControl?.disabled || switchProps?.disabled;
1006
1131
  return /*#__PURE__*/jsxs(FormControl, {
@@ -1048,7 +1173,9 @@ const InputSwitch = ({
1048
1173
 
1049
1174
  const InputTextField = ({
1050
1175
  formField,
1051
- textFieldProps
1176
+ textFieldProps,
1177
+ unregisterOptions,
1178
+ isUnregisteringOnUnmount
1052
1179
  }) => {
1053
1180
  const form = useHookFormContext();
1054
1181
  const {
@@ -1062,6 +1189,11 @@ const InputTextField = ({
1062
1189
  requiredErrorMessage,
1063
1190
  validate
1064
1191
  } = useMergedFormField(formField, formField.t);
1192
+ useEffectFieldUnregisterOnUnmount({
1193
+ name,
1194
+ unregisterOptions,
1195
+ isUnregisteringOnUnmount
1196
+ });
1065
1197
  if (!form) {
1066
1198
  throw Error(formContextNull);
1067
1199
  }
@@ -1107,7 +1239,9 @@ const InputTextField = ({
1107
1239
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
1108
1240
  const InputTimePicker = ({
1109
1241
  formField,
1110
- timePickerProps
1242
+ timePickerProps,
1243
+ unregisterOptions,
1244
+ isUnregisteringOnUnmount
1111
1245
  }) => {
1112
1246
  const {
1113
1247
  control
@@ -1120,6 +1254,11 @@ const InputTimePicker = ({
1120
1254
  required,
1121
1255
  requiredErrorMessage
1122
1256
  } = useMergedFormField(formField);
1257
+ useEffectFieldUnregisterOnUnmount({
1258
+ name,
1259
+ unregisterOptions,
1260
+ isUnregisteringOnUnmount
1261
+ });
1123
1262
  const [date, setDate] = useState(dayjs());
1124
1263
  const isRequired = required || muiFormControl?.required;
1125
1264
  const isDisabled = muiFormControl?.disabled || timePickerProps?.disabled;
@@ -1171,7 +1310,9 @@ const InputToggleButton = ({
1171
1310
  formField,
1172
1311
  toggleButtonProps,
1173
1312
  formControlLabelProps,
1174
- children
1313
+ children,
1314
+ unregisterOptions,
1315
+ isUnregisteringOnUnmount
1175
1316
  }) => {
1176
1317
  const {
1177
1318
  register,
@@ -1186,10 +1327,16 @@ const InputToggleButton = ({
1186
1327
  requiredErrorMessage,
1187
1328
  validate
1188
1329
  } = useMergedFormField(formField);
1330
+ useEffectFieldUnregisterOnUnmount({
1331
+ name,
1332
+ unregisterOptions,
1333
+ isUnregisteringOnUnmount
1334
+ });
1189
1335
  const id = `hook-form-input-toggle-button-${name}`;
1190
1336
  const valueToUse = !!useWatch({
1191
1337
  name: name,
1192
- control: control
1338
+ control: control,
1339
+ exact: true
1193
1340
  });
1194
1341
  assertTruthy(typeof valueToUse === "boolean", `Value (Field: ${name}, value: ${valueToUse?.toString() || "undefined"}) for a InputToggleButton should be undefined or boolean`);
1195
1342
  const onClick = useCallback(
@@ -1245,7 +1392,9 @@ const InputToggleButtonGroup = ({
1245
1392
  stackProps,
1246
1393
  typographyProps,
1247
1394
  buttons,
1248
- enforceValueSelected = false
1395
+ enforceValueSelected = false,
1396
+ unregisterOptions,
1397
+ isUnregisteringOnUnmount
1249
1398
  }) => {
1250
1399
  const {
1251
1400
  register,
@@ -1260,6 +1409,11 @@ const InputToggleButtonGroup = ({
1260
1409
  requiredErrorMessage,
1261
1410
  validate
1262
1411
  } = useMergedFormField(formField);
1412
+ useEffectFieldUnregisterOnUnmount({
1413
+ name,
1414
+ unregisterOptions,
1415
+ isUnregisteringOnUnmount
1416
+ });
1263
1417
  const changeEv = useCallback((_, value) => {
1264
1418
  const onSetValue = () => setValue(name, value, {
1265
1419
  shouldValidate: true,
@@ -1285,7 +1439,8 @@ const InputToggleButtonGroup = ({
1285
1439
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
1286
1440
  const valueFromForm = useWatch({
1287
1441
  name: name,
1288
- control: control
1442
+ control: control,
1443
+ exact: true
1289
1444
  });
1290
1445
  const isRequired = required || muiFormControl?.required;
1291
1446
  const isDisabled = muiFormControl?.disabled || toggleButtonGroupProps?.disabled;
@@ -1386,13 +1541,21 @@ const HookFormProvider = FormProvider;
1386
1541
 
1387
1542
  const InputEmail = props => {
1388
1543
  const merged = useMergedFormField(props.formField, props.formField.t, formDefaults);
1389
- return /*#__PURE__*/jsx(InputTextField, {
1544
+ const commonProps = useMemo(() => ({
1390
1545
  textFieldProps: {
1391
1546
  type: "email",
1392
1547
  autoComplete: "email",
1393
1548
  ...props.textFieldProps
1394
1549
  },
1395
1550
  formField: merged
1551
+ }), [merged, props.textFieldProps]);
1552
+ return props.isUnregisteringOnUnmount ? /*#__PURE__*/jsx(InputTextField, {
1553
+ ...commonProps,
1554
+ isUnregisteringOnUnmount: props.isUnregisteringOnUnmount,
1555
+ unregisterOptions: props.unregisterOptions
1556
+ }) : /*#__PURE__*/jsx(InputTextField, {
1557
+ ...commonProps,
1558
+ isUnregisteringOnUnmount: props.isUnregisteringOnUnmount
1396
1559
  });
1397
1560
  };
1398
1561
  const formDefaults = {