Skip to content

fix: treat NaN as empty in form schema so required validation fires for cleared number inputs#1681

Merged
serikjensen merged 2 commits intomainfrom
fix/required-validation-empty-number-inputs
May 6, 2026
Merged

fix: treat NaN as empty in form schema so required validation fires for cleared number inputs#1681
serikjensen merged 2 commits intomainfrom
fix/required-validation-empty-number-inputs

Conversation

@serikjensen
Copy link
Copy Markdown
Member

@serikjensen serikjensen commented May 5, 2026

Summary

react-aria's NumberField emits NaN when its input is cleared. In buildFormSchema, the makeOptional preprocess only normalized '' and null to undefined, so NaN slipped through to inner field preprocessors like coerceNaN(0) and was silently coerced to 0 — bypassing the superRefine required check (isEmpty(0) is false). Result: required currency fields looked required (no (optional) label) but the form happily submitted with no value.

This was most visible in useFederalTaxesForm, where every non-filingStatus field is a number with 0 as a legitimate value, so the domain-level workaround payScheduleSchema uses (a 1–31 range check) wasn't applicable. useCompensationForm was also affected — clearing the rate field reported RATE_MINIMUM instead of REQUIRED.

Changes

  • src/partner-hook-utils/form/buildFormSchema.ts: isEmpty now also recognizes NaN, and makeOptional reuses isEmpty so cleared numeric inputs normalize to undefined before any inner preprocessor runs. The required check then fires correctly.
  • src/partner-hook-utils/form/buildFormSchema.test.ts: framework-level regression coverage for the NaN-required and NaN-optional cases.
  • src/components/Employee/FederalTaxes/shared/useFederalTaxesForm/federalTaxesSchema.test.ts (new): domain coverage matching the original repro — extraWithholding: NaN with optionalFieldsToRequire.update set must produce REQUIRED, while 0 remains a valid value.
  • src/components/Employee/Compensation/shared/useCompensationForm/useCompensationForm.test.tsx: the test that previously asserted RATE_MINIMUM for NaN rate now asserts REQUIRED, matching the user-facing expectation when an input is empty.

Test plan

  • npm run test -- --run src/partner-hook-utils src/components/Company/PaySchedule src/components/Employee/FederalTaxes src/components/Employee/Compensation — 268 passing
  • npm run test -- --run (full suite) — 2470 passing
  • Manual: clear Step 4c: Extra withholding on the Federal Taxes page and submit — should now block submission with the configured REQUIRED validation message instead of silently coercing to 0
Screenshot 2026-05-05 at 4 50 21 PM

Made with Cursor

…or cleared number inputs

react-aria's NumberField emits NaN when its input is cleared. The
buildFormSchema makeOptional preprocess only normalized '' and null to
undefined, so NaN slipped through to inner field preprocessors like
coerceNaN(0) and was silently coerced to 0 — bypassing the superRefine
required check (isEmpty(0) is false). Result: required currency fields
appeared visually required but never blocked submission when emptied.

This affected useFederalTaxesForm (no domain workaround was possible
because 0 is a valid W-4 amount) and matched the behavior the
payScheduleSchema worked around with a 1–31 range check.

Now isEmpty also recognizes NaN and makeOptional reuses it, so cleared
numeric inputs normalize to undefined and the required check fires
correctly. Adds framework-level coverage in buildFormSchema.test.ts and
domain coverage in federalTaxesSchema.test.ts. The compensation test
that previously asserted RATE_MINIMUM for NaN rate is updated to assert
REQUIRED, which matches the user-facing expectation when an input is
empty.

Co-authored-by: Cursor <cursoragent@cursor.com>
@serikjensen serikjensen enabled auto-merge (squash) May 6, 2026 14:42
@serikjensen serikjensen merged commit 1a60aa6 into main May 6, 2026
19 checks passed
@serikjensen serikjensen deleted the fix/required-validation-empty-number-inputs branch May 6, 2026 14:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants