@@ -2447,6 +2447,78 @@ describe("DatePicker", () => {
24472447
24482448 expect ( onChangeSpy . mock . calls . at ( - 1 ) [ 0 ] ) . toStrictEqual ( [ null , null ] ) ;
24492449 } ) ;
2450+ it ( "should keep input cleared after blur when using controlled component (issue #5814)" , ( ) => {
2451+ function ControlledDatePicker ( ) {
2452+ const [ selected , setSelected ] = useState < Date | null > (
2453+ newDate ( "2024-12-25" ) ,
2454+ ) ;
2455+
2456+ return (
2457+ < DatePicker
2458+ selected = { selected }
2459+ onChange = { ( date : Date | null ) => setSelected ( date ) }
2460+ dateFormat = "MM/dd/yyyy"
2461+ />
2462+ ) ;
2463+ }
2464+
2465+ const { container } = render ( < ControlledDatePicker /> ) ;
2466+ const input = safeQuerySelector < HTMLInputElement > ( container , "input" ) ;
2467+
2468+ // Initial value should be the formatted date
2469+ expect ( input . value ) . toBe ( "12/25/2024" ) ;
2470+
2471+ // Clear the input
2472+ fireEvent . change ( input , { target : { value : "" } } ) ;
2473+
2474+ // Blur the input
2475+ fireEvent . blur ( input ) ;
2476+
2477+ // After blur, the input should still be empty (not revert to the date)
2478+ expect ( input . value ) . toBe ( "" ) ;
2479+ } ) ;
2480+ it ( "should handle mask pattern clearing (issue #5814)" , ( ) => {
2481+ // Mask libraries often show "__/__/____" when cleared instead of empty string
2482+ const onChangeSpy = jest . fn ( ) ;
2483+
2484+ function MaskedDatePicker ( ) {
2485+ const [ selected , setSelected ] = useState < Date | null > (
2486+ newDate ( "2024-12-25" ) ,
2487+ ) ;
2488+
2489+ const handleChange = ( date : Date | null ) => {
2490+ onChangeSpy ( date ) ;
2491+ setSelected ( date ) ;
2492+ } ;
2493+
2494+ return (
2495+ < DatePicker
2496+ selected = { selected }
2497+ onChange = { handleChange }
2498+ dateFormat = "MM/dd/yyyy"
2499+ />
2500+ ) ;
2501+ }
2502+
2503+ const { container } = render ( < MaskedDatePicker /> ) ;
2504+ const input = safeQuerySelector < HTMLInputElement > ( container , "input" ) ;
2505+
2506+ // Initial value should be the formatted date
2507+ expect ( input . value ) . toBe ( "12/25/2024" ) ;
2508+
2509+ // Simulate mask library clearing - value becomes mask pattern, not empty
2510+ fireEvent . change ( input , { target : { value : "__/__/____" } } ) ;
2511+
2512+ // onChange should NOT be called with null because mask pattern isn't a valid date
2513+ // But it also shouldn't be called with the old date
2514+ // The key issue: what happens on blur?
2515+
2516+ fireEvent . blur ( input ) ;
2517+
2518+ // The input should show the mask pattern, not revert to the old date
2519+ // This is where the bug manifests - in React 18, it might revert
2520+ expect ( input . value ) . not . toBe ( "12/25/2024" ) ;
2521+ } ) ;
24502522 it ( "should update preSelection when input changes for selectsRange" , ( ) => {
24512523 let instance : DatePicker | null = null ;
24522524 const onChangeSpy = jest . fn ( ) ;
0 commit comments