This document lists recommended automated and manual verification scenarios for @nish1896/rhf-mui-components.
- Unit/component tests: render each component with
react-hook-form, interact with it, and assert RHF state, callbacks, accessibility attributes, and error rendering. - Type tests: verify key generic props, object option types, callback argument shapes, and ref types compile as expected.
- Demo smoke tests: run the demo app, visit each form page, interact with representative fields, submit, reset, and verify displayed form state.
- Docs smoke tests: build docs and verify examples compile after API changes.
Run these for every field component unless explicitly not applicable.
| Area | Test cases |
|---|---|
| Basic render | Renders with minimum required props: fieldName and control. |
| Default value | Displays the value from RHF defaultValues. |
| Value update | User interaction updates RHF state with the expected value shape. |
| Validation | registerOptions.required displays the expected validation message after submit/blur. |
| Error rendering | Error state sets visual error state and helper/error text correctly. |
| Helper text | helperText renders when no error is present. |
| Hide error | hideErrorMessage hides message while keeping field error state. |
| Label | Auto-generated label is shown from fieldName; custom label overrides it. |
| Label position | showLabelAboveFormField and config allLabelsAboveFields place labels correctly. |
| Hide label | hideLabel removes the visible label and keeps field usable. |
| Disabled | MUI disabled and RHF form-level disabled both prevent interaction. |
| Required UI | required marks the label/input as required where applicable. |
| IDs | customIds are applied to field, label, helper, and error elements where supported. |
| Callbacks | onValueChange fires after default RHF update with object-based args where applicable. |
| Custom change | customOnChange overrides default behavior and only updates RHF when rhfOnChange is called. |
| Ref | External ref is forwarded to the interactive input/control where applicable. |
| Reset | RHF reset() restores field value and UI. |
| Submit | Submitted values match expected serialized value shape. |
| Accessibility | Label association, aria-invalid, aria-required, and helper/error descriptions are correct. |
- Types text and updates form value.
- Supports inherited MUI
TextFieldprops directly. - Calls
onValueChange({ newValue, event }). - Calls
customOnChange({ rhfOnChange, event, newValue }). - Handles multiline props.
- Respects RHF disabled state.
- External ref points to input.
- Renders password input by default.
- Visibility toggle switches input type between
passwordandtext. - Toggle button is keyboard accessible.
- Validation works with min length and required rules.
- Disabled state disables input and toggle button.
- Custom
slotProps/adornments merge without breaking visibility toggle.
- Accepts integer input.
- Accepts decimal input when configured.
- Rejects invalid non-numeric characters.
- Handles empty value as expected.
- Enforces min/max validation through RHF rules.
- Step controls or keyboard changes update value correctly.
onValueChangereturns{ newValue, event }wherenewValueisnumber | null.customOnChangecan block or transform numeric value.
- Pressing Enter adds a tag.
- Pressing delimiter adds a tag.
- Trims whitespace before adding.
- Prevents duplicate tags case-insensitively if that is current behavior.
maxTagsprevents additional typed tags.- Pasting delimiter-separated text adds multiple tags.
- Pasted tags are trimmed and deduplicated.
- Pasted tags are truncated to remaining
maxTagsslots. - Backspace/Delete on empty input removes the last tag.
- Chip delete removes the selected tag.
onTagAdd({ newTag, currentValue })can block by returningfalse.onTagAddcan transform a tag by returning a string.onTagDelete({ deletedTag, currentValue })can block removal.onTagPaste({ pastedTags, currentValue })can block all pasted tags.onTagPastecan replace pasted tags by returningstring[].limitTagshides tags while unfocused.limitTags={-1}always shows all tags.getLimitTagsTextcustomizes hidden tag summary.renderTagLabelcustomizes chip label.ChipPropscustomizes tag chips.
- Single file selection stores a
File. - Multiple file selection stores a
File[]. - Selecting files in multiple batches preserves previous files.
- Removing a file updates RHF state and calls
onValueChange. - Clearing field resets file input value.
acceptrejects invalid file types.maxSizerejects oversized files.maxFilescounts existing and newly selected files.onUploadErrorreceives[{ file, errors }].- Drag-and-drop adds files when enabled.
disableDragAndDropdisables drop behavior.- Drop zone visual state changes during drag enter/leave.
dropZonePropsobject applies custom props/styles.dropZoneProps(state)receives{ isDragging, disabled, error }.renderUploadButtonreceives hidden file input and opens file picker when clicked.renderFileItemcustomizes new file rendering and removal.existingFilesrenders server-side files.renderExistingFileItemcustomizes existing file rendering.- Existing files satisfy required validation.
- Existing files participate in
maxFilesvalidation. - Disabled state prevents click, drop, and remove actions.
- Renders options from
string[]. - Renders options from object array with
labelKeyandvalueKey. - Throws or validates when object options are missing required keys in non-skipped env.
- Single select stores selected value.
- Multiple select stores selected values array.
showDefaultOptionrenders default option.defaultOptionTextcustomizes default option.renderOptionLabelcustomizes option display.customOnChangecan override selected value.- Disabled options cannot be selected.
- Placeholder renders when no value is selected.
- Renders native options from
string[]. - Renders object options with
labelKeyandvalueKey. - Single selection stores the selected option value.
- Default option behavior works.
- Native select remains usable on mobile viewport.
- Validation error displays correctly.
- Disabled state prevents selection.
- Initial checked value reflects RHF state.
- Click toggles boolean value.
onValueChangereceives checked state.customOnChangecan override toggle behavior.- Label click toggles checkbox.
- Disabled state prevents toggle.
- Required validation behavior for unchecked value is verified and documented.
- Custom checkbox props are applied.
- Renders string options.
- Renders object options with
labelKeyandvalueKey. - Selecting one checkbox adds value to array.
- Deselecting removes value from array.
- Multiple selections preserve existing values.
customOnChangereceives current value, toggled value, and checked state.onValueChangefires with updated array.- Checkbox props apply to each checkbox.
- Disabled group prevents all selection.
- Disabled option behavior works if supported.
- Required validation fails when no option is selected.
- Renders string options.
- Renders object options with
labelKeyandvalueKey. - Selecting an option stores single value.
- Selecting another option replaces previous value.
renderOptionLabelcustomizes display.onValueChangefires with selected value.customOnChangecan override selected value.- Disabled group prevents selection.
- Required validation fails when no option is selected.
- Initial checked state reflects RHF boolean value.
- Click toggles boolean value.
- Label click toggles switch.
onValueChangefires with checked value.customOnChangecan override behavior.- Disabled state prevents toggle.
- Required validation behavior for boolean values is documented and verified.
- Initial value reflects default value.
- Dragging thumb updates RHF value.
- Keyboard arrows update value.
- Min/max bounds are respected.
- Step value is respected.
- Range slider stores tuple/array value if supported by MUI props.
- Marks render when provided.
onValueChangefires when the slider value changes.- Disabled state prevents movement.
- Required/validation rules display errors.
- Initial rating reflects default value.
- Clicking a rating stores numeric value.
- Hover preview does not commit until selection.
- Clearing rating stores expected empty value.
- Precision prop supports half ratings.
- Disabled/readOnly states prevent updates.
onValueChangefires with selected rating.- Required validation works when empty.
- Renders string options.
- Renders object options with
labelKeyandvalueKey. - Single selection stores primitive value.
- Multiple selection stores primitive array.
- Free solo stores typed string.
- Free solo commit-on-blur works.
- Multiple free solo stores custom string values alongside option values.
- Duplicate labels should be covered by a regression test once
getOptionKeysupport is added. getOptionLabeldisplayslabelKey.isOptionEqualToValuematches byvalueKey.- Clear action stores empty/null value as documented.
disableClearableprevents clearing.renderOptionreceives correct option shape.renderValuehandles object and string values.- Loading state renders spinner.
- Async option appending does not duplicate selected value.
onValueChangereceives{ newValue, selectedOption, event, reason, details }.customOnChangecan override RHF update.
- Single selection stores full option object.
- Multiple selection stores full option object array.
- Requires object options with
labelKeyandvalueKey. - Free solo is not supported.
isOptionEqualToValuematches objects byvalueKey.renderValuereceives option object(s).- Clear action resets value.
- Duplicate labels should be covered by a regression test once
getOptionKeysupport is added. onValueChangereceives{ newValue, event, reason, details }.
- Renders string options.
- Renders object options with
labelKeyandvalueKey. - Multiple selected values are stored as string array.
- Select All appears when more than one option exists.
- Select All selects all real options.
- Clicking Select All again clears all options.
- Select All shows indeterminate state when partially selected.
- Select All is hidden when
hideSelectAllOptionis true. - Select All is hidden when
freeSolois true. - Free solo values are committed on blur.
renderOptionLabelcustomizes real option labels.- Select All label can be customized separately via
selectAllText. - Disabled options cannot be toggled.
getLimitTagsTextcustomizes hidden selection summary.onValueChangereceives updated value and selected option.
- Stores selected values as full object array.
- Select All selects all option objects.
- Select All clears when all are selected.
- Partial selection shows indeterminate state.
- Select All option is not included in RHF value.
renderOptionLabelonly handles real options.- Free solo is not supported.
- Object equality works by
valueKey. - Disabled options cannot be toggled.
renderValuereceives real option objects only.
- Renders all countries by default.
- Renders provided filtered
countries. preferredCountriesappear at the top.- Single select returns
country[valueKey]whenvalueKeyis provided. - Single select returns full country object when
valueKeyis omitted. - Multiple select returns an array of selected values/objects.
renderOptionLabelcustomizes option content.- Search/filter follows MUI Autocomplete label matching by country name.
getOptionKeydefaults to stable country key.- Required validation works.
Run shared picker scenarios for all picker variants:
RHFDatePickerRHFDesktopDatePickerRHFMobileDatePickerRHFStaticDatePickerRHFTimePickerRHFDesktopTimePickerRHFMobileTimePickerRHFStaticTimePickerRHFDateTimePickerRHFDesktopDateTimePickerRHFMobileDateTimePickerRHFStaticDateTimePicker
- Renders inside
ConfigProviderwithdateAdapter. - Initial value reflects RHF default value.
- Valid selection updates RHF state in
onChange. - Invalid intermediate value does not update RHF state.
onValueChange({ newValue, context })fires for valid changes.customOnChange({ rhfOnChange, newValue, context })can override update.onAcceptbehavior does not block normal selection.- Clear action stores expected empty value.
- Min/max date or time validation displays error.
- Disabled and readOnly states prevent updates.
- Slot props and text field props merge correctly.
- External ref points to input where applicable.
- Static picker variants update without popover behavior.
- Desktop/mobile variants render and update in their expected mode.
- Selects date only.
- Does not include time component unexpectedly.
- Respects
disablePastanddisableFuture.
- Selects time only.
- Respects 12/24-hour configuration.
- Respects min/max time.
- Selects date and time.
- Keeps both date and time when editing either part.
- Respects min/max datetime.
- Renders with default black color when field is empty.
- Parses initial hex value.
- Parses initial RGB value.
- Parses initial HSV-compatible value when using
valueKey="hsv". - Color picker interaction updates RHF string value.
onValueChangereceives color object withhex,rgb, andhsv.customOnChangecan override default update and usesetColor.defaultColorchanges empty initial color.- Disabled state prevents color changes.
- External package CSS is loaded without TypeScript errors.
- Accepts initial string value for backward compatibility.
- Accepts initial
RHFPhoneInputValueobject. - User input stores structured object:
{ phone, country, dialCode, phoneNo }. - Country selection updates
country,dialCode,phone, andphoneNo. - Shared dial code countries such as US/Canada preserve selected
country. - Inline country search filters by country name, ISO2, and dial code.
- Search field stays pinned while country list scrolls.
- Country menu width behaves correctly on desktop and mobile.
- Selecting a country focuses the phone input.
searchCountryProps.textFieldPropscustomize search field.searchCountryProps.renderCountryMenuItemcustomizes menu item content.searchCountryProps.noCountryFoundTextrenders when no match exists.onValueChangereceives{ newValue, phoneData }.customOnChangecan override RHF update.- Custom validation can check the structured object shape, especially
phoneNo. - External ref points to the phone input.
- Renders editor with default config.
- Initial HTML value appears in editor.
- Typing updates RHF HTML string.
- Toolbar actions update output HTML.
onValueChange({ newValue, event, editor })fires on content change.customOnChange({ rhfOnChange, newValue, event, editor })can override update.- Required validation fails for empty content.
- Disabled state prevents editing.
- Custom
editorConfigreplaces the default config. - External ref exposes editor/input root as intended.
- SSR/build does not crash due to editor imports.
- Root package exports all public components.
- Subpath imports work for every component, for example
@nish1896/rhf-mui-components/mui/textfield. - Type imports work for every public prop type.
- Built
dist/package.jsonhas export paths without./dist. pnpm libsucceeds.pnpm lib:lintsucceeds.pnpm demo:buildsucceeds.pnpm docs:buildsucceeds.
- Run
pnpm demo. - Visit each demo form route.
- Submit empty form and verify validation errors.
- Fill each field with representative valid values.
- Verify the
FormStatepanel shows expected values. - Reset the form and verify defaults are restored.
- Toggle disabled examples and verify fields no longer submit values if RHF form-level disabled is used.
- Check browser console for React key warnings, controlled/uncontrolled warnings, and accessibility warnings.
RHFFileUploaderpreserves previously selected files across multiple uploads.RHFFileUploadervalidation countsexistingFiles.RHFFileUploaderrequired validation passes whenexistingFiles.length > 0.RHFFileUploaderonUploadErrorreturns[{ file, errors }].RHFPhoneInputstores object values after interaction.RHFPhoneInputcountry search works and keeps selected country for shared dial codes.RHFTagsInputtag callbacks use object args andcurrentValue.RHFCountrySelectuses a stable default option key.- Picker components update RHF state from
onChangefor valid values. - Components respect RHF
disabledfromController.
- Add
getOptionKeysupport to autocomplete wrappers before enabling duplicate-label key-warning tests for those wrappers.