Replace native date input with USWDS DatePicker in budget team requisition#5676
Replace native date input with USWDS DatePicker in budget team requisition#5676josbell wants to merge 12 commits into
Conversation
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…ion field layout Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
… alignment Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…izing Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR updates the pre-award budget team requisition review UI to use the USWDS DatePicker (instead of a native HTML date input) and adjusts date formatting for API submission, alongside a small global input styling change.
Changes:
- Replace the requisition date field UI with the USWDS DatePicker and update field layout/alignment on
ReviewBudgetTeamRequisition. - Format requisition dates for API submission via
formatDateForApi, and harden that helper against malformed/partial inputs. - Update unit tests and remove the
width-mobile-lgclass from the sharedInputcomponent.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| frontend/src/pages/agreements/pre-award-approval/ReviewBudgetTeamRequisition.jsx | Swaps requisition date to USWDS DatePicker and adjusts form layout/markup. |
| frontend/src/pages/agreements/pre-award-approval/ReviewBudgetTeamRequisition.hooks.js | Formats requisition date for API submission and wires DatePicker into the page via the hook. |
| frontend/src/pages/agreements/pre-award-approval/ReviewBudgetTeamRequisition.test.jsx | Updates tests to accommodate the DatePicker-based date field. |
| frontend/src/helpers/utils.js | Strengthens formatDateForApi parsing/formatting logic. |
| frontend/src/components/UI/Form/Input/Input.jsx | Removes fixed mobile width class from the shared input styling. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| type="date" | ||
| name="requisitionDate" | ||
| label="Requisition Date" | ||
| hint="mm/dd/yyyy" |
There was a problem hiding this comment.
✅ Fixed in commit ece7c4c
We've addressed this by:
-
Updated DatePicker component to pass
requiredandaria-requiredattributes to the input element:required={isRequired || isRequiredNoShow} aria-required={isRequired || isRequiredNoShow}
-
Added
isRequiredNoShow={true}to the MemoizedDatePicker usage (instead ofisRequired) to get the accessibility attributes without showing the "Required Information" visual label, maintaining the clean UI design.
This now properly communicates required field status to both screen readers and browser validation, fixing the WCAG 2.1 AA violation.
| data: { | ||
| requisition_number: requisitionNumber, | ||
| requisition_date: requisitionDate | ||
| requisition_date: formatDateForApi(requisitionDate) | ||
| // requisition_approved_by is server-controlled and set automatically |
There was a problem hiding this comment.
✅ Fixed in commit ece7c4c - Critical Issue
You correctly identified a data integrity vulnerability. We've fixed this by updating isFormValid():
// BEFORE (vulnerable)
return requisitionNumber.trim() !== "" && requisitionDate !== "" && attestationChecked;
// AFTER (fixed)
const formattedDate = formatDateForApi(requisitionDate);
return requisitionNumber.trim() !== "" && formattedDate !== null && attestationChecked;This now properly validates the date format. Invalid dates like "1", "01/01", or "abc" that previously passed validation (because they were non-empty strings) are now correctly rejected, preventing null values from reaching the API.
We also added comprehensive unit tests for formatDateForApi (7 test cases) to prevent regressions.
| import DatePicker from "../../../components/UI/USWDS/DatePicker"; | ||
| import { formatDateForApi } from "../../../helpers/utils"; | ||
| import React from "react"; | ||
|
|
There was a problem hiding this comment.
✅ Fixed in commit ece7c4c
Consolidated the duplicate React imports into a single statement:
import React, { useState, useMemo } from "react";Removed the duplicate import React from "react"; on line 9.
| const parts = date.split("/"); | ||
| if (parts.length !== 3) return null; | ||
|
|
||
| const [month, day, year] = parts; | ||
| if (!month || !day || !year) return null; | ||
|
|
||
| return `${year}-${month.padStart(2, "0")}-${day.padStart(2, "0")}`; |
There was a problem hiding this comment.
✅ Fixed in commit ece7c4c
Added comprehensive unit tests for formatDateForApi with 7 test cases covering:
- ✅ Valid MM/DD/YYYY format → YYYY-MM-DD conversion
- ✅ Single-digit month/day padding with leading zeros
- ✅ Null and undefined input handling (returns null)
- ✅ Empty string handling (returns null)
- ✅ Invalid formats: non-slash delimited (returns null)
- ✅ Wrong number of parts: too few or too many (returns null)
- ✅ Missing month, day, or year parts (returns null)
All tests pass (3,150 tests total), providing regression protection for this critical utility function.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
What changed
Replaced native HTML5 date input with USWDS MemoizedDatePicker component in ReviewBudgetTeamRequisition page. Enhanced date validation and fixed semantic HTML violations to improve accessibility and maintain USWDS compliance.
Key changes:
<input type="date">with MemoizedDatePicker following patterns from Procurement Tracker Step FourIssue
#1639
How to test
docker compose up --buildA11y impact
requiredandaria-required="true"attributesScreenshots
Not applicable - primarily functional changes to form inputs
Definition of Done Checklist
Links
/frontend/src/components/UI/USWDS/DatePicker.jsx/frontend/src/pages/agreements/pre-award-approval/ReviewBudgetTeamRequisition.test.jsx