Skip to content

Commit 86180c4

Browse files
authored
Merge 6d646a7 into 09b3ab1
2 parents 09b3ab1 + 6d646a7 commit 86180c4

File tree

1 file changed

+46
-13
lines changed

1 file changed

+46
-13
lines changed

src/Picker.tsx

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,16 @@
1414
import type { AlignType } from '@rc-component/trigger/lib/interface';
1515
import classNames from 'classnames';
1616
import useMergedState from 'rc-util/lib/hooks/useMergedState';
17-
import warning from 'rc-util/lib/warning';
1817
import pickAttrs from 'rc-util/lib/pickAttrs';
18+
import warning from 'rc-util/lib/warning';
1919
import * as React from 'react';
20+
import { GenerateConfig } from './generate';
2021
import useHoverValue from './hooks/useHoverValue';
2122
import usePickerInput from './hooks/usePickerInput';
2223
import usePresets from './hooks/usePresets';
2324
import useTextValueMapping from './hooks/useTextValueMapping';
2425
import useValueTexts from './hooks/useValueTexts';
25-
import type { CustomFormat, PickerMode, PresetDate } from './interface';
26+
import type { CustomFormat, DisabledTime, PickerMode, PresetDate } from './interface';
2627
import type { ContextOperationRefProps } from './PanelContext';
2728
import PanelContext from './PanelContext';
2829
import type {
@@ -34,10 +35,10 @@ import PickerPanel from './PickerPanel';
3435
import PickerTrigger from './PickerTrigger';
3536
import PresetPanel from './PresetPanel';
3637
import { formatValue, isEqual, parseValue } from './utils/dateUtil';
38+
import { getClearIcon } from './utils/getClearIcon';
3739
import { toArray } from './utils/miscUtil';
3840
import { elementsContains, getDefaultFormat, getInputSize } from './utils/uiUtil';
3941
import { legacyPropsWarning } from './utils/warnUtil';
40-
import { getClearIcon } from './utils/getClearIcon';
4142

4243
export type PickerRefConfig = {
4344
focus: () => void;
@@ -67,8 +68,8 @@ export type PickerSharedProps<DateType> = {
6768

6869
// Render
6970
suffixIcon?: React.ReactNode;
70-
/**
71-
* Clear all icon
71+
/**
72+
* Clear all icon
7273
* @deprecated Please use `allowClear` instead
7374
**/
7475
clearIcon?: React.ReactNode;
@@ -145,6 +146,32 @@ type MergedPickerProps<DateType> = {
145146
picker?: PickerMode;
146147
} & OmitType<DateType>;
147148

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+
148175
function InnerPicker<DateType>(props: PickerProps<DateType>) {
149176
const {
150177
prefixCls = 'rc-picker',
@@ -196,6 +223,7 @@ function InnerPicker<DateType>(props: PickerProps<DateType>) {
196223
autoComplete = 'off',
197224
inputRender,
198225
changeOnBlur,
226+
disabledTime,
199227
} = props as MergedPickerProps<DateType>;
200228

201229
const inputRef = React.useRef<HTMLInputElement>(null);
@@ -253,6 +281,8 @@ function InnerPicker<DateType>(props: PickerProps<DateType>) {
253281
locale,
254282
});
255283

284+
const timeProps = typeof showTime === 'object' ? showTime : {};
285+
256286
const [text, triggerTextChange, resetText] = useTextValueMapping({
257287
valueTexts,
258288
onTextChange: (newText) => {
@@ -261,7 +291,11 @@ function InnerPicker<DateType>(props: PickerProps<DateType>) {
261291
formatList,
262292
generateConfig,
263293
});
264-
if (inputDate && (!disabledDate || !disabledDate(inputDate))) {
294+
if (
295+
inputDate &&
296+
(!disabledDate || !disabledDate(inputDate)) &&
297+
!validateTime(picker, disabledTime, inputDate || timeProps?.defaultValue, generateConfig)
298+
) {
265299
setSelectedValue(inputDate);
266300
}
267301
},
@@ -340,7 +374,8 @@ function InnerPicker<DateType>(props: PickerProps<DateType>) {
340374
// When user typing disabledDate with keyboard and enter, this value will be empty
341375
!selectedValue ||
342376
// Normal disabled check
343-
(disabledDate && disabledDate(selectedValue))
377+
(disabledDate && disabledDate(selectedValue)) ||
378+
validateTime(picker, disabledTime, selectedValue || timeProps?.defaultValue, generateConfig)
344379
) {
345380
return false;
346381
}
@@ -490,11 +525,7 @@ function InnerPicker<DateType>(props: PickerProps<DateType>) {
490525
);
491526
}
492527

493-
const mergedClearIcon: React.ReactNode = getClearIcon(
494-
prefixCls,
495-
allowClear,
496-
clearIcon,
497-
);
528+
const mergedClearIcon: React.ReactNode = getClearIcon(prefixCls, allowClear, clearIcon);
498529

499530
const clearNode: React.ReactNode = (
500531
<span
@@ -517,7 +548,9 @@ function InnerPicker<DateType>(props: PickerProps<DateType>) {
517548

518549
const mergedAllowClear = !!allowClear && mergedValue && !disabled;
519550

520-
const mergedInputProps: React.InputHTMLAttributes<HTMLInputElement> & { ref: React.MutableRefObject<HTMLInputElement> } = {
551+
const mergedInputProps: React.InputHTMLAttributes<HTMLInputElement> & {
552+
ref: React.MutableRefObject<HTMLInputElement>;
553+
} = {
521554
id,
522555
tabIndex,
523556
disabled,

0 commit comments

Comments
 (0)