@@ -235,6 +235,7 @@ export default function DateInput({
235235 const dayInput = useRef < HTMLInputElement > ( null ) ;
236236 const [ isCalendarOpen , setIsCalendarOpen ] = useState ( isCalendarOpenProps ) ;
237237 const lastPressedKey = useRef < KeyboardEvent [ 'key' ] | undefined > ( undefined ) ;
238+ const hasPendingInternalChange = useRef ( false ) ;
238239
239240 useEffect ( ( ) => {
240241 setIsCalendarOpen ( isCalendarOpenProps ) ;
@@ -365,6 +366,16 @@ export default function DateInput({
365366 return dividers ? dividers [ 0 ] : null ;
366367 } ) ( ) ;
367368
369+ const yearMinLength = ( ( ) => {
370+ const yearMatch = format ?. match ( / y + / ) ;
371+
372+ if ( ! yearMatch || yearMatch [ 0 ] . length <= 1 ) {
373+ return null ;
374+ }
375+
376+ return yearMatch [ 0 ] . length ;
377+ } ) ( ) ;
378+
368379 function onClick ( event : React . MouseEvent < HTMLDivElement > & { target : HTMLDivElement } ) {
369380 if ( event . target === event . currentTarget ) {
370381 // Wrapper was directly clicked
@@ -468,6 +479,15 @@ export default function DateInput({
468479 return ;
469480 }
470481
482+ const isIncompleteYear =
483+ yearMinLength !== null &&
484+ yearInput . current ?. value &&
485+ yearInput . current . value . length < yearMinLength ;
486+
487+ if ( isIncompleteYear ) {
488+ return ;
489+ }
490+
471491 const isEveryValueFilled = formElements . every ( ( formElement ) => formElement . value ) ;
472492 const isEveryValueValid = formElements . every ( ( formElement ) => formElement . validity . valid ) ;
473493
@@ -500,6 +520,8 @@ export default function DateInput({
500520 ) {
501521 const { name, value } = event . target ;
502522
523+ hasPendingInternalChange . current = true ;
524+
503525 switch ( name ) {
504526 case 'year' :
505527 setYear ( value ) ;
@@ -511,9 +533,17 @@ export default function DateInput({
511533 setDay ( value ) ;
512534 break ;
513535 }
536+ }
537+
538+ // biome-ignore lint/correctness/useExhaustiveDependencies: onChangeExternal must run after internal value state updates
539+ useEffect ( ( ) => {
540+ if ( ! hasPendingInternalChange . current ) {
541+ return ;
542+ }
514543
544+ hasPendingInternalChange . current = false ;
515545 onChangeExternal ( ) ;
516- }
546+ } , [ day , month , year ] ) ;
517547
518548 /**
519549 * Called when native date input is changed.
0 commit comments