@@ -279,6 +279,11 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
279
279
// ============================= Misc ==============================
280
280
const formatList = toArray ( getDefaultFormat < DateType > ( format , picker , showTime , use12Hours ) ) ;
281
281
282
+ const formatDateValue = ( values : RangeValue < DateType > , index : 0 | 1 ) =>
283
+ values && values [ index ]
284
+ ? formatValue ( values [ index ] , { generateConfig, locale, format : formatList [ 0 ] } )
285
+ : '' ;
286
+
282
287
// Operation ref
283
288
const operationRef : React . MutableRefObject < ContextOperationRefProps | null > =
284
289
useRef < ContextOperationRefProps > ( null ) ;
@@ -398,7 +403,11 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
398
403
} , 0 ) ;
399
404
}
400
405
401
- function triggerChange ( newValue : RangeValue < DateType > , sourceIndex : 0 | 1 ) {
406
+ function triggerChange (
407
+ newValue : RangeValue < DateType > ,
408
+ sourceIndex : 0 | 1 ,
409
+ triggerCalendarChangeOnly ?: boolean ,
410
+ ) {
402
411
let values = newValue ;
403
412
let startValue = getValue ( values , 0 ) ;
404
413
let endValue = getValue ( values , 1 ) ;
@@ -432,37 +441,30 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
432
441
433
442
setSelectedValue ( values ) ;
434
443
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 ) ;
443
446
444
447
if ( onCalendarChange ) {
445
448
const info : RangeInfo = { range : sourceIndex === 0 ? 'start' : 'end' } ;
446
449
447
450
onCalendarChange ( values , [ startStr , endStr ] , info ) ;
448
451
}
449
452
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
+ }
466
468
}
467
469
}
468
470
}
@@ -570,29 +572,44 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
570
572
} , [ mergedOpen ] ) ;
571
573
572
574
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
+ }
577
592
}
578
593
}
594
+
579
595
return onBlur ?.( e ) ;
580
596
} ;
581
597
582
598
const getSharedInputHookProps = ( index : 0 | 1 , resetText : ( ) => void ) => ( {
583
599
blurToCancel : ! changeOnBlur && needConfirmButton ,
584
600
forwardKeyDown,
585
601
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 (
588
605
[
606
+ // Filter the ref of the currently selected input to trigger the onBlur event of another input.
607
+ ...( needConfirmButton ? [ elementsRefs [ mergedActivePickerIndex ] ] : elementsRefs ) ,
589
608
panelDivRef . current ,
590
- startInputDivRef . current ,
591
- endInputDivRef . current ,
592
- containerRef . current ,
593
609
] ,
594
610
target as HTMLElement ,
595
- ) ,
611
+ ) ;
612
+ } ,
596
613
onFocus : ( e : React . FocusEvent < HTMLInputElement > ) => {
597
614
if ( onFocus ) {
598
615
onFocus ( e ) ;
@@ -637,7 +654,6 @@ function InnerRangePicker<DateType>(props: RangePickerProps<DateType>) {
637
654
onKeyDown : ( e , preventDefault ) => {
638
655
onKeyDown ?.( e , preventDefault ) ;
639
656
} ,
640
- changeOnBlur,
641
657
} ;
642
658
643
659
const [ startInputProps , { focused : startFocused , typing : startTyping } ] = usePickerInput ( {
0 commit comments