From b7c3ca10e01e6ea9d1b9977963be354fba2b739b Mon Sep 17 00:00:00 2001 From: Kermit Date: Sat, 19 Dec 2020 19:27:48 +0800 Subject: [PATCH 01/10] chore: optimize disabledDate logic --- src/PanelContext.tsx | 3 +- src/PickerPanel.tsx | 3 +- src/panels/PanelBody.tsx | 17 +++++-- src/utils/dateUtil.ts | 98 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 114 insertions(+), 7 deletions(-) diff --git a/src/PanelContext.tsx b/src/PanelContext.tsx index 7ae278ff3..0ed771d50 100644 --- a/src/PanelContext.tsx +++ b/src/PanelContext.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { OnSelect } from './interface'; +import { OnSelect, PanelMode } from './interface'; export type ContextOperationRefProps = { onKeyDown?: (e: React.KeyboardEvent) => boolean; @@ -18,6 +18,7 @@ export interface PanelContextProps { onSelect?: OnSelect; hideRanges?: boolean; open?: boolean; + mode?: PanelMode; /** Only used for TimePicker and this is a deprecated prop */ defaultOpenValue?: any; diff --git a/src/PickerPanel.tsx b/src/PickerPanel.tsx index 55b32e669..deda606c6 100644 --- a/src/PickerPanel.tsx +++ b/src/PickerPanel.tsx @@ -347,7 +347,7 @@ function PickerPanel(props: PickerPanelProps) { onViewDateChange: setViewDate, sourceMode, onPanelChange: onInternalPanelChange, - disabledDate: mergedMode !== 'decade' ? disabledDate : undefined, + disabledDate, }; delete pickerProps.onChange; delete pickerProps.onSelect; @@ -521,6 +521,7 @@ function PickerPanel(props: PickerPanelProps) { { prefixCls: string; @@ -46,7 +47,7 @@ export default function PanelBody({ titleCell, headerCells, }: PanelBodyProps) { - const { onDateMouseEnter, onDateMouseLeave } = React.useContext(PanelContext); + const { onDateMouseEnter, onDateMouseLeave, mode } = React.useContext(PanelContext); const cellPrefixCls = `${prefixCls}-cell`; @@ -60,7 +61,12 @@ export default function PanelBody({ for (let j = 0; j < colNum; j += 1) { const offset = i * colNum + j; const currentDate = getCellDate(baseDate, offset); - const disabled = disabledDate && disabledDate(currentDate); + const disabled = getCellDateDisabled({ + cellDate: currentDate, + mode, + disabledDate, + generateConfig, + }); if (j === 0) { rowStartDate = currentDate; @@ -78,8 +84,11 @@ export default function PanelBody({ title={title} className={classNames(cellPrefixCls, { [`${cellPrefixCls}-disabled`]: disabled, - [`${cellPrefixCls}-start`]: getCellText(currentDate) === 1 || picker === 'year' && Number(title) % 10 === 0, - [`${cellPrefixCls}-end`]: title === getLastDay(generateConfig, currentDate) || picker === 'year' && Number(title) % 10 === 9, + [`${cellPrefixCls}-start`]: + getCellText(currentDate) === 1 || (picker === 'year' && Number(title) % 10 === 0), + [`${cellPrefixCls}-end`]: + title === getLastDay(generateConfig, currentDate) || + (picker === 'year' && Number(title) % 10 === 9), ...getCellClassName(currentDate), })} onClick={() => { diff --git a/src/utils/dateUtil.ts b/src/utils/dateUtil.ts index 3a718b31f..e4710c025 100644 --- a/src/utils/dateUtil.ts +++ b/src/utils/dateUtil.ts @@ -1,5 +1,6 @@ +import { DECADE_UNIT_DIFF } from '../panels/DecadePanel/index'; +import { PanelMode, NullableDateType, PickerMode, Locale, CustomFormat } from '../interface'; import { GenerateConfig } from '../generate'; -import { NullableDateType, PickerMode, Locale, CustomFormat } from '../interface'; export const WEEK_DAY_COUNT = 7; @@ -228,3 +229,98 @@ export function parseValue( return generateConfig.locale.parse(locale.locale, value, formatList as string[]); } + +export function getCellDateDisabled({ + cellDate, + mode, + disabledDate, + generateConfig, +}: { + cellDate: DateType; + mode: PanelMode; + generateConfig: GenerateConfig; + disabledDate?: (date: DateType) => boolean; +}): boolean { + if (!disabledDate) return false; + switch (mode) { + case 'date': + case 'week': { + return disabledDate(cellDate); + } + case 'month': { + const startDate = 1; + const endDate = generateConfig.getDate(generateConfig.getEndDate(cellDate)); + let currentDate = startDate; + while (currentDate <= endDate) { + const date = generateConfig.setDate(cellDate, currentDate); + if (!disabledDate(date)) { + return false; + } + currentDate += 1; + } + return true; + } + case 'quarter': { + const startMonth = Math.floor(generateConfig.getMonth(cellDate) / 3) * 3; + const endMonth = startMonth + 2; + let currentMonth = startMonth; + while (currentMonth <= endMonth) { + const date = generateConfig.setMonth(cellDate, currentMonth); + if ( + !getCellDateDisabled({ + cellDate: date, + mode: 'month', + generateConfig, + disabledDate, + }) + ) { + return false; + } + currentMonth += 1; + } + return true; + } + case 'year': { + const startMonth = 0; + const endMonth = 11; + let currentMonth = startMonth; + while (currentMonth <= endMonth) { + const date = generateConfig.setMonth(cellDate, currentMonth); + if ( + !getCellDateDisabled({ + cellDate: date, + mode: 'month', + generateConfig, + disabledDate, + }) + ) { + return false; + } + currentMonth += 1; + } + return true; + } + case 'decade': { + const year = generateConfig.getYear(cellDate); + const startYear = Math.floor(year / DECADE_UNIT_DIFF) * DECADE_UNIT_DIFF; + const endYear = startYear + DECADE_UNIT_DIFF - 1; + let currentYear = startYear; + while (currentYear <= endYear) { + const date = generateConfig.setYear(cellDate, currentYear); + if ( + !getCellDateDisabled({ + cellDate: date, + mode: 'year', + generateConfig, + disabledDate, + }) + ) { + return false; + } + currentYear += 1; + } + return true; + } + } + return false; +} From e654896a529cf3d2ba5bdf58a24dbc3c9b6c891b Mon Sep 17 00:00:00 2001 From: Kermit Date: Sun, 20 Dec 2020 13:10:30 +0800 Subject: [PATCH 02/10] fix: decade panel --- src/panels/DecadePanel/DecadeBody.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/panels/DecadePanel/DecadeBody.tsx b/src/panels/DecadePanel/DecadeBody.tsx index e0e90f198..4a8020abf 100644 --- a/src/panels/DecadePanel/DecadeBody.tsx +++ b/src/panels/DecadePanel/DecadeBody.tsx @@ -16,7 +16,7 @@ export interface YearBodyProps { function DecadeBody(props: YearBodyProps) { const DECADE_UNIT_DIFF_DES = DECADE_UNIT_DIFF - 1; - const { prefixCls, viewDate, generateConfig, disabledDate } = props; + const { prefixCls, viewDate, generateConfig } = props; const cellPrefixCls = `${prefixCls}-cell`; @@ -35,13 +35,10 @@ function DecadeBody(props: YearBodyProps) { ); const getCellClassName = (date: DateType) => { - const disabled = disabledDate && disabledDate(date); - const startDecadeNumber = generateConfig.getYear(date); const endDecadeNumber = startDecadeNumber + DECADE_UNIT_DIFF_DES; return { - [`${cellPrefixCls}-disabled`]: disabled, [`${cellPrefixCls}-in-view`]: startDecadeYear <= startDecadeNumber && endDecadeNumber <= endDecadeYear, [`${cellPrefixCls}-selected`]: startDecadeNumber === decadeYearNumber, From 3b872a24ad500ebd7c0d6f0db3e191d11735f721 Mon Sep 17 00:00:00 2001 From: Kermit Date: Mon, 21 Dec 2020 19:09:00 +0800 Subject: [PATCH 03/10] fix: hover value logic when change panel type --- examples/basic.tsx | 9 +++++++-- src/Picker.tsx | 17 +++++++++++------ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/examples/basic.tsx b/examples/basic.tsx index 7885a2ec1..254603acb 100644 --- a/examples/basic.tsx +++ b/examples/basic.tsx @@ -13,6 +13,11 @@ export default () => { const [value, setValue] = React.useState(defaultValue); const weekRef = React.useRef>(null); + const disabledDate = (current: Moment) => { + // Can not select days before today and today + return current && current <= moment().endOf('day'); + }; + const onSelect = (newValue: Moment) => { console.log('Select:', newValue); }; @@ -36,7 +41,7 @@ export default () => {

Basic

- {...sharedProps} locale={zhCN} /> + {...sharedProps} picker="date" value={undefined} disabledDate={disabledDate} locale={zhCN} /> {...sharedProps} locale={enUS} />
@@ -103,7 +108,7 @@ export default () => {

Week

- generateConfig={momentGenerateConfig} locale={enUS} picker="week" /> + disabledDate={disabledDate} generateConfig={momentGenerateConfig} locale={enUS} picker="week" />

Quarter

diff --git a/src/Picker.tsx b/src/Picker.tsx index 953d9894f..128348ced 100644 --- a/src/Picker.tsx +++ b/src/Picker.tsx @@ -357,6 +357,12 @@ function InnerPicker(props: PickerProps) { }; } + const [hoverValue, onEnter, onLeave] = useHoverValue(text, { + formatList, + generateConfig, + locale, + }); + // ============================= Panel ============================= const panelProps = { // Remove `picker` & `format` here since TimePicker is little different with other panel @@ -383,6 +389,11 @@ function InnerPicker(props: PickerProps) { setSelectedValue(date); }} direction={direction} + onPanelChange={(viewDate, mode) => { + const { onPanelChange } = panelProps; + onLeave(true); + onPanelChange?.(viewDate, mode); + }} /> ); @@ -445,12 +456,6 @@ function InnerPicker(props: PickerProps) { }; const popupPlacement = direction === 'rtl' ? 'bottomRight' : 'bottomLeft'; - const [hoverValue, onEnter, onLeave] = useHoverValue(text, { - formatList, - generateConfig, - locale, - }); - return ( Date: Mon, 21 Dec 2020 21:39:40 +0800 Subject: [PATCH 04/10] fix: range picker hover value --- src/RangePicker.tsx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/RangePicker.tsx b/src/RangePicker.tsx index c4de3b751..1154cf3fc 100644 --- a/src/RangePicker.tsx +++ b/src/RangePicker.tsx @@ -813,6 +813,13 @@ function InnerRangePicker(props: RangePickerProps) { locale={locale} tabIndex={-1} onPanelChange={(date, newMode) => { + // clear hover value when panel change + if (mergedActivePickerIndex === 0) { + onStartLeave(true); + } + if (mergedActivePickerIndex === 1) { + onEndLeave(true); + } triggerModesChange( updateValues(mergedModes, newMode, mergedActivePickerIndex), updateValues(selectedValue, date, mergedActivePickerIndex), From 6dd15e716f7e9df9305c9018d8b789920b0b6c37 Mon Sep 17 00:00:00 2001 From: Kermit Date: Thu, 24 Dec 2020 15:01:46 +0800 Subject: [PATCH 05/10] chore: add disableDate example --- examples/basic.tsx | 9 ++---- examples/disableDate.tsx | 63 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 7 deletions(-) create mode 100644 examples/disableDate.tsx diff --git a/examples/basic.tsx b/examples/basic.tsx index 254603acb..7885a2ec1 100644 --- a/examples/basic.tsx +++ b/examples/basic.tsx @@ -13,11 +13,6 @@ export default () => { const [value, setValue] = React.useState(defaultValue); const weekRef = React.useRef>(null); - const disabledDate = (current: Moment) => { - // Can not select days before today and today - return current && current <= moment().endOf('day'); - }; - const onSelect = (newValue: Moment) => { console.log('Select:', newValue); }; @@ -41,7 +36,7 @@ export default () => {

Basic

- {...sharedProps} picker="date" value={undefined} disabledDate={disabledDate} locale={zhCN} /> + {...sharedProps} locale={zhCN} /> {...sharedProps} locale={enUS} />
@@ -108,7 +103,7 @@ export default () => {

Week

- disabledDate={disabledDate} generateConfig={momentGenerateConfig} locale={enUS} picker="week" /> + generateConfig={momentGenerateConfig} locale={enUS} picker="week" />

Quarter

diff --git a/examples/disableDate.tsx b/examples/disableDate.tsx new file mode 100644 index 000000000..3ef67f81c --- /dev/null +++ b/examples/disableDate.tsx @@ -0,0 +1,63 @@ +import React from 'react'; +import moment, { Moment } from 'moment'; +import Picker from '../src/Picker'; +import momentGenerateConfig from '../src/generate/moment'; +import enUS from '../src/locale/en_US'; +import '../assets/index.less'; + +export default () => { + const [value, setValue] = React.useState(undefined); + + const onSelect = (newValue: Moment) => { + console.log('Select:', newValue); + }; + + const onChange = (newValue: Moment | null, formatString?: string) => { + console.log('Change:', newValue, formatString); + setValue(newValue); + }; + + function disabledDateBeforeToday(current: Moment) { + return current <= moment().endOf('day'); + } + + function disabledDateAfterToday(current: Moment) { + return current >= moment().endOf('day'); + } + + function disabledDateAfterTodayAndBeforeLastYear(current) { + return current >= moment().startOf('day') || current < moment().subtract(1, 'years'); + } + + const sharedProps = { + generateConfig: momentGenerateConfig, + value, + onSelect, + onChange, + }; + + return ( +
+

Value: {value ? value.format('YYYY-MM-DD HH:mm:ss') : 'null'}

+

Date Mode

+
+
+

Before Today

+ {...sharedProps} disabledDate={disabledDateBeforeToday} locale={enUS} /> +
+
+

After Today

+ {...sharedProps} disabledDate={disabledDateAfterToday} locale={enUS} /> +
+
+

After Today or Before last year

+ + {...sharedProps} + disabledDate={disabledDateAfterTodayAndBeforeLastYear} + locale={enUS} + /> +
+
+
+ ); +}; From c597852b9c61f8a18d422f6b0ebcf0d1007de915 Mon Sep 17 00:00:00 2001 From: Kermit Date: Fri, 25 Dec 2020 21:01:21 +0800 Subject: [PATCH 06/10] Merge branch 'master' of https://github.com/react-component/picker into fix-disableDate --- .gitignore | 1 - README.md | 9 ++-- examples/basic.tsx | 8 ++++ package.json | 2 +- src/PanelContext.tsx | 6 +-- src/Picker.tsx | 43 +++++++++---------- src/PickerPanel.tsx | 35 ++++++++-------- src/PickerTrigger.tsx | 6 +-- src/RangeContext.tsx | 6 +-- src/RangePicker.tsx | 50 ++++++++++++----------- src/generate/dateFns.ts | 2 +- src/generate/dayjs.ts | 7 ++-- src/generate/index.ts | 4 +- src/generate/moment.ts | 5 ++- src/hooks/useCellClassName.ts | 4 +- src/hooks/useHoverValue.ts | 3 +- src/hooks/usePickerInput.ts | 17 +++++++- src/hooks/useRangeDisabled.ts | 4 +- src/hooks/useRangeViewDates.ts | 4 +- src/hooks/useValueTexts.ts | 10 ++--- src/interface.ts | 22 +++++----- src/locale/ar_EG.ts | 2 +- src/locale/az_AZ.ts | 2 +- src/locale/bg_BG.ts | 2 +- src/locale/by_BY.ts | 2 +- src/locale/ca_ES.ts | 2 +- src/locale/cs_CZ.ts | 2 +- src/locale/da_DK.ts | 2 +- src/locale/de_DE.ts | 2 +- src/locale/el_GR.ts | 2 +- src/locale/en_GB.ts | 2 +- src/locale/en_US.ts | 2 +- src/locale/es_ES.ts | 2 +- src/locale/et_EE.ts | 2 +- src/locale/fa_IR.ts | 2 +- src/locale/fi_FI.ts | 2 +- src/locale/fr_BE.ts | 2 +- src/locale/fr_FR.ts | 2 +- src/locale/ga_IE.ts | 2 +- src/locale/gl_ES.ts | 2 +- src/locale/he_IL.ts | 2 +- src/locale/hi_IN.ts | 2 +- src/locale/hr_HR.ts | 2 +- src/locale/hu_HU.ts | 2 +- src/locale/id_ID.ts | 2 +- src/locale/is_IS.ts | 2 +- src/locale/it_IT.ts | 2 +- src/locale/ja_JP.ts | 2 +- src/locale/kk_KZ.ts | 2 +- src/locale/kmr_IQ.ts | 2 +- src/locale/kn_IN.ts | 2 +- src/locale/ko_KR.ts | 2 +- src/locale/lt_LT.ts | 2 +- src/locale/lv_LV.ts | 2 +- src/locale/mk_MK.ts | 2 +- src/locale/mm_MM.ts | 2 +- src/locale/mn_MN.ts | 2 +- src/locale/ms_MY.ts | 2 +- src/locale/nb_NO.ts | 2 +- src/locale/nl_BE.ts | 2 +- src/locale/nl_NL.ts | 2 +- src/locale/pl_PL.ts | 2 +- src/locale/pt_BR.ts | 2 +- src/locale/pt_PT.ts | 2 +- src/locale/ro_RO.ts | 2 +- src/locale/ru_RU.ts | 2 +- src/locale/sk_SK.ts | 2 +- src/locale/sl_SI.ts | 2 +- src/locale/sr_RS.ts | 2 +- src/locale/sv_SE.ts | 2 +- src/locale/ta_IN.ts | 2 +- src/locale/th_TH.ts | 2 +- src/locale/tr_TR.ts | 2 +- src/locale/ug_CN.ts | 2 +- src/locale/uk_UA.ts | 2 +- src/locale/vi_VN.ts | 2 +- src/locale/zh_CN.ts | 2 +- src/locale/zh_TW.ts | 2 +- src/panels/DatePanel/DateBody.tsx | 12 +++--- src/panels/DatePanel/DateHeader.tsx | 8 ++-- src/panels/DatePanel/index.tsx | 14 +++---- src/panels/DatetimePanel/index.tsx | 21 +++++----- src/panels/DecadePanel/DecadeBody.tsx | 6 +-- src/panels/DecadePanel/DecadeHeader.tsx | 6 +-- src/panels/DecadePanel/index.tsx | 2 +- src/panels/Header.tsx | 4 +- src/panels/MonthPanel/MonthBody.tsx | 8 ++-- src/panels/MonthPanel/MonthHeader.tsx | 8 ++-- src/panels/MonthPanel/index.tsx | 9 ++-- src/panels/PanelBody.tsx | 8 ++-- src/panels/QuarterPanel/QuarterBody.tsx | 8 ++-- src/panels/QuarterPanel/QuarterHeader.tsx | 8 ++-- src/panels/QuarterPanel/index.tsx | 4 +- src/panels/TimePanel/TimeBody.tsx | 17 ++++---- src/panels/TimePanel/TimeHeader.tsx | 8 ++-- src/panels/TimePanel/TimeUnitColumn.tsx | 8 ++-- src/panels/TimePanel/index.tsx | 15 ++++--- src/panels/WeekPanel/index.tsx | 2 +- src/panels/YearPanel/YearBody.tsx | 8 ++-- src/panels/YearPanel/YearHeader.tsx | 6 +-- src/panels/YearPanel/index.tsx | 6 +-- src/utils/dateUtil.ts | 7 ++-- src/utils/getExtraFooter.tsx | 2 +- src/utils/getRanges.tsx | 6 +-- src/utils/timeUtil.ts | 2 +- src/utils/uiUtil.ts | 10 ++--- tests/picker.spec.tsx | 27 ++++++++++++ tsconfig.json | 11 +++++ 108 files changed, 345 insertions(+), 278 deletions(-) create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore index a4ff34388..bcd6c77a7 100644 --- a/.gitignore +++ b/.gitignore @@ -31,4 +31,3 @@ package-lock.json coverage/ .doc .history -tsconfig.json diff --git a/README.md b/README.md index 88a718a6d..d3b2e29ae 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# rc-picker +# rc-picker [![NPM version][npm-image]][npm-url] [![build status][github-actions-image]][github-actions-url] @@ -76,8 +76,9 @@ render(, mountNode); | getPopupContainer | function(trigger) | | to set the container of the floating layer, while the default is to create a div element in body | | onChange | Function(date: moment, dateString: string) | | a callback function, can be executed when the selected time is changing | | onOpenChange | Function(open:boolean) | | called when open/close picker | -| onFocus | (evnet:React.FocusEventHandler) => void | | called like input's on focus | -| onBlur | (evnet:React.FocusEventHandler) => void | | called like input's on blur | +| onFocus | (event:React.FocusEvent) => void | | called like input's on focus | +| onBlur | (event:React.FocusEvent) => void | | called like input's on blur | +| onKeyDown | (event:React.KeyboardEvent, preventDefault: () => void) => void | | input on keydown event | | direction | String: ltr or rtl | | Layout direction of picker component, it supports RTL direction too. | ### PickerPanel @@ -102,7 +103,7 @@ render(, mountNode); | renderExtraFooter | (mode) => React.Node | | extra footer | | onSelect | Function(date: moment) | | a callback function, can be executed when the selected time | | onPanelChange | Function(value: moment, mode) | | callback when picker panel mode is changed | -| onMouseDown | (evnet:React.MouseEventHandler) => void | | callback when executed onMouseDown evnent | +| onMouseDown | (event:React.MouseEvent) => void | | callback when executed onMouseDown evnent | | direction | String: ltr or rtl | | Layout direction of picker component, it supports RTL direction too. | ### RangePicker diff --git a/examples/basic.tsx b/examples/basic.tsx index 7885a2ec1..a68704a96 100644 --- a/examples/basic.tsx +++ b/examples/basic.tsx @@ -29,6 +29,10 @@ export default () => { onChange, }; + const keyDown = (e, preventDefault) => { + if (e.keyCode === 13) preventDefault(); + }; + return (

Value: {value ? value.format('YYYY-MM-DD HH:mm:ss') : 'null'}

@@ -125,6 +129,10 @@ export default () => {

Keyboard navigation (Tab key) disabled

{...sharedProps} locale={enUS} tabIndex={-1} />
+
+

Keyboard event with prevent default behaviors

+ {...sharedProps} locale={enUS} onKeyDown={keyDown} /> +
); diff --git a/package.json b/package.json index 75f96eace..e77df3831 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rc-picker", - "version": "2.4.3", + "version": "2.5.0", "description": "React date & time picker", "keywords": [ "react", diff --git a/src/PanelContext.tsx b/src/PanelContext.tsx index 0ed771d50..32bccae47 100644 --- a/src/PanelContext.tsx +++ b/src/PanelContext.tsx @@ -1,12 +1,12 @@ import * as React from 'react'; -import { OnSelect, PanelMode } from './interface'; +import type { OnSelect, PanelMode } from './interface'; export type ContextOperationRefProps = { onKeyDown?: (e: React.KeyboardEvent) => boolean; onClose?: () => void; }; -export interface PanelContextProps { +export type PanelContextProps = { operationRef?: React.MutableRefObject; /** Only work with time panel */ hideHeader?: boolean; @@ -22,7 +22,7 @@ export interface PanelContextProps { /** Only used for TimePicker and this is a deprecated prop */ defaultOpenValue?: any; -} +}; const PanelContext = React.createContext({}); diff --git a/src/Picker.tsx b/src/Picker.tsx index 128348ced..b404dd70f 100644 --- a/src/Picker.tsx +++ b/src/Picker.tsx @@ -13,31 +13,33 @@ import * as React from 'react'; import classNames from 'classnames'; -import { AlignType } from 'rc-trigger/lib/interface'; +import type { AlignType } from 'rc-trigger/lib/interface'; import warning from 'rc-util/lib/warning'; import useMergedState from 'rc-util/lib/hooks/useMergedState'; -import PickerPanel, { +import type { PickerPanelBaseProps, PickerPanelDateProps, PickerPanelTimeProps, } from './PickerPanel'; +import PickerPanel from './PickerPanel'; import PickerTrigger from './PickerTrigger'; import { formatValue, isEqual, parseValue } from './utils/dateUtil'; import getDataOrAriaProps, { toArray } from './utils/miscUtil'; -import PanelContext, { ContextOperationRefProps } from './PanelContext'; -import { CustomFormat, PickerMode } from './interface'; +import type { ContextOperationRefProps } from './PanelContext'; +import PanelContext from './PanelContext'; +import type { CustomFormat, PickerMode } from './interface'; import { getDefaultFormat, getInputSize, elementsContains } from './utils/uiUtil'; import usePickerInput from './hooks/usePickerInput'; import useTextValueMapping from './hooks/useTextValueMapping'; import useValueTexts from './hooks/useValueTexts'; import useHoverValue from './hooks/useHoverValue'; -export interface PickerRefConfig { +export type PickerRefConfig = { focus: () => void; blur: () => void; -} +}; -export interface PickerSharedProps extends React.AriaAttributes { +export type PickerSharedProps = { dropdownClassName?: string; dropdownAlign?: AlignType; popupStyle?: React.CSSProperties; @@ -54,7 +56,7 @@ export interface PickerSharedProps extends React.AriaAttributes { id?: string; // Value - format?: string | CustomFormat | Array>; + format?: string | CustomFormat | (string | CustomFormat)[]; // Render suffixIcon?: React.ReactNode; @@ -77,6 +79,7 @@ export interface PickerSharedProps extends React.AriaAttributes { onMouseLeave?: React.MouseEventHandler; onClick?: React.MouseEventHandler; onContextMenu?: React.MouseEventHandler; + onKeyDown?: (event: React.KeyboardEvent, preventDefault: () => void) => void; // Internal /** @private Internal usage, do not use in production mode!!! */ @@ -88,31 +91,25 @@ export interface PickerSharedProps extends React.AriaAttributes { autoComplete?: string; direction?: 'ltr' | 'rtl'; -} +} & React.AriaAttributes; type OmitPanelProps = Omit< Props, 'onChange' | 'hideHeader' | 'pickerValue' | 'onPickerValueChange' >; -export interface PickerBaseProps - extends PickerSharedProps, - OmitPanelProps> {} +export type PickerBaseProps = {} & PickerSharedProps & OmitPanelProps>; -export interface PickerDateProps - extends PickerSharedProps, - OmitPanelProps> {} +export type PickerDateProps = {} & PickerSharedProps & OmitPanelProps>; -export interface PickerTimeProps - extends PickerSharedProps, - Omit>, 'format'> { +export type PickerTimeProps = { picker: 'time'; /** * @deprecated Please use `defaultValue` directly instead * since `defaultOpenValue` will confuse user of current value status */ defaultOpenValue?: DateType; -} +} & PickerSharedProps & Omit>, 'format'>; export type PickerProps = | PickerBaseProps @@ -123,9 +120,9 @@ export type PickerProps = type OmitType = Omit, 'picker'> & Omit, 'picker'> & Omit, 'picker'>; -interface MergedPickerProps extends OmitType { +type MergedPickerProps = { picker?: PickerMode; -} +} & OmitType; function InnerPicker(props: PickerProps) { const { @@ -170,6 +167,7 @@ function InnerPicker(props: PickerProps) { onMouseLeave, onContextMenu, onClick, + onKeyDown, onSelect, direction, autoComplete = 'off', @@ -310,6 +308,9 @@ function InnerPicker(props: PickerProps) { setSelectedValue(mergedValue); resetText(); }, + onKeyDown: (e, preventDefault) => { + onKeyDown?.(e, preventDefault); + }, onFocus, onBlur, }); diff --git a/src/PickerPanel.tsx b/src/PickerPanel.tsx index deda606c6..1dcdac8eb 100644 --- a/src/PickerPanel.tsx +++ b/src/PickerPanel.tsx @@ -1,5 +1,3 @@ -/* eslint-disable jsx-a11y/no-noninteractive-tabindex */ - /** * Logic: * When `mode` === `picker`, @@ -12,7 +10,8 @@ import classNames from 'classnames'; import KeyCode from 'rc-util/lib/KeyCode'; import warning from 'rc-util/lib/warning'; import useMergedState from 'rc-util/lib/hooks/useMergedState'; -import TimePanel, { SharedTimeProps } from './panels/TimePanel'; +import type { SharedTimeProps } from './panels/TimePanel'; +import TimePanel from './panels/TimePanel'; import DatetimePanel from './panels/DatetimePanel'; import DatePanel from './panels/DatePanel'; import WeekPanel from './panels/WeekPanel'; @@ -20,8 +19,8 @@ import MonthPanel from './panels/MonthPanel'; import QuarterPanel from './panels/QuarterPanel'; import YearPanel from './panels/YearPanel'; import DecadePanel from './panels/DecadePanel'; -import { GenerateConfig } from './generate'; -import { +import type { GenerateConfig } from './generate'; +import type { Locale, PanelMode, PanelRefProps, @@ -32,15 +31,15 @@ import { } from './interface'; import { isEqual } from './utils/dateUtil'; import PanelContext from './PanelContext'; -import { DateRender } from './panels/DatePanel/DateBody'; +import type { DateRender } from './panels/DatePanel/DateBody'; import { PickerModeMap } from './utils/uiUtil'; -import { MonthCellRender } from './panels/MonthPanel/MonthBody'; +import type { MonthCellRender } from './panels/MonthPanel/MonthBody'; import RangeContext from './RangeContext'; import getExtraFooter from './utils/getExtraFooter'; import getRanges from './utils/getRanges'; import { getLowerBoundTime, setTime } from './utils/timeUtil'; -export interface PickerPanelSharedProps { +export type PickerPanelSharedProps = { prefixCls?: string; className?: string; style?: React.CSSProperties; @@ -84,13 +83,13 @@ export interface PickerPanelSharedProps { /** @private Internal usage. Do not use in your production env */ components?: Components; -} +}; -export interface PickerPanelBaseProps extends PickerPanelSharedProps { +export type PickerPanelBaseProps = { picker: Exclude; -} +} & PickerPanelSharedProps; -export interface PickerPanelDateProps extends PickerPanelSharedProps { +export type PickerPanelDateProps = { picker?: 'date'; showToday?: boolean; showNow?: boolean; @@ -98,13 +97,11 @@ export interface PickerPanelDateProps extends PickerPanelSharedProps; disabledTime?: DisabledTime; -} +} & PickerPanelSharedProps; -export interface PickerPanelTimeProps - extends PickerPanelSharedProps, - SharedTimeProps { +export type PickerPanelTimeProps = { picker: 'time'; -} +} & PickerPanelSharedProps & SharedTimeProps; export type PickerPanelProps = | PickerPanelBaseProps @@ -115,9 +112,9 @@ export type PickerPanelProps = type OmitType = Omit, 'picker'> & Omit, 'picker'> & Omit, 'picker'>; -interface MergedPickerPanelProps extends OmitType { +type MergedPickerPanelProps = { picker?: PickerMode; -} +} & OmitType; function PickerPanel(props: PickerPanelProps) { const { diff --git a/src/PickerTrigger.tsx b/src/PickerTrigger.tsx index ccf9e5d9b..d942442e1 100644 --- a/src/PickerTrigger.tsx +++ b/src/PickerTrigger.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import classNames from 'classnames'; import Trigger from 'rc-trigger'; -import { AlignType } from 'rc-trigger/lib/interface'; +import type { AlignType } from 'rc-trigger/lib/interface'; const BUILT_IN_PLACEMENTS = { bottomLeft: { @@ -40,7 +40,7 @@ const BUILT_IN_PLACEMENTS = { type Placement = 'bottomLeft' | 'bottomRight' | 'topLeft' | 'topRight'; -export interface PickerTriggerProps { +export type PickerTriggerProps = { prefixCls: string; visible: boolean; popupElement: React.ReactElement; @@ -53,7 +53,7 @@ export interface PickerTriggerProps { range?: boolean; popupPlacement?: Placement; direction?: 'ltr' | 'rtl'; -} +}; function PickerTrigger({ prefixCls, diff --git a/src/RangeContext.tsx b/src/RangeContext.tsx index 77f641cac..f3747de38 100644 --- a/src/RangeContext.tsx +++ b/src/RangeContext.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; -import { NullableDateType, RangeValue } from './interface'; +import type { NullableDateType, RangeValue } from './interface'; -export interface RangeContextProps { +export type RangeContextProps = { /** * Set displayed range value style. * Panel only has one value, this is only style effect. @@ -10,7 +10,7 @@ export interface RangeContextProps { hoverRangedValue?: RangeValue; inRange?: boolean; panelPosition?: 'left' | 'right' | false; -} +}; const RangeContext = React.createContext({}); diff --git a/src/RangePicker.tsx b/src/RangePicker.tsx index 1154cf3fc..774e3e795 100644 --- a/src/RangePicker.tsx +++ b/src/RangePicker.tsx @@ -3,15 +3,16 @@ import { useRef, useEffect, useState } from 'react'; import classNames from 'classnames'; import warning from 'rc-util/lib/warning'; import useMergedState from 'rc-util/lib/hooks/useMergedState'; -import { DisabledTimes, PanelMode, PickerMode, RangeValue, EventValue } from './interface'; -import { PickerBaseProps, PickerDateProps, PickerTimeProps, PickerRefConfig } from './Picker'; -import { SharedTimeProps } from './panels/TimePanel'; +import type { DisabledTimes, PanelMode, PickerMode, RangeValue, EventValue } from './interface'; +import type { PickerBaseProps, PickerDateProps, PickerTimeProps, PickerRefConfig } from './Picker'; +import type { SharedTimeProps } from './panels/TimePanel'; import PickerTrigger from './PickerTrigger'; import PickerPanel from './PickerPanel'; import usePickerInput from './hooks/usePickerInput'; import getDataOrAriaProps, { toArray, getValue, updateValues } from './utils/miscUtil'; import { getDefaultFormat, getInputSize, elementsContains } from './utils/uiUtil'; -import PanelContext, { ContextOperationRefProps } from './PanelContext'; +import type { ContextOperationRefProps } from './PanelContext'; +import PanelContext from './PanelContext'; import { isEqual, getClosingViewDate, @@ -23,14 +24,14 @@ import { } from './utils/dateUtil'; import useValueTexts from './hooks/useValueTexts'; import useTextValueMapping from './hooks/useTextValueMapping'; -import { GenerateConfig } from './generate'; -import { PickerPanelProps } from '.'; +import type { GenerateConfig } from './generate'; +import type { PickerPanelProps } from '.'; import RangeContext from './RangeContext'; import useRangeDisabled from './hooks/useRangeDisabled'; import getExtraFooter from './utils/getExtraFooter'; import getRanges from './utils/getRanges'; import useRangeViewDates from './hooks/useRangeViewDates'; -import { DateRender } from './panels/DatePanel/DateBody'; +import type { DateRender } from './panels/DatePanel/DateBody'; import useHoverValue from './hooks/useHoverValue'; function reorderValues( @@ -67,9 +68,9 @@ function canValueTrigger( export type RangeType = 'start' | 'end'; -export interface RangeInfo { +export type RangeInfo = { range: RangeType; -} +}; export type RangeDateRender = ( currentDate: DateType, @@ -77,7 +78,7 @@ export type RangeDateRender = ( info: RangeInfo, ) => React.ReactNode; -export interface RangePickerSharedProps { +export type RangePickerSharedProps = { id?: string; value?: RangeValue; defaultValue?: RangeValue; @@ -108,7 +109,7 @@ export interface RangePickerSharedProps { activePickerIndex?: 0 | 1; dateRender?: RangeDateRender; panelRender?: (originPanel: React.ReactNode) => React.ReactNode; -} +}; type OmitPickerProps = Omit< Props, @@ -134,21 +135,15 @@ type RangeShowTimeObject = Omit, 'defaultVal defaultValue?: DateType[]; }; -export interface RangePickerBaseProps - extends RangePickerSharedProps, - OmitPickerProps> {} +export type RangePickerBaseProps = {} & RangePickerSharedProps & OmitPickerProps>; -export interface RangePickerDateProps - extends RangePickerSharedProps, - OmitPickerProps> { +export type RangePickerDateProps = { showTime?: boolean | RangeShowTimeObject; -} +} & RangePickerSharedProps & OmitPickerProps>; -export interface RangePickerTimeProps - extends RangePickerSharedProps, - OmitPickerProps> { +export type RangePickerTimeProps = { order?: boolean; -} +} & RangePickerSharedProps & OmitPickerProps>; export type RangePickerProps = | RangePickerBaseProps @@ -160,9 +155,9 @@ type OmitType = Omit, 'picker'> & Omit, 'picker'> & Omit, 'picker'>; -interface MergedRangePickerProps extends OmitType { +type MergedRangePickerProps = { picker?: PickerMode; -} +} & OmitType; function InnerRangePicker(props: RangePickerProps) { const { @@ -210,6 +205,7 @@ function InnerRangePicker(props: RangePickerProps) { onFocus, onBlur, onOk, + onKeyDown, components, order, direction, @@ -610,12 +606,18 @@ function InnerRangePicker(props: RangePickerProps) { ...getSharedInputHookProps(0, resetStartText), open: startOpen, value: startText, + onKeyDown: (e, preventDefault) => { + onKeyDown?.(e, preventDefault); + }, }); const [endInputProps, { focused: endFocused, typing: endTyping }] = usePickerInput({ ...getSharedInputHookProps(1, resetEndText), open: endOpen, value: endText, + onKeyDown: (e, preventDefault) => { + onKeyDown?.(e, preventDefault); + }, }); // ========================== Click Picker ========================== diff --git a/src/generate/dateFns.ts b/src/generate/dateFns.ts index 06ff8ce7d..196f8d7ec 100644 --- a/src/generate/dateFns.ts +++ b/src/generate/dateFns.ts @@ -24,7 +24,7 @@ import { parse as parseDate, } from 'date-fns'; import * as Locale from 'date-fns/locale'; -import { GenerateConfig } from '.'; +import type { GenerateConfig } from '.'; const dealLocal = (str: string) => { return str.replace(/_/g, ''); diff --git a/src/generate/dayjs.ts b/src/generate/dayjs.ts index b8560dd67..b1d888ce7 100644 --- a/src/generate/dayjs.ts +++ b/src/generate/dayjs.ts @@ -1,4 +1,5 @@ -import dayjs, { Dayjs } from 'dayjs'; +import type { Dayjs } from 'dayjs'; +import dayjs from 'dayjs'; import { noteOnce } from 'rc-util/lib/warning'; import weekday from 'dayjs/plugin/weekday'; import localeData from 'dayjs/plugin/localeData'; @@ -6,7 +7,7 @@ import weekOfYear from 'dayjs/plugin/weekOfYear'; import weekYear from 'dayjs/plugin/weekYear'; import advancedFormat from 'dayjs/plugin/advancedFormat'; import customParseFormat from 'dayjs/plugin/customParseFormat'; -import { GenerateConfig } from '.'; +import type { GenerateConfig } from '.'; dayjs.extend(customParseFormat); dayjs.extend(advancedFormat); @@ -25,7 +26,7 @@ dayjs.extend((o, c) => { }; }); -type IlocaleMapObject = { [key: string]: string }; +type IlocaleMapObject = Record; const localeMap: IlocaleMapObject = { en_GB: 'en-gb', en_US: 'en', diff --git a/src/generate/index.ts b/src/generate/index.ts index 7f7429594..b0cd56d5e 100644 --- a/src/generate/index.ts +++ b/src/generate/index.ts @@ -1,4 +1,4 @@ -export interface GenerateConfig { +export type GenerateConfig = { // Get getWeekDay: (value: DateType) => number; getSecond: (value: DateType) => number; @@ -41,4 +41,4 @@ export interface GenerateConfig { /** A proxy for getting locale with moment or other locale library */ getShortMonths?: (locale: string) => string[]; }; -} +}; diff --git a/src/generate/moment.ts b/src/generate/moment.ts index 4af057e16..62a0538fc 100644 --- a/src/generate/moment.ts +++ b/src/generate/moment.ts @@ -1,6 +1,7 @@ -import moment, { Moment } from 'moment'; +import type { Moment } from 'moment'; +import moment from 'moment'; import { noteOnce } from 'rc-util/lib/warning'; -import { GenerateConfig } from '.'; +import type { GenerateConfig } from '.'; const generateConfig: GenerateConfig = { // get diff --git a/src/hooks/useCellClassName.ts b/src/hooks/useCellClassName.ts index 251e1ebc1..7aeb2b5f7 100644 --- a/src/hooks/useCellClassName.ts +++ b/src/hooks/useCellClassName.ts @@ -1,6 +1,6 @@ import { isInRange } from '../utils/dateUtil'; -import { GenerateConfig } from '../generate'; -import { RangeValue, NullableDateType } from '../interface'; +import type { GenerateConfig } from '../generate'; +import type { RangeValue, NullableDateType } from '../interface'; import { getValue } from '../utils/miscUtil'; export default function useCellClassName({ diff --git a/src/hooks/useHoverValue.ts b/src/hooks/useHoverValue.ts index 0ff4f389b..e24cda03e 100644 --- a/src/hooks/useHoverValue.ts +++ b/src/hooks/useHoverValue.ts @@ -1,5 +1,6 @@ import { useState, useEffect, useRef } from 'react'; -import useValueTexts, { ValueTextConfig } from './useValueTexts'; +import type { ValueTextConfig } from './useValueTexts'; +import useValueTexts from './useValueTexts'; export default function useHoverValue( valueText: string, diff --git a/src/hooks/usePickerInput.ts b/src/hooks/usePickerInput.ts index 9903baff3..b08ed6389 100644 --- a/src/hooks/usePickerInput.ts +++ b/src/hooks/usePickerInput.ts @@ -1,4 +1,4 @@ -import * as React from 'react'; +import type * as React from 'react'; import { useState, useEffect, useRef } from 'react'; import KeyCode from 'rc-util/lib/KeyCode'; import { addGlobalMouseDownEvent } from '../utils/uiUtil'; @@ -9,6 +9,7 @@ export default function usePickerInput({ isClickOutside, triggerOpen, forwardKeyDown, + onKeyDown, blurToCancel, onSubmit, onCancel, @@ -20,6 +21,10 @@ export default function usePickerInput({ isClickOutside: (clickElement: EventTarget | null) => boolean; triggerOpen: (open: boolean) => void; forwardKeyDown: (e: React.KeyboardEvent) => boolean; + onKeyDown: ( + e: React.KeyboardEvent, + preventDefault: () => void, + ) => void; blurToCancel?: boolean; onSubmit: () => void | boolean; onCancel: () => void; @@ -37,12 +42,22 @@ export default function usePickerInput({ const valueChangedRef = useRef(false); + const preventDefaultRef = useRef(false); + const inputProps: React.DOMAttributes = { onMouseDown: () => { setTyping(true); triggerOpen(true); }, onKeyDown: e => { + const preventDefault = (): void => { + preventDefaultRef.current = true; + }; + + onKeyDown(e, preventDefault); + + if (preventDefaultRef.current) return; + switch (e.which) { case KeyCode.ENTER: { if (!open) { diff --git a/src/hooks/useRangeDisabled.ts b/src/hooks/useRangeDisabled.ts index 1bbe585d6..c01b81673 100644 --- a/src/hooks/useRangeDisabled.ts +++ b/src/hooks/useRangeDisabled.ts @@ -1,7 +1,7 @@ import * as React from 'react'; -import { RangeValue, PickerMode, Locale } from '../interface'; +import type { RangeValue, PickerMode, Locale } from '../interface'; import { getValue } from '../utils/miscUtil'; -import { GenerateConfig } from '../generate'; +import type { GenerateConfig } from '../generate'; import { isSameDate, getQuarter } from '../utils/dateUtil'; export default function useRangeDisabled( diff --git a/src/hooks/useRangeViewDates.ts b/src/hooks/useRangeViewDates.ts index e68681fa0..df6e63453 100644 --- a/src/hooks/useRangeViewDates.ts +++ b/src/hooks/useRangeViewDates.ts @@ -1,6 +1,6 @@ import * as React from 'react'; -import { RangeValue, PickerMode } from '../interface'; -import { GenerateConfig } from '../generate'; +import type { RangeValue, PickerMode } from '../interface'; +import type { GenerateConfig } from '../generate'; import { getValue, updateValues } from '../utils/miscUtil'; import { getClosingViewDate, isSameYear, isSameMonth, isSameDecade } from '../utils/dateUtil'; diff --git a/src/hooks/useValueTexts.ts b/src/hooks/useValueTexts.ts index d796ebf26..89f01f5d9 100644 --- a/src/hooks/useValueTexts.ts +++ b/src/hooks/useValueTexts.ts @@ -1,14 +1,14 @@ import shallowEqual from 'shallowequal'; import useMemo from 'rc-util/lib/hooks/useMemo'; -import { GenerateConfig } from '../generate'; -import { CustomFormat, Locale } from '../interface'; +import type { GenerateConfig } from '../generate'; +import type { CustomFormat, Locale } from '../interface'; import { formatValue } from '../utils/dateUtil'; -export interface ValueTextConfig { - formatList: Array>; +export type ValueTextConfig = { + formatList: (string | CustomFormat)[]; generateConfig: GenerateConfig; locale: Locale; -} +}; export default function useValueTexts( value: DateType | null, diff --git a/src/interface.ts b/src/interface.ts index 530b821fd..ef362e223 100644 --- a/src/interface.ts +++ b/src/interface.ts @@ -1,6 +1,6 @@ -import { GenerateConfig } from './generate'; +import type { GenerateConfig } from './generate'; -export interface Locale { +export type Locale = { locale: string; // ===================== Date Panel ===================== @@ -38,23 +38,23 @@ export interface Locale { shortWeekDays?: string[]; shortMonths?: string[]; -} +}; export type PanelMode = 'time' | 'date' | 'week' | 'month' | 'quarter' | 'year' | 'decade'; export type PickerMode = Exclude; -export interface PanelRefProps { +export type PanelRefProps = { onKeyDown?: (e: React.KeyboardEvent) => boolean; onBlur?: React.FocusEventHandler; onClose?: () => void; -} +}; export type NullableDateType = DateType | null | undefined; export type OnSelect = (value: DateType, type: 'key' | 'mouse' | 'submit') => void; -export interface PanelSharedProps { +export type PanelSharedProps = { prefixCls: string; generateConfig: GenerateConfig; value?: NullableDateType; @@ -79,13 +79,13 @@ export interface PanelSharedProps { onSelect: OnSelect; onViewDateChange: (value: DateType) => void; onPanelChange: (mode: PanelMode | null, viewValue: DateType) => void; -} +}; -export interface DisabledTimes { +export type DisabledTimes = { disabledHours?: () => number[]; disabledMinutes?: (hour: number) => number[]; disabledSeconds?: (hour: number, minute: number) => number[]; -} +}; export type DisabledTime = (date: DateType | null) => DisabledTimes; @@ -94,10 +94,10 @@ export type OnPanelChange = (value: DateType, mode: PanelMode) => void export type EventValue = DateType | null; export type RangeValue = [EventValue, EventValue] | null; -export interface Components { +export type Components = { button?: React.ComponentType | string; rangeItem?: React.ComponentType | string; -} +}; export type RangeList = { label: string; diff --git a/src/locale/ar_EG.ts b/src/locale/ar_EG.ts index 5ec73c13c..14e9b6b27 100644 --- a/src/locale/ar_EG.ts +++ b/src/locale/ar_EG.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'ar_EG', diff --git a/src/locale/az_AZ.ts b/src/locale/az_AZ.ts index 123fb9765..a499805bc 100644 --- a/src/locale/az_AZ.ts +++ b/src/locale/az_AZ.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'az_AZ', diff --git a/src/locale/bg_BG.ts b/src/locale/bg_BG.ts index bcc4bc1d7..07334a91d 100644 --- a/src/locale/bg_BG.ts +++ b/src/locale/bg_BG.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'bg_BG', diff --git a/src/locale/by_BY.ts b/src/locale/by_BY.ts index ea25e4275..3339d970b 100644 --- a/src/locale/by_BY.ts +++ b/src/locale/by_BY.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'by_BY', diff --git a/src/locale/ca_ES.ts b/src/locale/ca_ES.ts index 56236d5cc..f93f09397 100644 --- a/src/locale/ca_ES.ts +++ b/src/locale/ca_ES.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'ca_ES', diff --git a/src/locale/cs_CZ.ts b/src/locale/cs_CZ.ts index cce049f1d..3c1b2eb3c 100644 --- a/src/locale/cs_CZ.ts +++ b/src/locale/cs_CZ.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'cs_CZ', diff --git a/src/locale/da_DK.ts b/src/locale/da_DK.ts index 18d692cf2..f3fe17c6e 100644 --- a/src/locale/da_DK.ts +++ b/src/locale/da_DK.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'da_DK', diff --git a/src/locale/de_DE.ts b/src/locale/de_DE.ts index 948e0b4ca..e053a6302 100644 --- a/src/locale/de_DE.ts +++ b/src/locale/de_DE.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'de_DE', diff --git a/src/locale/el_GR.ts b/src/locale/el_GR.ts index 7b446e6cb..e8979a57a 100644 --- a/src/locale/el_GR.ts +++ b/src/locale/el_GR.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'el_GR', diff --git a/src/locale/en_GB.ts b/src/locale/en_GB.ts index 5b4afdc47..a875ae257 100644 --- a/src/locale/en_GB.ts +++ b/src/locale/en_GB.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'en_GB', diff --git a/src/locale/en_US.ts b/src/locale/en_US.ts index d0c289888..28d5fad58 100644 --- a/src/locale/en_US.ts +++ b/src/locale/en_US.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'en_US', diff --git a/src/locale/es_ES.ts b/src/locale/es_ES.ts index 765cda6f1..373db7dbf 100644 --- a/src/locale/es_ES.ts +++ b/src/locale/es_ES.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'es_ES', diff --git a/src/locale/et_EE.ts b/src/locale/et_EE.ts index 81518508e..19a4af593 100644 --- a/src/locale/et_EE.ts +++ b/src/locale/et_EE.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'et_EE', diff --git a/src/locale/fa_IR.ts b/src/locale/fa_IR.ts index ae81ee013..f7e1af3b5 100644 --- a/src/locale/fa_IR.ts +++ b/src/locale/fa_IR.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'fa_IR', diff --git a/src/locale/fi_FI.ts b/src/locale/fi_FI.ts index e676ce343..9a02113bf 100644 --- a/src/locale/fi_FI.ts +++ b/src/locale/fi_FI.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'fi_FI', diff --git a/src/locale/fr_BE.ts b/src/locale/fr_BE.ts index 5bba781fa..b39864474 100644 --- a/src/locale/fr_BE.ts +++ b/src/locale/fr_BE.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'fr_BE', diff --git a/src/locale/fr_FR.ts b/src/locale/fr_FR.ts index cf28d73b3..53239b592 100644 --- a/src/locale/fr_FR.ts +++ b/src/locale/fr_FR.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'fr_FR', diff --git a/src/locale/ga_IE.ts b/src/locale/ga_IE.ts index 7e37306a6..326a209bd 100644 --- a/src/locale/ga_IE.ts +++ b/src/locale/ga_IE.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'ga_IE', diff --git a/src/locale/gl_ES.ts b/src/locale/gl_ES.ts index 620ab5467..13258764e 100644 --- a/src/locale/gl_ES.ts +++ b/src/locale/gl_ES.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'gl_ES', diff --git a/src/locale/he_IL.ts b/src/locale/he_IL.ts index 14dcdf354..ea3fc8b73 100644 --- a/src/locale/he_IL.ts +++ b/src/locale/he_IL.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'he_IL', diff --git a/src/locale/hi_IN.ts b/src/locale/hi_IN.ts index dc2d458a7..51ae22917 100644 --- a/src/locale/hi_IN.ts +++ b/src/locale/hi_IN.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'hi_IN', diff --git a/src/locale/hr_HR.ts b/src/locale/hr_HR.ts index 2b3395c66..a341396b5 100644 --- a/src/locale/hr_HR.ts +++ b/src/locale/hr_HR.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'hr_HR', diff --git a/src/locale/hu_HU.ts b/src/locale/hu_HU.ts index 70731d5dd..b98603dc8 100644 --- a/src/locale/hu_HU.ts +++ b/src/locale/hu_HU.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'hu_HU', diff --git a/src/locale/id_ID.ts b/src/locale/id_ID.ts index 379432d84..01c9d760b 100644 --- a/src/locale/id_ID.ts +++ b/src/locale/id_ID.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'id_ID', diff --git a/src/locale/is_IS.ts b/src/locale/is_IS.ts index 3e7262f47..efea36701 100644 --- a/src/locale/is_IS.ts +++ b/src/locale/is_IS.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'is_IS', diff --git a/src/locale/it_IT.ts b/src/locale/it_IT.ts index f422183b7..3b69a9f2f 100644 --- a/src/locale/it_IT.ts +++ b/src/locale/it_IT.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'it_IT', diff --git a/src/locale/ja_JP.ts b/src/locale/ja_JP.ts index 09f72373f..f4d3985f9 100644 --- a/src/locale/ja_JP.ts +++ b/src/locale/ja_JP.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'ja_JP', diff --git a/src/locale/kk_KZ.ts b/src/locale/kk_KZ.ts index f0101112c..f3b6787ff 100644 --- a/src/locale/kk_KZ.ts +++ b/src/locale/kk_KZ.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'kk_KZ', diff --git a/src/locale/kmr_IQ.ts b/src/locale/kmr_IQ.ts index d514fa50e..867ec68b0 100644 --- a/src/locale/kmr_IQ.ts +++ b/src/locale/kmr_IQ.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'ku', diff --git a/src/locale/kn_IN.ts b/src/locale/kn_IN.ts index ef2468d82..1731ebdaf 100644 --- a/src/locale/kn_IN.ts +++ b/src/locale/kn_IN.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'kn_IN', diff --git a/src/locale/ko_KR.ts b/src/locale/ko_KR.ts index 55dbbacc9..6f8416c7e 100644 --- a/src/locale/ko_KR.ts +++ b/src/locale/ko_KR.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'ko_KR', diff --git a/src/locale/lt_LT.ts b/src/locale/lt_LT.ts index f7ebab8ce..2ddb658c7 100644 --- a/src/locale/lt_LT.ts +++ b/src/locale/lt_LT.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'lt_LT', diff --git a/src/locale/lv_LV.ts b/src/locale/lv_LV.ts index 6f7926197..0529ff639 100644 --- a/src/locale/lv_LV.ts +++ b/src/locale/lv_LV.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'lv_LV', diff --git a/src/locale/mk_MK.ts b/src/locale/mk_MK.ts index 85d71aea5..d1dd459ab 100644 --- a/src/locale/mk_MK.ts +++ b/src/locale/mk_MK.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'mk_MK', diff --git a/src/locale/mm_MM.ts b/src/locale/mm_MM.ts index 0aa0c6fa4..b6a824156 100644 --- a/src/locale/mm_MM.ts +++ b/src/locale/mm_MM.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'mm_MM', diff --git a/src/locale/mn_MN.ts b/src/locale/mn_MN.ts index ac88441a5..3b9e2ef7d 100644 --- a/src/locale/mn_MN.ts +++ b/src/locale/mn_MN.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'mn_MN', diff --git a/src/locale/ms_MY.ts b/src/locale/ms_MY.ts index 48c05cbc6..1e3784c9e 100644 --- a/src/locale/ms_MY.ts +++ b/src/locale/ms_MY.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'ms_MY', diff --git a/src/locale/nb_NO.ts b/src/locale/nb_NO.ts index b7a116f70..a2ce4ea64 100644 --- a/src/locale/nb_NO.ts +++ b/src/locale/nb_NO.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'nb_NO', diff --git a/src/locale/nl_BE.ts b/src/locale/nl_BE.ts index fc6f2d0e5..e78fef000 100644 --- a/src/locale/nl_BE.ts +++ b/src/locale/nl_BE.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'nl_BE', diff --git a/src/locale/nl_NL.ts b/src/locale/nl_NL.ts index e608948dd..cb33549e5 100644 --- a/src/locale/nl_NL.ts +++ b/src/locale/nl_NL.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'nl_NL', diff --git a/src/locale/pl_PL.ts b/src/locale/pl_PL.ts index ac963caa5..d37f20f8f 100644 --- a/src/locale/pl_PL.ts +++ b/src/locale/pl_PL.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'pl_PL', diff --git a/src/locale/pt_BR.ts b/src/locale/pt_BR.ts index 0442d4bfc..55de9610f 100644 --- a/src/locale/pt_BR.ts +++ b/src/locale/pt_BR.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'pt_BR', diff --git a/src/locale/pt_PT.ts b/src/locale/pt_PT.ts index 498f3fc0f..86a9a64cc 100644 --- a/src/locale/pt_PT.ts +++ b/src/locale/pt_PT.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'pt_PT', diff --git a/src/locale/ro_RO.ts b/src/locale/ro_RO.ts index 832d5ab20..7994b7bee 100644 --- a/src/locale/ro_RO.ts +++ b/src/locale/ro_RO.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'ro_RO', diff --git a/src/locale/ru_RU.ts b/src/locale/ru_RU.ts index b3897282c..0b53b1a54 100644 --- a/src/locale/ru_RU.ts +++ b/src/locale/ru_RU.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'ru_RU', diff --git a/src/locale/sk_SK.ts b/src/locale/sk_SK.ts index f7ad4bbb4..997f55e4f 100644 --- a/src/locale/sk_SK.ts +++ b/src/locale/sk_SK.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'sk_SK', diff --git a/src/locale/sl_SI.ts b/src/locale/sl_SI.ts index fe710142c..4af01844f 100644 --- a/src/locale/sl_SI.ts +++ b/src/locale/sl_SI.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'sl_SI', diff --git a/src/locale/sr_RS.ts b/src/locale/sr_RS.ts index 5c5b25dfe..d77eb97a4 100644 --- a/src/locale/sr_RS.ts +++ b/src/locale/sr_RS.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'sr_RS', diff --git a/src/locale/sv_SE.ts b/src/locale/sv_SE.ts index ecba2a958..c42c29cc0 100644 --- a/src/locale/sv_SE.ts +++ b/src/locale/sv_SE.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'sv_SE', diff --git a/src/locale/ta_IN.ts b/src/locale/ta_IN.ts index 53d287c4b..7f0e30568 100644 --- a/src/locale/ta_IN.ts +++ b/src/locale/ta_IN.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'ta_IN', diff --git a/src/locale/th_TH.ts b/src/locale/th_TH.ts index 0c36ce24a..bcc1c42ab 100644 --- a/src/locale/th_TH.ts +++ b/src/locale/th_TH.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'th_TH', diff --git a/src/locale/tr_TR.ts b/src/locale/tr_TR.ts index 8ed0f8b9f..f2f10540b 100644 --- a/src/locale/tr_TR.ts +++ b/src/locale/tr_TR.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'tr_TR', diff --git a/src/locale/ug_CN.ts b/src/locale/ug_CN.ts index 88db861fa..4e0241671 100644 --- a/src/locale/ug_CN.ts +++ b/src/locale/ug_CN.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'ug_CN', diff --git a/src/locale/uk_UA.ts b/src/locale/uk_UA.ts index d9892b2b8..eb56087fe 100644 --- a/src/locale/uk_UA.ts +++ b/src/locale/uk_UA.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'uk_UA', diff --git a/src/locale/vi_VN.ts b/src/locale/vi_VN.ts index 5939dbc6c..75302e70e 100644 --- a/src/locale/vi_VN.ts +++ b/src/locale/vi_VN.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'vi_VN', diff --git a/src/locale/zh_CN.ts b/src/locale/zh_CN.ts index 3f48d38bc..0b0495bae 100644 --- a/src/locale/zh_CN.ts +++ b/src/locale/zh_CN.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'zh_CN', diff --git a/src/locale/zh_TW.ts b/src/locale/zh_TW.ts index 41456f08b..47bd3b03a 100644 --- a/src/locale/zh_TW.ts +++ b/src/locale/zh_TW.ts @@ -1,4 +1,4 @@ -import { Locale } from '../interface'; +import type { Locale } from '../interface'; const locale: Locale = { locale: 'zh_TW', diff --git a/src/panels/DatePanel/DateBody.tsx b/src/panels/DatePanel/DateBody.tsx index 6639bea64..d0df6788b 100644 --- a/src/panels/DatePanel/DateBody.tsx +++ b/src/panels/DatePanel/DateBody.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { GenerateConfig } from '../../generate'; +import type { GenerateConfig } from '../../generate'; import { WEEK_DAY_COUNT, getWeekStartDate, @@ -7,23 +7,23 @@ import { isSameMonth, formatValue, } from '../../utils/dateUtil'; -import { Locale } from '../../interface'; +import type { Locale } from '../../interface'; import RangeContext from '../../RangeContext'; import useCellClassName from '../../hooks/useCellClassName'; import PanelBody from '../PanelBody'; export type DateRender = (currentDate: DateType, today: DateType) => React.ReactNode; -export interface DateBodyPassProps { +export type DateBodyPassProps = { dateRender?: DateRender; disabledDate?: (date: DateType) => boolean; // Used for week panel prefixColumn?: (date: DateType) => React.ReactNode; rowClassName?: (date: DateType) => string; -} +}; -export interface DateBodyProps extends DateBodyPassProps { +export type DateBodyProps = { prefixCls: string; generateConfig: GenerateConfig; value?: DateType | null; @@ -31,7 +31,7 @@ export interface DateBodyProps extends DateBodyPassProps { locale: Locale; rowCount: number; onSelect: (value: DateType) => void; -} +} & DateBodyPassProps; function DateBody(props: DateBodyProps) { const { diff --git a/src/panels/DatePanel/DateHeader.tsx b/src/panels/DatePanel/DateHeader.tsx index b229936f8..efe91f1f0 100644 --- a/src/panels/DatePanel/DateHeader.tsx +++ b/src/panels/DatePanel/DateHeader.tsx @@ -1,11 +1,11 @@ import * as React from 'react'; import Header from '../Header'; -import { Locale } from '../../interface'; -import { GenerateConfig } from '../../generate'; +import type { Locale } from '../../interface'; +import type { GenerateConfig } from '../../generate'; import PanelContext from '../../PanelContext'; import { formatValue } from '../../utils/dateUtil'; -export interface DateHeaderProps { +export type DateHeaderProps = { prefixCls: string; viewDate: DateType; value?: DateType | null; @@ -18,7 +18,7 @@ export interface DateHeaderProps { onNextMonth: () => void; onYearClick: () => void; onMonthClick: () => void; -} +}; function DateHeader(props: DateHeaderProps) { const { diff --git a/src/panels/DatePanel/index.tsx b/src/panels/DatePanel/index.tsx index 7a12b470b..155f9ae92 100644 --- a/src/panels/DatePanel/index.tsx +++ b/src/panels/DatePanel/index.tsx @@ -1,23 +1,23 @@ import * as React from 'react'; import classNames from 'classnames'; -import DateBody, { DateBodyPassProps, DateRender } from './DateBody'; +import type { DateBodyPassProps, DateRender } from './DateBody'; +import DateBody from './DateBody'; import DateHeader from './DateHeader'; -import { PanelSharedProps } from '../../interface'; +import type { PanelSharedProps } from '../../interface'; import { WEEK_DAY_COUNT } from '../../utils/dateUtil'; -import { createKeyDownHandler, KeyboardConfig } from '../../utils/uiUtil'; +import type { KeyboardConfig } from '../../utils/uiUtil'; +import { createKeyDownHandler } from '../../utils/uiUtil'; const DATE_ROW_COUNT = 6; -export interface DatePanelProps - extends PanelSharedProps, - DateBodyPassProps { +export type DatePanelProps = { active?: boolean; dateRender?: DateRender; // Used for week panel panelName?: string; keyboardConfig?: KeyboardConfig; -} +} & PanelSharedProps & DateBodyPassProps; function DatePanel(props: DatePanelProps) { const { diff --git a/src/panels/DatetimePanel/index.tsx b/src/panels/DatetimePanel/index.tsx index d059c25dc..eb3faccc9 100644 --- a/src/panels/DatetimePanel/index.tsx +++ b/src/panels/DatetimePanel/index.tsx @@ -1,11 +1,13 @@ import * as React from 'react'; import classNames from 'classnames'; import KeyCode from 'rc-util/lib/KeyCode'; -import DatePanel, { DatePanelProps } from '../DatePanel'; -import TimePanel, { SharedTimeProps } from '../TimePanel'; +import type { DatePanelProps } from '../DatePanel'; +import DatePanel from '../DatePanel'; +import type { SharedTimeProps } from '../TimePanel'; +import TimePanel from '../TimePanel'; import { tuple } from '../../utils/miscUtil'; -import { PanelRefProps, DisabledTime, NullableDateType } from '../../interface'; -import { GenerateConfig } from '../../generate'; +import type { PanelRefProps, DisabledTime, NullableDateType } from '../../interface'; +import type { GenerateConfig } from '../../generate'; function setTime( generateConfig: GenerateConfig, @@ -32,15 +34,14 @@ function setTime( return newDate; } -export interface DatetimePanelProps - extends Omit< - DatePanelProps, - 'disabledHours' | 'disabledMinutes' | 'disabledSeconds' - > { +export type DatetimePanelProps = { disabledTime?: DisabledTime; showTime?: boolean | SharedTimeProps; defaultValue?: DateType; -} +} & Omit< + DatePanelProps, + 'disabledHours' | 'disabledMinutes' | 'disabledSeconds' + >; const ACTIVE_PANEL = tuple('date', 'time'); type ActivePanelType = typeof ACTIVE_PANEL[number]; diff --git a/src/panels/DecadePanel/DecadeBody.tsx b/src/panels/DecadePanel/DecadeBody.tsx index 4a8020abf..079464ee0 100644 --- a/src/panels/DecadePanel/DecadeBody.tsx +++ b/src/panels/DecadePanel/DecadeBody.tsx @@ -1,18 +1,18 @@ import * as React from 'react'; -import { GenerateConfig } from '../../generate'; +import type { GenerateConfig } from '../../generate'; import { DECADE_DISTANCE_COUNT, DECADE_UNIT_DIFF } from '.'; import PanelBody from '../PanelBody'; export const DECADE_COL_COUNT = 3; const DECADE_ROW_COUNT = 4; -export interface YearBodyProps { +export type YearBodyProps = { prefixCls: string; generateConfig: GenerateConfig; viewDate: DateType; disabledDate?: (date: DateType) => boolean; onSelect: (value: DateType) => void; -} +}; function DecadeBody(props: YearBodyProps) { const DECADE_UNIT_DIFF_DES = DECADE_UNIT_DIFF - 1; diff --git a/src/panels/DecadePanel/DecadeHeader.tsx b/src/panels/DecadePanel/DecadeHeader.tsx index 1d3ffdcea..e7a3ebd0b 100644 --- a/src/panels/DecadePanel/DecadeHeader.tsx +++ b/src/panels/DecadePanel/DecadeHeader.tsx @@ -1,17 +1,17 @@ import * as React from 'react'; import Header from '../Header'; -import { GenerateConfig } from '../../generate'; +import type { GenerateConfig } from '../../generate'; import { DECADE_DISTANCE_COUNT } from '.'; import PanelContext from '../../PanelContext'; -export interface YearHeaderProps { +export type YearHeaderProps = { prefixCls: string; viewDate: DateType; generateConfig: GenerateConfig; onPrevDecades: () => void; onNextDecades: () => void; -} +}; function DecadeHeader(props: YearHeaderProps) { const { diff --git a/src/panels/DecadePanel/index.tsx b/src/panels/DecadePanel/index.tsx index 963a30ae3..d04de0fbb 100644 --- a/src/panels/DecadePanel/index.tsx +++ b/src/panels/DecadePanel/index.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import DecadeHeader from './DecadeHeader'; import DecadeBody, { DECADE_COL_COUNT } from './DecadeBody'; -import { PanelSharedProps } from '../../interface'; +import type { PanelSharedProps } from '../../interface'; import { createKeyDownHandler } from '../../utils/uiUtil'; export type DecadePanelProps = PanelSharedProps; diff --git a/src/panels/Header.tsx b/src/panels/Header.tsx index dfe1093bc..75620bc67 100644 --- a/src/panels/Header.tsx +++ b/src/panels/Header.tsx @@ -5,7 +5,7 @@ const HIDDEN_STYLE: React.CSSProperties = { visibility: 'hidden', }; -export interface HeaderProps { +export type HeaderProps = { prefixCls: string; // Icons @@ -24,7 +24,7 @@ export interface HeaderProps { onSuperNext?: () => void; children?: React.ReactNode; -} +}; function Header({ prefixCls, diff --git a/src/panels/MonthPanel/MonthBody.tsx b/src/panels/MonthPanel/MonthBody.tsx index d94c951eb..7b80a441c 100644 --- a/src/panels/MonthPanel/MonthBody.tsx +++ b/src/panels/MonthPanel/MonthBody.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; -import { GenerateConfig } from '../../generate'; -import { Locale } from '../../interface'; +import type { GenerateConfig } from '../../generate'; +import type { Locale } from '../../interface'; import { formatValue, isSameMonth } from '../../utils/dateUtil'; import RangeContext from '../../RangeContext'; import useCellClassName from '../../hooks/useCellClassName'; @@ -11,7 +11,7 @@ const MONTH_ROW_COUNT = 4; export type MonthCellRender = (currentDate: DateType, locale: Locale) => React.ReactNode; -export interface MonthBodyProps { +export type MonthBodyProps = { prefixCls: string; locale: Locale; generateConfig: GenerateConfig; @@ -20,7 +20,7 @@ export interface MonthBodyProps { disabledDate?: (date: DateType) => boolean; monthCellRender?: MonthCellRender; onSelect: (value: DateType) => void; -} +}; function MonthBody(props: MonthBodyProps) { const { prefixCls, locale, value, viewDate, generateConfig, monthCellRender } = props; diff --git a/src/panels/MonthPanel/MonthHeader.tsx b/src/panels/MonthPanel/MonthHeader.tsx index 36eea4971..899ff0dcf 100644 --- a/src/panels/MonthPanel/MonthHeader.tsx +++ b/src/panels/MonthPanel/MonthHeader.tsx @@ -1,11 +1,11 @@ import * as React from 'react'; import Header from '../Header'; -import { Locale } from '../../interface'; -import { GenerateConfig } from '../../generate'; +import type { Locale } from '../../interface'; +import type { GenerateConfig } from '../../generate'; import PanelContext from '../../PanelContext'; import { formatValue } from '../../utils/dateUtil'; -export interface MonthHeaderProps { +export type MonthHeaderProps = { prefixCls: string; viewDate: DateType; locale: Locale; @@ -14,7 +14,7 @@ export interface MonthHeaderProps { onPrevYear: () => void; onNextYear: () => void; onYearClick: () => void; -} +}; function MonthHeader(props: MonthHeaderProps) { const { diff --git a/src/panels/MonthPanel/index.tsx b/src/panels/MonthPanel/index.tsx index 825f3b7f4..b2fb270b9 100644 --- a/src/panels/MonthPanel/index.tsx +++ b/src/panels/MonthPanel/index.tsx @@ -1,12 +1,13 @@ import * as React from 'react'; import MonthHeader from './MonthHeader'; -import MonthBody, { MONTH_COL_COUNT, MonthCellRender } from './MonthBody'; -import { PanelSharedProps } from '../../interface'; +import type { MonthCellRender } from './MonthBody'; +import MonthBody, { MONTH_COL_COUNT } from './MonthBody'; +import type { PanelSharedProps } from '../../interface'; import { createKeyDownHandler } from '../../utils/uiUtil'; -export interface MonthPanelProps extends PanelSharedProps { +export type MonthPanelProps = { monthCellContentRender?: MonthCellRender; -} +} & PanelSharedProps; function MonthPanel(props: MonthPanelProps) { const { diff --git a/src/panels/PanelBody.tsx b/src/panels/PanelBody.tsx index 8f9c8a936..fce93d478 100644 --- a/src/panels/PanelBody.tsx +++ b/src/panels/PanelBody.tsx @@ -1,12 +1,12 @@ import * as React from 'react'; import classNames from 'classnames'; import PanelContext from '../PanelContext'; -import { GenerateConfig } from '../generate'; +import type { GenerateConfig } from '../generate'; import { getLastDay } from '../utils/timeUtil'; -import { PanelMode } from '../interface'; +import type { PanelMode } from '../interface'; import { getCellDateDisabled } from '../utils/dateUtil'; -export interface PanelBodyProps { +export type PanelBodyProps = { prefixCls: string; disabledDate?: (date: DateType) => boolean; onSelect: (value: DateType) => void; @@ -27,7 +27,7 @@ export interface PanelBodyProps { // Used for week panel prefixColumn?: (date: DateType) => React.ReactNode; rowClassName?: (date: DateType) => string; -} +}; export default function PanelBody({ prefixCls, diff --git a/src/panels/QuarterPanel/QuarterBody.tsx b/src/panels/QuarterPanel/QuarterBody.tsx index 2bc4afb6e..451bb699d 100644 --- a/src/panels/QuarterPanel/QuarterBody.tsx +++ b/src/panels/QuarterPanel/QuarterBody.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; -import { GenerateConfig } from '../../generate'; -import { Locale } from '../../interface'; +import type { GenerateConfig } from '../../generate'; +import type { Locale } from '../../interface'; import { formatValue, isSameQuarter } from '../../utils/dateUtil'; import RangeContext from '../../RangeContext'; import useCellClassName from '../../hooks/useCellClassName'; @@ -9,7 +9,7 @@ import PanelBody from '../PanelBody'; export const QUARTER_COL_COUNT = 4; const QUARTER_ROW_COUNT = 1; -export interface QuarterBodyProps { +export type QuarterBodyProps = { prefixCls: string; locale: Locale; generateConfig: GenerateConfig; @@ -17,7 +17,7 @@ export interface QuarterBodyProps { viewDate: DateType; disabledDate?: (date: DateType) => boolean; onSelect: (value: DateType) => void; -} +}; function QuarterBody(props: QuarterBodyProps) { const { prefixCls, locale, value, viewDate, generateConfig } = props; diff --git a/src/panels/QuarterPanel/QuarterHeader.tsx b/src/panels/QuarterPanel/QuarterHeader.tsx index 79a2d2ded..aeb707815 100644 --- a/src/panels/QuarterPanel/QuarterHeader.tsx +++ b/src/panels/QuarterPanel/QuarterHeader.tsx @@ -1,11 +1,11 @@ import * as React from 'react'; import Header from '../Header'; -import { Locale } from '../../interface'; -import { GenerateConfig } from '../../generate'; +import type { Locale } from '../../interface'; +import type { GenerateConfig } from '../../generate'; import PanelContext from '../../PanelContext'; import { formatValue } from '../../utils/dateUtil'; -export interface QuarterHeaderProps { +export type QuarterHeaderProps = { prefixCls: string; viewDate: DateType; locale: Locale; @@ -14,7 +14,7 @@ export interface QuarterHeaderProps { onPrevYear: () => void; onNextYear: () => void; onYearClick: () => void; -} +}; function QuarterHeader(props: QuarterHeaderProps) { const { diff --git a/src/panels/QuarterPanel/index.tsx b/src/panels/QuarterPanel/index.tsx index 673e4ff3e..5ae4d3136 100644 --- a/src/panels/QuarterPanel/index.tsx +++ b/src/panels/QuarterPanel/index.tsx @@ -1,10 +1,10 @@ import * as React from 'react'; import QuarterHeader from './QuarterHeader'; import QuarterBody from './QuarterBody'; -import { PanelSharedProps } from '../../interface'; +import type { PanelSharedProps } from '../../interface'; import { createKeyDownHandler } from '../../utils/uiUtil'; -export interface QuarterPanelProps extends PanelSharedProps {} +export type QuarterPanelProps = {} & PanelSharedProps; function QuarterPanel(props: QuarterPanelProps) { const { diff --git a/src/panels/TimePanel/TimeBody.tsx b/src/panels/TimePanel/TimeBody.tsx index 79e131ed1..5e2cf10a1 100644 --- a/src/panels/TimePanel/TimeBody.tsx +++ b/src/panels/TimePanel/TimeBody.tsx @@ -1,10 +1,11 @@ import * as React from 'react'; import useMemo from 'rc-util/lib/hooks/useMemo'; -import { GenerateConfig } from '../../generate'; -import { Locale, OnSelect } from '../../interface'; -import TimeUnitColumn, { Unit } from './TimeUnitColumn'; +import type { GenerateConfig } from '../../generate'; +import type { Locale, OnSelect } from '../../interface'; +import type { Unit } from './TimeUnitColumn'; +import TimeUnitColumn from './TimeUnitColumn'; import { leftPad } from '../../utils/miscUtil'; -import { SharedTimeProps } from '.'; +import type { SharedTimeProps } from '.'; import { setTime as utilSetTime } from '../../utils/timeUtil'; function shouldUnitsUpdate(prevUnits: Unit[], nextUnits: Unit[]) { @@ -33,11 +34,11 @@ function generateUnits( return units; } -export interface BodyOperationRef { +export type BodyOperationRef = { onUpDown: (diff: number) => void; -} +}; -export interface TimeBodyProps extends SharedTimeProps { +export type TimeBodyProps = { prefixCls: string; locale: Locale; generateConfig: GenerateConfig; @@ -45,7 +46,7 @@ export interface TimeBodyProps extends SharedTimeProps { onSelect: OnSelect; activeColumnIndex: number; operationRef: React.MutableRefObject; -} +} & SharedTimeProps; function TimeBody(props: TimeBodyProps) { const { diff --git a/src/panels/TimePanel/TimeHeader.tsx b/src/panels/TimePanel/TimeHeader.tsx index a993ae2af..d8ee90da3 100644 --- a/src/panels/TimePanel/TimeHeader.tsx +++ b/src/panels/TimePanel/TimeHeader.tsx @@ -1,17 +1,17 @@ import * as React from 'react'; import Header from '../Header'; -import { Locale } from '../../interface'; -import { GenerateConfig } from '../../generate'; +import type { Locale } from '../../interface'; +import type { GenerateConfig } from '../../generate'; import PanelContext from '../../PanelContext'; import { formatValue } from '../../utils/dateUtil'; -export interface TimeHeaderProps { +export type TimeHeaderProps = { prefixCls: string; value?: DateType | null; locale: Locale; generateConfig: GenerateConfig; format: string; -} +}; function TimeHeader(props: TimeHeaderProps) { const { hideHeader } = React.useContext(PanelContext); diff --git a/src/panels/TimePanel/TimeUnitColumn.tsx b/src/panels/TimePanel/TimeUnitColumn.tsx index 8587908df..bd1be0a98 100644 --- a/src/panels/TimePanel/TimeUnitColumn.tsx +++ b/src/panels/TimePanel/TimeUnitColumn.tsx @@ -4,20 +4,20 @@ import classNames from 'classnames'; import { scrollTo, waitElementReady } from '../../utils/uiUtil'; import PanelContext from '../../PanelContext'; -export interface Unit { +export type Unit = { label: React.ReactText; value: number; disabled: boolean; -} +}; -export interface TimeUnitColumnProps { +export type TimeUnitColumnProps = { prefixCls?: string; units?: Unit[]; value?: number; active?: boolean; hideDisabledOptions?: boolean; onSelect?: (value: number) => void; -} +}; function TimeUnitColumn(props: TimeUnitColumnProps) { const { prefixCls, units, onSelect, value, active, hideDisabledOptions } = props; diff --git a/src/panels/TimePanel/index.tsx b/src/panels/TimePanel/index.tsx index 8882da495..0b490f3b5 100644 --- a/src/panels/TimePanel/index.tsx +++ b/src/panels/TimePanel/index.tsx @@ -1,11 +1,12 @@ import * as React from 'react'; import classNames from 'classnames'; import TimeHeader from './TimeHeader'; -import TimeBody, { BodyOperationRef } from './TimeBody'; -import { PanelSharedProps, DisabledTimes } from '../../interface'; +import type { BodyOperationRef } from './TimeBody'; +import TimeBody from './TimeBody'; +import type { PanelSharedProps, DisabledTimes } from '../../interface'; import { createKeyDownHandler } from '../../utils/uiUtil'; -export interface SharedTimeProps extends DisabledTimes { +export type SharedTimeProps = { format?: string; showNow?: boolean; showHour?: boolean; @@ -17,14 +18,12 @@ export interface SharedTimeProps extends DisabledTimes { secondStep?: number; hideDisabledOptions?: boolean; defaultValue?: DateType; -} +} & DisabledTimes; -export interface TimePanelProps - extends PanelSharedProps, - SharedTimeProps { +export type TimePanelProps = { format?: string; active?: boolean; -} +} & PanelSharedProps & SharedTimeProps; const countBoolean = (boolList: (boolean | undefined)[]) => boolList.filter(bool => bool !== false).length; diff --git a/src/panels/WeekPanel/index.tsx b/src/panels/WeekPanel/index.tsx index d664e4cc4..478f87698 100644 --- a/src/panels/WeekPanel/index.tsx +++ b/src/panels/WeekPanel/index.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import classNames from 'classnames'; import DatePanel from '../DatePanel'; -import { PanelSharedProps } from '../../interface'; +import type { PanelSharedProps } from '../../interface'; import { isSameWeek } from '../../utils/dateUtil'; export type WeekPanelProps = PanelSharedProps; diff --git a/src/panels/YearPanel/YearBody.tsx b/src/panels/YearPanel/YearBody.tsx index b0ca29ec3..685b14a02 100644 --- a/src/panels/YearPanel/YearBody.tsx +++ b/src/panels/YearPanel/YearBody.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; -import { GenerateConfig } from '../../generate'; +import type { GenerateConfig } from '../../generate'; import { YEAR_DECADE_COUNT } from '.'; -import { Locale, NullableDateType } from '../../interface'; +import type { Locale, NullableDateType } from '../../interface'; import useCellClassName from '../../hooks/useCellClassName'; import { formatValue, isSameYear } from '../../utils/dateUtil'; import RangeContext from '../../RangeContext'; @@ -10,7 +10,7 @@ import PanelBody from '../PanelBody'; export const YEAR_COL_COUNT = 3; const YEAR_ROW_COUNT = 4; -export interface YearBodyProps { +export type YearBodyProps = { prefixCls: string; locale: Locale; generateConfig: GenerateConfig; @@ -18,7 +18,7 @@ export interface YearBodyProps { viewDate: DateType; disabledDate?: (date: DateType) => boolean; onSelect: (value: DateType) => void; -} +}; function YearBody(props: YearBodyProps) { const { prefixCls, value, viewDate, locale, generateConfig } = props; diff --git a/src/panels/YearPanel/YearHeader.tsx b/src/panels/YearPanel/YearHeader.tsx index 3c60aab9a..7b453722f 100644 --- a/src/panels/YearPanel/YearHeader.tsx +++ b/src/panels/YearPanel/YearHeader.tsx @@ -1,10 +1,10 @@ import * as React from 'react'; import Header from '../Header'; -import { GenerateConfig } from '../../generate'; +import type { GenerateConfig } from '../../generate'; import { YEAR_DECADE_COUNT } from '.'; import PanelContext from '../../PanelContext'; -export interface YearHeaderProps { +export type YearHeaderProps = { prefixCls: string; viewDate: DateType; value?: DateType | null; @@ -13,7 +13,7 @@ export interface YearHeaderProps { onPrevDecade: () => void; onNextDecade: () => void; onDecadeClick: () => void; -} +}; function YearHeader(props: YearHeaderProps) { const { prefixCls, generateConfig, viewDate, onPrevDecade, onNextDecade, onDecadeClick } = props; diff --git a/src/panels/YearPanel/index.tsx b/src/panels/YearPanel/index.tsx index a1387c41a..6e349de7c 100644 --- a/src/panels/YearPanel/index.tsx +++ b/src/panels/YearPanel/index.tsx @@ -1,12 +1,12 @@ import * as React from 'react'; import YearHeader from './YearHeader'; import YearBody, { YEAR_COL_COUNT } from './YearBody'; -import { PanelSharedProps, PanelMode } from '../../interface'; +import type { PanelSharedProps, PanelMode } from '../../interface'; import { createKeyDownHandler } from '../../utils/uiUtil'; -export interface YearPanelProps extends PanelSharedProps { +export type YearPanelProps = { sourceMode: PanelMode; -} +} & PanelSharedProps; export const YEAR_DECADE_COUNT = 10; diff --git a/src/utils/dateUtil.ts b/src/utils/dateUtil.ts index e4710c025..0dc5fb163 100644 --- a/src/utils/dateUtil.ts +++ b/src/utils/dateUtil.ts @@ -1,6 +1,6 @@ import { DECADE_UNIT_DIFF } from '../panels/DecadePanel/index'; -import { PanelMode, NullableDateType, PickerMode, Locale, CustomFormat } from '../interface'; -import { GenerateConfig } from '../generate'; +import type { PanelMode, NullableDateType, PickerMode, Locale, CustomFormat } from '../interface'; +import type { GenerateConfig } from '../generate'; export const WEEK_DAY_COUNT = 7; @@ -220,7 +220,7 @@ export function parseValue( }: { generateConfig: GenerateConfig; locale: Locale; - formatList: Array>; + formatList: (string | CustomFormat)[]; }, ) { if (!value || typeof formatList[0] === 'function') { @@ -242,6 +242,7 @@ export function getCellDateDisabled({ disabledDate?: (date: DateType) => boolean; }): boolean { if (!disabledDate) return false; + // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check switch (mode) { case 'date': case 'week': { diff --git a/src/utils/getExtraFooter.tsx b/src/utils/getExtraFooter.tsx index 37f90bb3c..af54e15d3 100644 --- a/src/utils/getExtraFooter.tsx +++ b/src/utils/getExtraFooter.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { PanelMode } from '../interface'; +import type { PanelMode } from '../interface'; export default function getExtraFooter( prefixCls: string, diff --git a/src/utils/getRanges.tsx b/src/utils/getRanges.tsx index 2b8f2f94f..1621e62eb 100644 --- a/src/utils/getRanges.tsx +++ b/src/utils/getRanges.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; -import { Components, RangeList, Locale } from '../interface'; +import type { Components, RangeList, Locale } from '../interface'; -export interface RangesProps { +export type RangesProps = { prefixCls: string; rangeList?: RangeList; components?: Components; @@ -11,7 +11,7 @@ export interface RangesProps { okDisabled?: boolean; showNow?: boolean; locale: Locale; -} +}; export default function getRanges({ prefixCls, diff --git a/src/utils/timeUtil.ts b/src/utils/timeUtil.ts index 8cdbfa224..0b9e5dc61 100644 --- a/src/utils/timeUtil.ts +++ b/src/utils/timeUtil.ts @@ -1,4 +1,4 @@ -import { GenerateConfig } from '../generate'; +import type { GenerateConfig } from '../generate'; export function setTime( generateConfig: GenerateConfig, diff --git a/src/utils/uiUtil.ts b/src/utils/uiUtil.ts index d6f800a71..1cc0e3528 100644 --- a/src/utils/uiUtil.ts +++ b/src/utils/uiUtil.ts @@ -1,8 +1,8 @@ import KeyCode from 'rc-util/lib/KeyCode'; import raf from 'rc-util/lib/raf'; import isVisible from 'rc-util/lib/Dom/isVisible'; -import { GenerateConfig } from '../generate'; -import { CustomFormat, PanelMode, PickerMode } from '../interface'; +import type { GenerateConfig } from '../generate'; +import type { CustomFormat, PanelMode, PickerMode } from '../interface'; const scrollIds = new Map(); @@ -59,13 +59,13 @@ export function scrollTo(element: HTMLElement, to: number, duration: number) { } /* eslint-enable */ -export interface KeyboardConfig { +export type KeyboardConfig = { onLeftRight?: ((diff: number) => void) | null; onCtrlLeftRight?: ((diff: number) => void) | null; onUpDown?: ((diff: number) => void) | null; onPageUpDown?: ((diff: number) => void) | null; onEnter?: (() => void) | null; -} +}; export function createKeyDownHandler( event: React.KeyboardEvent, { onLeftRight, onCtrlLeftRight, onUpDown, onPageUpDown, onEnter }: KeyboardConfig, @@ -145,7 +145,7 @@ export function createKeyDownHandler( // ===================== Format ===================== export function getDefaultFormat( - format: string | CustomFormat | Array> | undefined, + format: string | CustomFormat | (string | CustomFormat)[] | undefined, picker: PickerMode | undefined, showTime: boolean | object | undefined, use12Hours: boolean | undefined, diff --git a/tests/picker.spec.tsx b/tests/picker.spec.tsx index a177aab0b..6b2264b2c 100644 --- a/tests/picker.spec.tsx +++ b/tests/picker.spec.tsx @@ -866,4 +866,31 @@ describe('Picker.Basic', () => { wrapper.unmount(); }); }); + + describe('prevent default on keydown', () => { + it('should open picker panel if no prevent default', () => { + const keyDown = jest.fn(); + const wrapper = mount(); + + wrapper.closePicker(); + wrapper.keyDown(KeyCode.ENTER); + expect(wrapper.isOpen()).toBeTruthy(); + }); + + it('should not open if prevent default is called', () => { + const keyDown = jest.fn(({ which }, preventDefault) => { + if (which === 13) preventDefault(); + }); + const wrapper = mount(); + + wrapper.openPicker(); + expect(wrapper.isOpen()).toBeTruthy(); + + wrapper.keyDown(KeyCode.ESC); + expect(wrapper.isOpen()).toBeFalsy(); + + wrapper.keyDown(KeyCode.ENTER); + expect(wrapper.isOpen()).toBeFalsy(); + }); + }); }); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 000000000..bba22975e --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "esnext", + "moduleResolution": "node", + "baseUrl": "./", + "jsx": "preserve", + "declaration": true, + "skipLibCheck": true, + "esModuleInterop": true + } +} \ No newline at end of file From f68e8c6ade22a1dac6ccd3a7ba860c055eefb075 Mon Sep 17 00:00:00 2001 From: Kermit Date: Fri, 25 Dec 2020 21:03:05 +0800 Subject: [PATCH 07/10] chore: rename disabledDate example --- examples/{disableDate.tsx => disabledDate.tsx} | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) rename examples/{disableDate.tsx => disabledDate.tsx} (96%) diff --git a/examples/disableDate.tsx b/examples/disabledDate.tsx similarity index 96% rename from examples/disableDate.tsx rename to examples/disabledDate.tsx index 3ef67f81c..7ce49d6d0 100644 --- a/examples/disableDate.tsx +++ b/examples/disabledDate.tsx @@ -1,5 +1,6 @@ import React from 'react'; -import moment, { Moment } from 'moment'; +import type { Moment } from 'moment'; +import moment from 'moment'; import Picker from '../src/Picker'; import momentGenerateConfig from '../src/generate/moment'; import enUS from '../src/locale/en_US'; From fb35003c4684de41f0438f207299dbebafec990e Mon Sep 17 00:00:00 2001 From: Kermit Date: Mon, 28 Dec 2020 21:32:14 +0800 Subject: [PATCH 08/10] chore: clean code --- src/Picker.tsx | 2 +- src/utils/dateUtil.ts | 113 ++++++++++++++++++++---------------------- 2 files changed, 55 insertions(+), 60 deletions(-) diff --git a/src/Picker.tsx b/src/Picker.tsx index b404dd70f..2463473ca 100644 --- a/src/Picker.tsx +++ b/src/Picker.tsx @@ -391,7 +391,7 @@ function InnerPicker(props: PickerProps) { }} direction={direction} onPanelChange={(viewDate, mode) => { - const { onPanelChange } = panelProps; + const { onPanelChange } = props; onLeave(true); onPanelChange?.(viewDate, mode); }} diff --git a/src/utils/dateUtil.ts b/src/utils/dateUtil.ts index 0dc5fb163..6df5004ac 100644 --- a/src/utils/dateUtil.ts +++ b/src/utils/dateUtil.ts @@ -242,6 +242,56 @@ export function getCellDateDisabled({ disabledDate?: (date: DateType) => boolean; }): boolean { if (!disabledDate) return false; + // Whether cellDate is disabled in range + const getDisabledFromRange = ( + currentMode: 'date' | 'month' | 'year', + start: number, + end: number, + ) => { + let current = start; + while (current <= end) { + let date: DateType; + switch (currentMode) { + case 'date': { + date = generateConfig.setDate(cellDate, current); + if (!disabledDate(date)) { + return false; + } + break; + } + case 'month': { + date = generateConfig.setMonth(cellDate, current); + if ( + !getCellDateDisabled({ + cellDate: date, + mode: 'month', + generateConfig, + disabledDate, + }) + ) { + return false; + } + break; + } + case 'year': { + date = generateConfig.setYear(cellDate, current); + if ( + !getCellDateDisabled({ + cellDate: date, + mode: 'year', + generateConfig, + disabledDate, + }) + ) { + return false; + } + break; + } + } + current += 1; + } + return true; + }; // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check switch (mode) { case 'date': @@ -251,76 +301,21 @@ export function getCellDateDisabled({ case 'month': { const startDate = 1; const endDate = generateConfig.getDate(generateConfig.getEndDate(cellDate)); - let currentDate = startDate; - while (currentDate <= endDate) { - const date = generateConfig.setDate(cellDate, currentDate); - if (!disabledDate(date)) { - return false; - } - currentDate += 1; - } - return true; + return getDisabledFromRange('date', startDate, endDate); } case 'quarter': { const startMonth = Math.floor(generateConfig.getMonth(cellDate) / 3) * 3; const endMonth = startMonth + 2; - let currentMonth = startMonth; - while (currentMonth <= endMonth) { - const date = generateConfig.setMonth(cellDate, currentMonth); - if ( - !getCellDateDisabled({ - cellDate: date, - mode: 'month', - generateConfig, - disabledDate, - }) - ) { - return false; - } - currentMonth += 1; - } - return true; + return getDisabledFromRange('month', startMonth, endMonth); } case 'year': { - const startMonth = 0; - const endMonth = 11; - let currentMonth = startMonth; - while (currentMonth <= endMonth) { - const date = generateConfig.setMonth(cellDate, currentMonth); - if ( - !getCellDateDisabled({ - cellDate: date, - mode: 'month', - generateConfig, - disabledDate, - }) - ) { - return false; - } - currentMonth += 1; - } - return true; + return getDisabledFromRange('month', 0, 11); } case 'decade': { const year = generateConfig.getYear(cellDate); const startYear = Math.floor(year / DECADE_UNIT_DIFF) * DECADE_UNIT_DIFF; const endYear = startYear + DECADE_UNIT_DIFF - 1; - let currentYear = startYear; - while (currentYear <= endYear) { - const date = generateConfig.setYear(cellDate, currentYear); - if ( - !getCellDateDisabled({ - cellDate: date, - mode: 'year', - generateConfig, - disabledDate, - }) - ) { - return false; - } - currentYear += 1; - } - return true; + return getDisabledFromRange('year', startYear, endYear); } } return false; From dbe843b8c47a9b66d6db84aaec2db1a1fefc06ef Mon Sep 17 00:00:00 2001 From: Kermit Date: Mon, 28 Dec 2020 22:22:25 +0800 Subject: [PATCH 09/10] chore: add test case --- tests/picker.spec.tsx | 63 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/tests/picker.spec.tsx b/tests/picker.spec.tsx index f13251277..807cdafac 100644 --- a/tests/picker.spec.tsx +++ b/tests/picker.spec.tsx @@ -893,4 +893,67 @@ describe('Picker.Basic', () => { expect(wrapper.isOpen()).toBeFalsy(); }); }); + + describe('disabledDate', () => { + function disabledDate(current: Moment) { + return current <= getMoment('2020-12-28 00:00:00').endOf('day'); + } + const wrapper = mount(); + // Date Panel + Array.from({ + length: 31 + }).forEach((v, i) => { + const cell = wrapper.findCell(`${i + 1}`); + // >= 29 + if (i >= 28) { + expect(cell.hasClass('rc-picker-cell-disabled')).toBeFalsy(); + } else { + expect(cell.hasClass('rc-picker-cell-disabled')).toBeTruthy(); + } + }); + wrapper.find('.rc-picker-month-btn').simulate('click'); + // Month Panel + Array.from({ + length: 12 + }).forEach((v, i) => { + const cell = wrapper.find('.rc-picker-cell-in-view').at(i); + // >= 12 + if (i >= 11) { + expect(cell.hasClass('rc-picker-cell-disabled')).toBeFalsy(); + } else { + expect(cell.hasClass('rc-picker-cell-disabled')).toBeTruthy(); + } + }); + wrapper.find('.rc-picker-year-btn').simulate('click'); + // Year Panel + Array.from({ + length: 10 + }).forEach((v, i) => { + const cell = wrapper.find('.rc-picker-cell-in-view').at(i); + // >= 2020 + expect(cell.hasClass('rc-picker-cell-disabled')).toBeFalsy(); + }); + // Decade Panel + Array.from({ + length: 8 + }).forEach((v, i) => { + const cell = wrapper.find('.rc-picker-cell-in-view').at(i); + // >= 2020 + expect(cell.hasClass('rc-picker-cell-disabled')).toBeFalsy(); + }); + + const quarterWrapper = mount(); + // quarter Panel + Array.from({ + length: 4 + }).forEach((v, i) => { + const cell = quarterWrapper.find('.rc-picker-cell-in-view').at(i); + // >= 4 + if (i >= 3) { + expect(cell.hasClass('rc-picker-cell-disabled')).toBeFalsy(); + } else { + expect(cell.hasClass('rc-picker-cell-disabled')).toBeTruthy(); + } + }); + }); }); From 1329de9a1a76c2f6721468a4c4db60f88460ae86 Mon Sep 17 00:00:00 2001 From: Kermit Date: Mon, 28 Dec 2020 22:35:54 +0800 Subject: [PATCH 10/10] chore: clean code --- src/utils/dateUtil.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/utils/dateUtil.ts b/src/utils/dateUtil.ts index 6df5004ac..677d73416 100644 --- a/src/utils/dateUtil.ts +++ b/src/utils/dateUtil.ts @@ -230,6 +230,7 @@ export function parseValue( return generateConfig.locale.parse(locale.locale, value, formatList as string[]); } +// eslint-disable-next-line consistent-return export function getCellDateDisabled({ cellDate, mode, @@ -237,7 +238,7 @@ export function getCellDateDisabled({ generateConfig, }: { cellDate: DateType; - mode: PanelMode; + mode: Omit; generateConfig: GenerateConfig; disabledDate?: (date: DateType) => boolean; }): boolean { @@ -292,7 +293,6 @@ export function getCellDateDisabled({ } return true; }; - // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check switch (mode) { case 'date': case 'week': { @@ -318,5 +318,4 @@ export function getCellDateDisabled({ return getDisabledFromRange('year', startYear, endYear); } } - return false; }