@@ -279,6 +279,11 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
279279 // ============================= Misc ==============================
280280 const formatList = toArray ( getDefaultFormat < DateType > ( format , picker , showTime , use12Hours ) ) ;
281281
282+ const formatDateValue = ( values : RangeValue < DateType > , index : 0 | 1 ) =>
283+ values && values [ index ]
284+ ? formatValue ( values [ index ] , { generateConfig, locale, format : formatList [ 0 ] } )
285+ : '' ;
286+
282287 // Operation ref
283288 const operationRef : React . MutableRefObject < ContextOperationRefProps | null > =
284289 useRef < ContextOperationRefProps > ( null ) ;
@@ -398,7 +403,11 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
398403 } , 0 ) ;
399404 }
400405
401- function triggerChange ( newValue : RangeValue < DateType > , sourceIndex : 0 | 1 ) {
406+ function triggerChange (
407+ newValue : RangeValue < DateType > ,
408+ sourceIndex : 0 | 1 ,
409+ triggerCalendarChangeOnly ?: boolean ,
410+ ) {
402411 let values = newValue ;
403412 let startValue = getValue ( values , 0 ) ;
404413 let endValue = getValue ( values , 1 ) ;
@@ -432,37 +441,30 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
432441
433442 setSelectedValue ( values ) ;
434443
435- const startStr =
436- values && values [ 0 ]
437- ? formatValue ( values [ 0 ] , { generateConfig, locale, format : formatList [ 0 ] } )
438- : '' ;
439- const endStr =
440- values && values [ 1 ]
441- ? formatValue ( values [ 1 ] , { generateConfig, locale, format : formatList [ 0 ] } )
442- : '' ;
444+ const startStr = formatDateValue ( values , 0 ) ;
445+ const endStr = formatDateValue ( values , 1 ) ;
443446
444447 if ( onCalendarChange ) {
445448 const info : RangeInfo = { range : sourceIndex === 0 ? 'start' : 'end' } ;
446449
447450 onCalendarChange ( values , [ startStr , endStr ] , info ) ;
448451 }
449452
450- // >>>>> Trigger `onChange` event
451- const canStartValueTrigger = canValueTrigger ( startValue , 0 , mergedDisabled , allowEmpty ) ;
452- const canEndValueTrigger = canValueTrigger ( endValue , 1 , mergedDisabled , allowEmpty ) ;
453-
454- const canTrigger = values === null || ( canStartValueTrigger && canEndValueTrigger ) ;
455-
456- if ( canTrigger ) {
457- // Trigger onChange only when value is validate
458- setInnerValue ( values ) ;
459-
460- if (
461- onChange &&
462- ( ! isEqual ( generateConfig , getValue ( mergedValue , 0 ) , startValue ) ||
463- ! isEqual ( generateConfig , getValue ( mergedValue , 1 ) , endValue ) )
464- ) {
465- onChange ( values , [ startStr , endStr ] ) ;
453+ if ( ! triggerCalendarChangeOnly ) {
454+ // >>>>> Trigger `onChange` event
455+ const canStartValueTrigger = canValueTrigger ( startValue , 0 , mergedDisabled , allowEmpty ) ;
456+ const canEndValueTrigger = canValueTrigger ( endValue , 1 , mergedDisabled , allowEmpty ) ;
457+ const canTrigger = values === null || ( canStartValueTrigger && canEndValueTrigger ) ;
458+ if ( canTrigger ) {
459+ // Trigger onChange only when value is validate
460+ setInnerValue ( values ) ;
461+ if (
462+ onChange &&
463+ ( ! isEqual ( generateConfig , getValue ( mergedValue , 0 ) , startValue ) ||
464+ ! isEqual ( generateConfig , getValue ( mergedValue , 1 ) , endValue ) )
465+ ) {
466+ onChange ( values , [ startStr , endStr ] ) ;
467+ }
466468 }
467469 }
468470 }
@@ -570,29 +572,44 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
570572 } , [ mergedOpen ] ) ;
571573
572574 const onInternalBlur : React . FocusEventHandler < HTMLInputElement > = ( e ) => {
573- if ( changeOnBlur && delayOpen ) {
574- const selectedIndexValue = getValue ( selectedValue , mergedActivePickerIndex ) ;
575- if ( selectedIndexValue ) {
576- triggerChange ( selectedValue , mergedActivePickerIndex ) ;
575+ if ( delayOpen ) {
576+ if ( changeOnBlur ) {
577+ const selectedIndexValue = getValue ( selectedValue , mergedActivePickerIndex ) ;
578+
579+ if ( selectedIndexValue ) {
580+ triggerChange ( selectedValue , mergedActivePickerIndex ) ;
581+ }
582+ } else if ( needConfirmButton ) {
583+ // when in dateTime mode, switching between two date input fields will trigger onCalendarChange.
584+ // when onBlur is triggered, the input field has already switched,
585+ // so it's necessary to obtain the value of the previous input field here.
586+ const needTriggerIndex = mergedActivePickerIndex ? 0 : 1 ;
587+ const selectedIndexValue = getValue ( selectedValue , needTriggerIndex ) ;
588+
589+ if ( selectedIndexValue ) {
590+ triggerChange ( selectedValue , needTriggerIndex , true ) ;
591+ }
577592 }
578593 }
594+
579595 return onBlur ?.( e ) ;
580596 } ;
581597
582598 const getSharedInputHookProps = ( index : 0 | 1 , resetText : ( ) => void ) => ( {
583599 blurToCancel : ! changeOnBlur && needConfirmButton ,
584600 forwardKeyDown,
585601 onBlur : onInternalBlur ,
586- isClickOutside : ( target : EventTarget | null ) =>
587- ! elementsContains (
602+ isClickOutside : ( target : EventTarget | null ) => {
603+ const elementsRefs = [ startInputDivRef . current , endInputDivRef . current , containerRef . current ] ;
604+ return ! elementsContains (
588605 [
606+ // Filter the ref of the currently selected input to trigger the onBlur event of another input.
607+ ...( needConfirmButton ? [ elementsRefs [ mergedActivePickerIndex ] ] : elementsRefs ) ,
589608 panelDivRef . current ,
590- startInputDivRef . current ,
591- endInputDivRef . current ,
592- containerRef . current ,
593609 ] ,
594610 target as HTMLElement ,
595- ) ,
611+ ) ;
612+ } ,
596613 onFocus : ( e : React . FocusEvent < HTMLInputElement > ) => {
597614 if ( onFocus ) {
598615 onFocus ( e ) ;
@@ -637,7 +654,6 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
637654 onKeyDown : ( e , preventDefault ) => {
638655 onKeyDown ?.( e , preventDefault ) ;
639656 } ,
640- changeOnBlur,
641657 } ;
642658
643659 const [ startInputProps , { focused : startFocused , typing : startTyping } ] = usePickerInput ( {
0 commit comments