14
14
import type { AlignType } from '@rc-component/trigger/lib/interface' ;
15
15
import classNames from 'classnames' ;
16
16
import useMergedState from 'rc-util/lib/hooks/useMergedState' ;
17
- import warning from 'rc-util/lib/warning' ;
18
17
import pickAttrs from 'rc-util/lib/pickAttrs' ;
18
+ import warning from 'rc-util/lib/warning' ;
19
19
import * as React from 'react' ;
20
+ import { GenerateConfig } from './generate' ;
20
21
import useHoverValue from './hooks/useHoverValue' ;
21
22
import usePickerInput from './hooks/usePickerInput' ;
22
23
import usePresets from './hooks/usePresets' ;
23
24
import useTextValueMapping from './hooks/useTextValueMapping' ;
24
25
import useValueTexts from './hooks/useValueTexts' ;
25
- import type { CustomFormat , PickerMode , PresetDate } from './interface' ;
26
+ import type { CustomFormat , DisabledTime , PickerMode , PresetDate } from './interface' ;
26
27
import type { ContextOperationRefProps } from './PanelContext' ;
27
28
import PanelContext from './PanelContext' ;
28
29
import type {
@@ -34,10 +35,10 @@ import PickerPanel from './PickerPanel';
34
35
import PickerTrigger from './PickerTrigger' ;
35
36
import PresetPanel from './PresetPanel' ;
36
37
import { formatValue , isEqual , parseValue } from './utils/dateUtil' ;
38
+ import { getClearIcon } from './utils/getClearIcon' ;
37
39
import { toArray } from './utils/miscUtil' ;
38
40
import { elementsContains , getDefaultFormat , getInputSize } from './utils/uiUtil' ;
39
41
import { legacyPropsWarning } from './utils/warnUtil' ;
40
- import { getClearIcon } from './utils/getClearIcon' ;
41
42
42
43
export type PickerRefConfig = {
43
44
focus : ( ) => void ;
@@ -67,8 +68,8 @@ export type PickerSharedProps<DateType> = {
67
68
68
69
// Render
69
70
suffixIcon ?: React . ReactNode ;
70
- /**
71
- * Clear all icon
71
+ /**
72
+ * Clear all icon
72
73
* @deprecated Please use `allowClear` instead
73
74
**/
74
75
clearIcon ?: React . ReactNode ;
@@ -145,6 +146,32 @@ type MergedPickerProps<DateType> = {
145
146
picker ?: PickerMode ;
146
147
} & OmitType < DateType > ;
147
148
149
+ function testValueInSet ( num : number , range : number [ ] ) {
150
+ if ( typeof num === 'undefined' || typeof range === 'undefined' ) return ;
151
+ const set = new Set ( range ) ;
152
+ return set . has ( num ) ;
153
+ }
154
+
155
+ function validateTime < DateType > (
156
+ picker : PickerMode ,
157
+ disabledTime : DisabledTime < DateType > ,
158
+ date : DateType ,
159
+ generateConfig : GenerateConfig < DateType > ,
160
+ ) {
161
+ if ( ! disabledTime || picker !== 'date' ) return false ;
162
+ const disabledTimes = disabledTime ( date ) ;
163
+ if ( ! disabledTimes ) return false ;
164
+ const { disabledHours, disabledMinutes, disabledSeconds } = disabledTimes ;
165
+ const hour = generateConfig . getHour ( date ) ;
166
+ const minter = generateConfig . getMinute ( date ) ;
167
+ const second = generateConfig . getSecond ( date ) ;
168
+
169
+ const validateHour = testValueInSet ( hour , disabledHours ?.( ) ) ;
170
+ const validateMinute = testValueInSet ( minter , disabledMinutes ?.( hour ) ) ;
171
+ const validateSecond = testValueInSet ( second , disabledSeconds ?.( hour , minter ) ) ;
172
+ return validateHour || validateMinute || validateSecond ;
173
+ }
174
+
148
175
function InnerPicker < DateType > ( props : PickerProps < DateType > ) {
149
176
const {
150
177
prefixCls = 'rc-picker' ,
@@ -196,6 +223,7 @@ function InnerPicker<DateType>(props: PickerProps<DateType>) {
196
223
autoComplete = 'off' ,
197
224
inputRender,
198
225
changeOnBlur,
226
+ disabledTime,
199
227
} = props as MergedPickerProps < DateType > ;
200
228
201
229
const inputRef = React . useRef < HTMLInputElement > ( null ) ;
@@ -253,6 +281,8 @@ function InnerPicker<DateType>(props: PickerProps<DateType>) {
253
281
locale,
254
282
} ) ;
255
283
284
+ const timeProps = typeof showTime === 'object' ? showTime : { } ;
285
+
256
286
const [ text , triggerTextChange , resetText ] = useTextValueMapping ( {
257
287
valueTexts,
258
288
onTextChange : ( newText ) => {
@@ -261,7 +291,11 @@ function InnerPicker<DateType>(props: PickerProps<DateType>) {
261
291
formatList,
262
292
generateConfig,
263
293
} ) ;
264
- if ( inputDate && ( ! disabledDate || ! disabledDate ( inputDate ) ) ) {
294
+ if (
295
+ inputDate &&
296
+ ( ! disabledDate || ! disabledDate ( inputDate ) ) &&
297
+ ! validateTime ( picker , disabledTime , inputDate || timeProps ?. defaultValue , generateConfig )
298
+ ) {
265
299
setSelectedValue ( inputDate ) ;
266
300
}
267
301
} ,
@@ -340,7 +374,8 @@ function InnerPicker<DateType>(props: PickerProps<DateType>) {
340
374
// When user typing disabledDate with keyboard and enter, this value will be empty
341
375
! selectedValue ||
342
376
// Normal disabled check
343
- ( disabledDate && disabledDate ( selectedValue ) )
377
+ ( disabledDate && disabledDate ( selectedValue ) ) ||
378
+ validateTime ( picker , disabledTime , selectedValue || timeProps ?. defaultValue , generateConfig )
344
379
) {
345
380
return false ;
346
381
}
@@ -490,11 +525,7 @@ function InnerPicker<DateType>(props: PickerProps<DateType>) {
490
525
) ;
491
526
}
492
527
493
- const mergedClearIcon : React . ReactNode = getClearIcon (
494
- prefixCls ,
495
- allowClear ,
496
- clearIcon ,
497
- ) ;
528
+ const mergedClearIcon : React . ReactNode = getClearIcon ( prefixCls , allowClear , clearIcon ) ;
498
529
499
530
const clearNode : React . ReactNode = (
500
531
< span
@@ -517,7 +548,9 @@ function InnerPicker<DateType>(props: PickerProps<DateType>) {
517
548
518
549
const mergedAllowClear = ! ! allowClear && mergedValue && ! disabled ;
519
550
520
- const mergedInputProps : React . InputHTMLAttributes < HTMLInputElement > & { ref : React . MutableRefObject < HTMLInputElement > } = {
551
+ const mergedInputProps : React . InputHTMLAttributes < HTMLInputElement > & {
552
+ ref : React . MutableRefObject < HTMLInputElement > ;
553
+ } = {
521
554
id,
522
555
tabIndex,
523
556
disabled,
0 commit comments