@nish1896/rhf-mui-components
Version:
A suite of 20+ production-ready react-hook-form components built with material-ui. Fully typed, tree-shakable, and optimized for enterprise-grade forms.
107 lines (106 loc) • 4.17 kB
JavaScript
"use client";
import { RHFMuiConfigContext } from "../../config/ConfigProvider.js";
import { validateArray } from "../../utils/array.js";
import { coerceValue, getOptionValue, isKeyValueOption } from "../../utils/object.js";
import { fieldNameToLabel } from "../../utils/text-transform.js";
import { useFieldIds } from "../../utils/useFieldIds.js";
import FormControl from "../../common/FormControl.js";
import FormHelperText from "../../common/FormHelperText.js";
import FormLabel from "../../common/FormLabel.js";
import { Fragment, useContext } from "react";
import { jsx, jsxs } from "react/jsx-runtime";
import { Controller } from "react-hook-form";
import FormControlLabel from "@mui/material/FormControlLabel";
import MuiCheckbox from "@mui/material/Checkbox";
//#region src/mui/checkbox-group/index.tsx
const RHFCheckboxGroup = ({ fieldName, control, registerOptions, options, labelKey, valueKey, onValueChange, disabled: muiDisabled, label, showLabelAboveFormField, formLabelProps, checkboxProps, formControlLabelProps, required, helperText, errorMessage, hideErrorMessage, formHelperTextProps, onBlur }) => {
validateArray("RHFCheckboxGroup", options, labelKey, valueKey);
const { fieldId, labelId, helperTextId, errorId } = useFieldIds(fieldName);
const { defaultFormControlLabelSx } = useContext(RHFMuiConfigContext);
const fieldLabel = label ?? fieldNameToLabel(fieldName);
const { sx, ...otherFormControlLabelProps } = formControlLabelProps ?? {};
const appliedFormControlLabelSx = {
...defaultFormControlLabelSx,
...sx
};
const isError = !!errorMessage;
const showHelperTextElement = !!helperText || isError && !hideErrorMessage;
return /* @__PURE__ */ jsx(Controller, {
name: fieldName,
control,
rules: registerOptions,
render: ({ field }) => {
const { value, onChange: rhfOnChange, onBlur: rhfOnBlur } = field;
const rhfValue = value ?? [];
const handleChange = (event, checked, optionValue) => {
const normalized = coerceValue(event.target.value, optionValue);
const newValue = checked ? rhfValue.includes(normalized) ? rhfValue : [...rhfValue, normalized] : rhfValue.filter((v) => v !== normalized);
rhfOnChange(newValue);
onValueChange?.(normalized, newValue, event);
};
return /* @__PURE__ */ jsx(FormControl, {
component: "fieldset",
error: isError,
onBlur: (e) => {
const currentTarget = e.currentTarget;
const relatedTarget = e.relatedTarget;
/**
* Trigger blur event only if focus is moving OUTSIDE
* the checkbox group, instead of calling onBlur for
* every checkbox.
*/
if (!currentTarget.contains(relatedTarget)) {
rhfOnBlur();
onBlur?.(e);
}
},
children: /* @__PURE__ */ jsxs(Fragment, { children: [
/* @__PURE__ */ jsx(FormLabel, {
label: fieldLabel,
isVisible: showLabelAboveFormField ?? true,
required,
error: isError,
formLabelProps: {
id: labelId,
component: "legend",
...formLabelProps
}
}),
options.map((option, idx) => {
const isObject = isKeyValueOption(option, labelKey, valueKey);
const opnValue = getOptionValue(option, valueKey);
const opnLabel = isObject ? String(option[labelKey]) : String(option);
const checked = rhfValue.includes(opnValue);
return /* @__PURE__ */ jsx(FormControlLabel, {
control: /* @__PURE__ */ jsx(MuiCheckbox, {
...checkboxProps,
id: `${fieldId}-${opnValue}`,
name: `${fieldName}-${idx}`,
value: opnValue,
checked,
onChange: (e) => handleChange(e, e.target.checked, opnValue)
}),
label: opnLabel,
sx: appliedFormControlLabelSx,
disabled: muiDisabled,
...otherFormControlLabelProps
}, `${opnValue}-${idx}`);
}),
/* @__PURE__ */ jsx(FormHelperText, {
error: isError,
errorMessage,
hideErrorMessage,
helperText,
showHelperTextElement,
formHelperTextProps: {
id: isError ? errorId : helperTextId,
...formHelperTextProps
}
})
] })
});
}
});
};
//#endregion
export { RHFCheckboxGroup as default };