@@ -11,17 +11,19 @@ import {
1111 DisabledTime ,
1212 PickerMode ,
1313 PanelMode ,
14+ OnPanelChange ,
1415} from './interface' ;
1516import { toArray } from './utils/miscUtil' ;
1617import RangeContext from './RangeContext' ;
1718import { isSameDate } from './utils/dateUtil' ;
1819import { getDefaultFormat } from './utils/uiUtil' ;
1920import { SharedTimeProps } from './panels/TimePanel' ;
2021
21- type RangeValue < DateType > = [ DateType | null , DateType | null ] | null ;
22+ type EventValue < DateType > = DateType | null ;
23+ type RangeValue < DateType > = [ EventValue < DateType > , EventValue < DateType > ] | null ;
2224
2325function canTriggerChange < DateType > (
24- dates : [ DateType | null , DateType | null ] ,
26+ dates : [ EventValue < DateType > , EventValue < DateType > ] ,
2527 allowEmpty ?: [ boolean , boolean ] ,
2628) : boolean {
2729 const passStart = dates [ 0 ] || ( allowEmpty && allowEmpty [ 0 ] ) ;
@@ -35,7 +37,7 @@ export interface RangePickerSharedProps<DateType> {
3537 defaultPickerValue ?: [ DateType , DateType ] ;
3638 placeholder ?: [ string , string ] ;
3739 disabledTime ?: (
38- date : DateType | null ,
40+ date : EventValue < DateType > ,
3941 type : 'start' | 'end' ,
4042 ) => DisabledTimes ;
4143 ranges ?: Record <
@@ -48,13 +50,17 @@ export interface RangePickerSharedProps<DateType> {
4850 selectable ?: [ boolean , boolean ] ;
4951 mode ?: [ PanelMode , PanelMode ] ;
5052 onChange ?: (
51- value : RangeValue < DateType > ,
53+ values : RangeValue < DateType > ,
5254 formatString : [ string , string ] ,
5355 ) => void ;
5456 onCalendarChange ?: (
55- value : RangeValue < DateType > ,
57+ values : RangeValue < DateType > ,
5658 formatString : [ string , string ] ,
5759 ) => void ;
60+ onPanelChange ?: (
61+ values : RangeValue < DateType > ,
62+ modes : [ PanelMode , PanelMode ] ,
63+ ) => void ;
5864 onFocus ?: React . FocusEventHandler < HTMLInputElement > ;
5965 onBlur ?: React . FocusEventHandler < HTMLInputElement > ;
6066}
@@ -64,13 +70,14 @@ type OmitPickerProps<Props> = Omit<
6470 | 'value'
6571 | 'defaultValue'
6672 | 'defaultPickerValue'
67- | 'onChange'
68- | 'onSelect'
6973 | 'placeholder'
7074 | 'disabledTime'
7175 | 'showToday'
7276 | 'showTime'
7377 | 'mode'
78+ | 'onChange'
79+ | 'onSelect'
80+ | 'onPanelChange'
7481> ;
7582
7683export interface RangePickerBaseProps < DateType >
@@ -135,6 +142,7 @@ function InternalRangePicker<DateType>(
135142 disabled,
136143 onChange,
137144 onCalendarChange,
145+ onPanelChange,
138146 onFocus,
139147 onBlur,
140148 } = props as MergedRangePickerProps < DateType > & {
@@ -248,6 +256,69 @@ function InternalRangePicker<DateType>(
248256 }
249257 } ;
250258
259+ // ============================== Mode ==============================
260+
261+ /**
262+ * [Legacy] handle internal `onPanelChange`
263+ */
264+ const [ innerModes , setInnerModes ] = React . useState ( ( ) : [
265+ PanelMode ,
266+ PanelMode ,
267+ ] => {
268+ if ( mode ) {
269+ return mode ;
270+ }
271+ if ( picker ) {
272+ return [ picker , picker ] ;
273+ }
274+ return showTime ? [ 'datetime' , 'datetime' ] : [ 'date' , 'date' ] ;
275+ } ) ;
276+ const [ onStartPanelChange , onEndPanelChange ] = React . useMemo <
277+ [ OnPanelChange < DateType > | undefined , OnPanelChange < DateType > | undefined ]
278+ > ( ( ) => {
279+ const onInternalPanelChange = (
280+ newValue : DateType ,
281+ newMode : PanelMode ,
282+ source : 'start' | 'end' ,
283+ ) => {
284+ const values : [ EventValue < DateType > , EventValue < DateType > ] = [
285+ ...( mergedValue || [ ] ) ,
286+ ] as [ EventValue < DateType > , EventValue < DateType > ] ;
287+ const modes : [ PanelMode , PanelMode ] = [ ...innerModes ] as [
288+ PanelMode ,
289+ PanelMode ,
290+ ] ;
291+
292+ if ( source === 'start' ) {
293+ values [ 0 ] = newValue ;
294+ modes [ 0 ] = newMode ;
295+ } else {
296+ values [ 1 ] = newValue ;
297+ modes [ 1 ] = newMode ;
298+ }
299+ setInnerModes ( modes ) ;
300+
301+ if ( onPanelChange ) {
302+ onPanelChange ( values , modes ) ;
303+ }
304+ } ;
305+
306+ return [
307+ ( newVal : DateType , newMode : PanelMode ) => {
308+ onInternalPanelChange ( newVal , newMode , 'start' ) ;
309+ } ,
310+ ( newVal : DateType , newMode : PanelMode ) => {
311+ onInternalPanelChange ( newVal , newMode , 'end' ) ;
312+ } ,
313+ ] ;
314+ } , [ onPanelChange , mode , picker ] ) ;
315+
316+ React . useEffect ( ( ) => {
317+ if ( mode ) {
318+ setInnerModes ( mode ) ;
319+ }
320+ } , [ mode ] ) ;
321+
251322 // ============================= Render =============================
252323 const pickerProps = {
253324 ...props ,
@@ -257,6 +328,7 @@ function InternalRangePicker<DateType>(
257328 style : undefined ,
258329 placeholder : undefined ,
259330 disabledTime : undefined ,
331+ onPanelChange : undefined ,
260332 } ;
261333
262334 // Time
@@ -344,6 +416,7 @@ function InternalRangePicker<DateType>(
344416 onSelect = { onStartSelect }
345417 onFocus = { onFocus }
346418 onBlur = { onBlur }
419+ onPanelChange = { onStartPanelChange }
347420 />
348421 { separator }
349422 < Picker < DateType >
@@ -362,6 +435,7 @@ function InternalRangePicker<DateType>(
362435 onSelect = { onEndSelect }
363436 onFocus = { onFocus }
364437 onBlur = { onBlur }
438+ onPanelChange = { onEndPanelChange }
365439 />
366440 </ div >
367441 </ RangeContext . Provider >
0 commit comments