From 4dd71eeff204316240f84d8d85e8735e252c619c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E8=B4=A7=E6=9C=BA=E5=99=A8=E4=BA=BA?= Date: Tue, 12 Nov 2024 14:18:44 +0800 Subject: [PATCH] enhance: not allow change for locked --- docs/examples/debug.tsx | 41 +++++++++++---------- src/PickerInput/RangePicker.tsx | 20 +++++++++- src/PickerInput/hooks/useRangeActiveLock.ts | 23 ++++++++++++ src/PickerInput/hooks/useRangeValue.ts | 11 +++++- 4 files changed, 73 insertions(+), 22 deletions(-) create mode 100644 src/PickerInput/hooks/useRangeActiveLock.ts 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/useRangeActiveLock.ts b/src/PickerInput/hooks/useRangeActiveLock.ts new file mode 100644 index 000000000..e249a68b6 --- /dev/null +++ b/src/PickerInput/hooks/useRangeActiveLock.ts @@ -0,0 +1,23 @@ +import * as React from 'react'; + +export default function useRangeActiveLock(): [ + focused: boolean, + triggerFocus: (focused: boolean) => void, + // lastOperation: (type?: OperationType) => OperationType, + // activeIndex: number, + setActiveIndex: (index: number) => void, + // nextActiveIndex: NextActive, + // activeList: number[], +] { + const [activeIndex, setActiveIndex] = React.useState(null); + const [focused, setFocused] = React.useState(false); + const [activeList, setActiveList] = React.useState([]); + + // ============================= Active ============================= + const onActive = (index: number) => { + setActiveIndex(index); + setActiveList([...activeList, index]); + }; + + return [focused, setFocused, onActive]; +} 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