diff --git a/docs/examples/debug.tsx b/docs/examples/debug.tsx index 917336617..fb459c797 100644 --- a/docs/examples/debug.tsx +++ b/docs/examples/debug.tsx @@ -55,32 +55,35 @@ export default () => { {...sharedLocale} style={{ width: 400 }} showTime + // allowEmpty // disabledDate={(_, info) => { // console.log('Date:', info); // return false; // }} - disabledTime={(date, range, info) => { - // console.log(`Time-${range}`, range, info); - const { from } = info; + // disabledTime={(date, range, info) => { + // // console.log(`Time-${range}`, range, info); + // const { from } = info; - if (from) { - console.log( - `Time-${range}`, - from.format('YYYY-MM-DD HH:mm:ss'), - date.format('YYYY-MM-DD HH:mm:ss'), - ); - } + // if (from) { + // console.log( + // `Time-${range}`, + // from.format('YYYY-MM-DD HH:mm:ss'), + // date.format('YYYY-MM-DD HH:mm:ss'), + // ); + // } - if (from && from.isSame(date, 'day')) { - return { - disabledHours: () => [from.hour()], - disabledMinutes: () => [0, 1, 2, 3], - disabledSeconds: () => [0, 1, 2, 3], - }; - } - return {}; - }} + // if (from && from.isSame(date, 'day')) { + // return { + // disabledHours: () => [from.hour()], + // disabledMinutes: () => [0, 1, 2, 3], + // disabledSeconds: () => [0, 1, 2, 3], + // }; + // } + // return {}; + // }} /> + + {/* (config: T | [T, T] | null | undefined, defaultConfig: T): [T, T] { @@ -325,6 +325,8 @@ function RangePicker( flushSubmit, /** Trigger `onChange` directly without check `disabledDate` */ triggerSubmitChange, + /** Tell `index` has filled value in it */ + hasSubmitValue, ] = useRangeValue, DateType>( filledProps, mergedValue, @@ -630,6 +632,22 @@ function RangePicker( // ======================= Selector ======================= const onSelectorFocus: SelectorProps['onFocus'] = (event, index) => { + // Check if `needConfirm` but user not submit yet + const activeListLen = activeIndexList.length; + const lastActiveIndex = activeIndexList[activeListLen - 1]; + if ( + activeListLen && + lastActiveIndex !== index && + needConfirm && + // Not change index if is not filled + !allowEmpty[lastActiveIndex] && + !hasSubmitValue(lastActiveIndex) && + calendarValue[lastActiveIndex] + ) { + selectorRef.current.focus({ index: lastActiveIndex }); + return; + } + lastOperation('input'); triggerOpen(true, { diff --git a/src/PickerInput/hooks/useRangeValue.ts b/src/PickerInput/hooks/useRangeValue.ts index 14814869f..bf33d1c6e 100644 --- a/src/PickerInput/hooks/useRangeValue.ts +++ b/src/PickerInput/hooks/useRangeValue.ts @@ -76,7 +76,7 @@ function orderDates( * Used for internal value management. * It should always use `mergedValue` in render logic */ -export function useCalendarValue(mergedValue: MergedValueType) { +function useCalendarValue(mergedValue: MergedValueType) { const [calendarValue, setCalendarValue] = useSyncState(mergedValue); /** Sync calendarValue & submitValue back with value */ @@ -186,6 +186,8 @@ export default function useRangeValue void, /** Trigger `onChange` directly without check `disabledDate` */ triggerSubmitChange: (value: ValueType) => boolean, + /** Tell `index` has filled value in it */ + hasSubmitValue: (index: number) => boolean, ] { const { // MISC @@ -331,6 +333,11 @@ export default function useRangeValue { resetWarned(); global.scrollCalled = false; jest.useFakeTimers().setSystemTime(getDay('1990-09-03 00:00:00').valueOf()); + document.body.innerHTML = ''; }); afterEach(() => { @@ -2054,4 +2055,20 @@ describe('Picker.Range', () => { 'rc-picker-input-active', ); }); + + it('should not click to focus on next field if first field is not confirm', () => { + const onCalendarChange = jest.fn(); + const { container } = render( + , + ); + + // Select first field + openPicker(container, 0); + selectCell(11); + expect(onCalendarChange).toHaveBeenCalled(); + + // Not click confirm and click next field + openPicker(container, 1); + expect(container.querySelectorAll('.rc-picker-input')[0]).toHaveClass('rc-picker-input-active'); + }); });