diff --git a/examples/basic.tsx b/examples/basic.tsx index 0649d07ee..ec0106076 100644 --- a/examples/basic.tsx +++ b/examples/basic.tsx @@ -102,11 +102,11 @@ export default () => {

Week

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

Quarter

+ generateConfig={momentGenerateConfig} locale={enUS} picker="quarter" />

Time

@@ -114,12 +114,7 @@ export default () => {

Time 12

- - {...sharedProps} - locale={zhCN} - picker="time" - use12Hours - /> + {...sharedProps} locale={zhCN} picker="time" use12Hours />

Year

diff --git a/examples/panel.tsx b/examples/panel.tsx index d7d9fdf67..70e0c1cb0 100644 --- a/examples/panel.tsx +++ b/examples/panel.tsx @@ -68,6 +68,11 @@ export default () => { {...sharedProps} locale={zhCN} picker="month" />
+
+

Quarter Picker

+ {...sharedProps} locale={zhCN} picker="quarter" /> +
+

Week Picker US

{...sharedProps} locale={enUS} picker="week" /> @@ -79,12 +84,7 @@ export default () => {

Uncontrolled

- - {...sharedProps} - locale={jaJP} - value={undefined} - picker="time" - /> + {...sharedProps} locale={jaJP} value={undefined} picker="time" />

Time AM/PM

diff --git a/src/PickerPanel.tsx b/src/PickerPanel.tsx index c7e04f584..8c8102dfd 100644 --- a/src/PickerPanel.tsx +++ b/src/PickerPanel.tsx @@ -17,6 +17,7 @@ import DatetimePanel from './panels/DatetimePanel'; import DatePanel from './panels/DatePanel'; import WeekPanel from './panels/WeekPanel'; import MonthPanel from './panels/MonthPanel'; +import QuarterPanel from './panels/QuarterPanel'; import YearPanel from './panels/YearPanel'; import DecadePanel from './panels/DecadePanel'; import { GenerateConfig } from './generate'; @@ -84,13 +85,11 @@ export interface PickerPanelSharedProps { components?: Components; } -export interface PickerPanelBaseProps - extends PickerPanelSharedProps { +export interface PickerPanelBaseProps extends PickerPanelSharedProps { picker: Exclude; } -export interface PickerPanelDateProps - extends PickerPanelSharedProps { +export interface PickerPanelDateProps extends PickerPanelSharedProps { picker?: 'date'; showToday?: boolean; @@ -149,18 +148,11 @@ function PickerPanel(props: PickerPanelProps) { direction, } = props as MergedPickerPanelProps; - const needConfirmButton: boolean = - (picker === 'date' && !!showTime) || picker === 'time'; + const needConfirmButton: boolean = (picker === 'date' && !!showTime) || picker === 'time'; if (process.env.NODE_ENV !== 'production') { - warning( - !value || generateConfig.isValidate(value), - 'Invalidate date pass to `value`.', - ); - warning( - !value || generateConfig.isValidate(value), - 'Invalidate date pass to `defaultValue`.', - ); + warning(!value || generateConfig.isValidate(value), 'Invalidate date pass to `value`.'); + warning(!value || generateConfig.isValidate(value), 'Invalidate date pass to `defaultValue`.'); } // ============================ State ============================= @@ -174,12 +166,7 @@ function PickerPanel(props: PickerPanelProps) { defaultOpenValue, } = panelContext; - const { - inRange, - panelPosition, - rangedValue, - hoverRangedValue, - } = React.useContext(RangeContext); + const { inRange, panelPosition, rangedValue, hoverRangedValue } = React.useContext(RangeContext); const panelRef = React.useRef({}); // Handle init logic @@ -198,10 +185,7 @@ function PickerPanel(props: PickerPanelProps) { }); // View date control - const [viewDate, setInnerViewDate] = useMergedState< - DateType | null, - DateType - >(null, { + const [viewDate, setInnerViewDate] = useMergedState(null, { value: pickerValue, defaultValue: defaultPickerValue || mergedValue, postState: date => date || generateConfig.getNow(), @@ -237,22 +221,14 @@ function PickerPanel(props: PickerPanelProps) { }, ); - const [sourceMode, setSourceMode] = React.useState( - () => mergedMode, - ); + const [sourceMode, setSourceMode] = React.useState(() => mergedMode); - const onInternalPanelChange = ( - newMode: PanelMode | null, - viewValue: DateType, - ) => { + const onInternalPanelChange = (newMode: PanelMode | null, viewValue: DateType) => { const nextMode = getInternalNextMode(newMode || mergedMode); setSourceMode(mergedMode); setInnerMode(nextMode); - if ( - onPanelChange && - (mergedMode !== nextMode || isEqual(generateConfig, viewDate, viewDate)) - ) { + if (onPanelChange && (mergedMode !== nextMode || isEqual(generateConfig, viewDate, viewDate))) { onPanelChange(viewValue, nextMode); } }; @@ -392,6 +368,18 @@ function PickerPanel(props: PickerPanelProps) { ); break; + case 'quarter': + panelNode = ( + + {...pickerProps} + onSelect={(date, type) => { + setViewDate(date); + triggerSelect(date, type); + }} + /> + ); + break; + case 'week': panelNode = ( (props: PickerPanelProps) { (props: PickerPanelProps) {
; @@ -51,10 +52,7 @@ export interface PanelRefProps { export type NullableDateType = DateType | null | undefined; -export type OnSelect = ( - value: DateType, - type: 'key' | 'mouse' | 'submit', -) => void; +export type OnSelect = (value: DateType, type: 'key' | 'mouse' | 'submit') => void; export interface PanelSharedProps { prefixCls: string; @@ -91,15 +89,10 @@ export interface DisabledTimes { export type DisabledTime = (date: DateType | null) => DisabledTimes; -export type OnPanelChange = ( - value: DateType, - mode: PanelMode, -) => void; +export type OnPanelChange = (value: DateType, mode: PanelMode) => void; export type EventValue = DateType | null; -export type RangeValue = - | [EventValue, EventValue] - | null; +export type RangeValue = [EventValue, EventValue] | null; export interface Components { button?: React.ComponentType | string; diff --git a/src/panels/QuarterPanel/QuarterBody.tsx b/src/panels/QuarterPanel/QuarterBody.tsx new file mode 100644 index 000000000..f6607852e --- /dev/null +++ b/src/panels/QuarterPanel/QuarterBody.tsx @@ -0,0 +1,58 @@ +import * as React from 'react'; +import { GenerateConfig } from '../../generate'; +import { Locale } from '../../interface'; +import { isSameQuarter } from '../../utils/dateUtil'; +import RangeContext from '../../RangeContext'; +import useCellClassName from '../../hooks/useCellClassName'; +import PanelBody from '../PanelBody'; + +export const QUARTER_COL_COUNT = 4; +const QUARTER_ROW_COUNT = 1; + +export interface QuarterBodyProps { + prefixCls: string; + locale: Locale; + generateConfig: GenerateConfig; + value?: DateType | null; + viewDate: DateType; + disabledDate?: (date: DateType) => boolean; + onSelect: (value: DateType) => void; +} + +function QuarterBody(props: QuarterBodyProps) { + const { prefixCls, locale, value, viewDate, generateConfig } = props; + + const { rangedValue, hoverRangedValue } = React.useContext(RangeContext); + + const cellPrefixCls = `${prefixCls}-cell`; + + const getCellClassName = useCellClassName({ + cellPrefixCls, + value, + generateConfig, + rangedValue, + hoverRangedValue, + isSameCell: (current, target) => isSameQuarter(generateConfig, current, target), + isInView: () => true, + offsetCell: (date, offset) => generateConfig.addMonth(date, offset * 3), + }); + + const baseQuarter = generateConfig.setDate(generateConfig.setMonth(viewDate, 0), 1); + + return ( + + generateConfig.locale.format(locale.locale, date, locale.quarterFormat || '\\QQ') + } + getCellClassName={getCellClassName} + getCellDate={(date, offset) => generateConfig.addMonth(date, offset * 3)} + titleCell={date => generateConfig.locale.format(locale.locale, date, 'YYYY-\\QQ')} + /> + ); +} + +export default QuarterBody; diff --git a/src/panels/QuarterPanel/QuarterHeader.tsx b/src/panels/QuarterPanel/QuarterHeader.tsx new file mode 100644 index 000000000..5a288ca69 --- /dev/null +++ b/src/panels/QuarterPanel/QuarterHeader.tsx @@ -0,0 +1,44 @@ +import * as React from 'react'; +import Header from '../Header'; +import { Locale } from '../../interface'; +import { GenerateConfig } from '../../generate'; +import PanelContext from '../../PanelContext'; + +export interface QuarterHeaderProps { + prefixCls: string; + viewDate: DateType; + locale: Locale; + generateConfig: GenerateConfig; + + onPrevYear: () => void; + onNextYear: () => void; + onYearClick: () => void; +} + +function QuarterHeader(props: QuarterHeaderProps) { + const { + prefixCls, + generateConfig, + locale, + viewDate, + onNextYear, + onPrevYear, + onYearClick, + } = props; + const { hideHeader } = React.useContext(PanelContext); + if (hideHeader) { + return null; + } + + const headerPrefixCls = `${prefixCls}-header`; + + return ( +
+ +
+ ); +} + +export default QuarterHeader; diff --git a/src/panels/QuarterPanel/index.tsx b/src/panels/QuarterPanel/index.tsx new file mode 100644 index 000000000..673e4ff3e --- /dev/null +++ b/src/panels/QuarterPanel/index.tsx @@ -0,0 +1,72 @@ +import * as React from 'react'; +import QuarterHeader from './QuarterHeader'; +import QuarterBody from './QuarterBody'; +import { PanelSharedProps } from '../../interface'; +import { createKeyDownHandler } from '../../utils/uiUtil'; + +export interface QuarterPanelProps extends PanelSharedProps {} + +function QuarterPanel(props: QuarterPanelProps) { + const { + prefixCls, + operationRef, + onViewDateChange, + generateConfig, + value, + viewDate, + onPanelChange, + onSelect, + } = props; + + const panelPrefixCls = `${prefixCls}-quarter-panel`; + + // ======================= Keyboard ======================= + operationRef.current = { + onKeyDown: event => + createKeyDownHandler(event, { + onLeftRight: diff => { + onSelect(generateConfig.addMonth(value || viewDate, diff * 3), 'key'); + }, + onCtrlLeftRight: diff => { + onSelect(generateConfig.addYear(value || viewDate, diff), 'key'); + }, + onUpDown: diff => { + onSelect(generateConfig.addYear(value || viewDate, diff), 'key'); + }, + }), + }; + + // ==================== View Operation ==================== + const onYearChange = (diff: number) => { + const newDate = generateConfig.addYear(viewDate, diff); + onViewDateChange(newDate); + onPanelChange(null, newDate); + }; + + return ( +
+ { + onYearChange(-1); + }} + onNextYear={() => { + onYearChange(1); + }} + onYearClick={() => { + onPanelChange('year', viewDate); + }} + /> + + {...props} + prefixCls={prefixCls} + onSelect={date => { + onSelect(date, 'mouse'); + }} + /> +
+ ); +} + +export default QuarterPanel; diff --git a/src/utils/dateUtil.ts b/src/utils/dateUtil.ts index 56c428269..b14cb7d9f 100644 --- a/src/utils/dateUtil.ts +++ b/src/utils/dateUtil.ts @@ -42,6 +42,27 @@ export function isSameYear( return generateConfig.getYear(year1!) === generateConfig.getYear(year2!); } +export function getQuarter(generateConfig: GenerateConfig, date: DateType) { + const quota = Math.floor(generateConfig.getMonth(date) / 3); + return quota + 1; +} + +export function isSameQuarter( + generateConfig: GenerateConfig, + quarter1: NullableDateType, + quarter2: NullableDateType, +) { + const equal = isNullEqual(quarter1, quarter2); + if (typeof equal === 'boolean') { + return equal; + } + + return ( + isSameYear(generateConfig, quarter1, quarter2) && + getQuarter(generateConfig, quarter1!) === getQuarter(generateConfig, quarter2!) + ); +} + export function isSameMonth( generateConfig: GenerateConfig, month1: NullableDateType, @@ -104,8 +125,7 @@ export function isSameWeek( } return ( - generateConfig.locale.getWeek(locale, date1!) === - generateConfig.locale.getWeek(locale, date2!) + generateConfig.locale.getWeek(locale, date1!) === generateConfig.locale.getWeek(locale, date2!) ); } @@ -114,10 +134,7 @@ export function isEqual( value1: NullableDateType, value2: NullableDateType, ) { - return ( - isSameDate(generateConfig, value1, value2) && - isSameTime(generateConfig, value1, value2) - ); + return isSameDate(generateConfig, value1, value2) && isSameTime(generateConfig, value1, value2); } /** Between in date but not equal of date */ diff --git a/src/utils/uiUtil.ts b/src/utils/uiUtil.ts index a294b8550..6d1a772df 100644 --- a/src/utils/uiUtil.ts +++ b/src/utils/uiUtil.ts @@ -44,13 +44,7 @@ export interface KeyboardConfig { } export function createKeyDownHandler( event: React.KeyboardEvent, - { - onLeftRight, - onCtrlLeftRight, - onUpDown, - onPageUpDown, - onEnter, - }: KeyboardConfig, + { onLeftRight, onCtrlLeftRight, onUpDown, onPageUpDown, onEnter }: KeyboardConfig, ): boolean { const { which, ctrlKey, metaKey } = event; @@ -147,6 +141,10 @@ export function getDefaultFormat( mergedFormat = 'YYYY-MM'; break; + case 'quarter': + mergedFormat = 'YYYY-\\QQ'; + break; + case 'year': mergedFormat = 'YYYY'; break; @@ -170,11 +168,7 @@ let globalClickFunc: ClickEventHandler | null = null; const clickCallbacks = new Set(); export function addGlobalMouseDownEvent(callback: ClickEventHandler) { - if ( - !globalClickFunc && - typeof window !== 'undefined' && - window.addEventListener - ) { + if (!globalClickFunc && typeof window !== 'undefined' && window.addEventListener) { globalClickFunc = (e: MouseEvent) => { // Clone a new list to avoid repeat trigger events [...clickCallbacks].forEach(queueFunc => { @@ -210,6 +204,13 @@ const getMonthNextMode = (next: PanelMode): PanelMode => { return next; }; +const getQuarterNextMode = (next: PanelMode): PanelMode => { + if (next === 'month' || next === 'date') { + return 'quarter'; + } + return next; +}; + const getWeekNextMode = (next: PanelMode): PanelMode => { if (next === 'date') { return 'week'; @@ -217,12 +218,10 @@ const getWeekNextMode = (next: PanelMode): PanelMode => { return next; }; -export const PickerModeMap: Record< - PickerMode, - ((next: PanelMode) => PanelMode) | null -> = { +export const PickerModeMap: Record PanelMode) | null> = { year: getYearNextMode, month: getMonthNextMode, + quarter: getQuarterNextMode, week: getWeekNextMode, time: null, date: null, diff --git a/tests/keyboard.spec.tsx b/tests/keyboard.spec.tsx index dc781587f..16f02ff86 100644 --- a/tests/keyboard.spec.tsx +++ b/tests/keyboard.spec.tsx @@ -14,9 +14,7 @@ import { describe('Picker.Keyboard', () => { function panelKeyDown(wrapper: Wrapper, keyCode: number, info?: object) { - wrapper - .find('.rc-picker-panel') - .simulate('keyDown', { which: keyCode, ...info }); + wrapper.find('.rc-picker-panel').simulate('keyDown', { which: keyCode, ...info }); } beforeAll(() => { @@ -30,9 +28,7 @@ describe('Picker.Keyboard', () => { it('open to select', () => { const onChange = jest.fn(); const onSelect = jest.fn(); - const wrapper = mount( - , - ); + const wrapper = mount(); wrapper.find('input').simulate('focus'); wrapper.keyDown(KeyCode.ENTER); expect(wrapper.isOpen()).toBeTruthy(); @@ -195,77 +191,45 @@ describe('Picker.Keyboard', () => { ].forEach(({ name, operate }) => { it(name, () => { const onSelect = jest.fn(); - const wrapper = mount( - , - ); + const wrapper = mount(); // Focus Panel wrapper.find('.rc-picker-panel').simulate('focus'); // Focus Date Panel operate(wrapper); - expect( - wrapper.find('.rc-picker-date-panel-active').length, - ).toBeTruthy(); + expect(wrapper.find('.rc-picker-date-panel-active').length).toBeTruthy(); // Select panelKeyDown(wrapper, KeyCode.DOWN); - expect( - isSame(onSelect.mock.calls[0][0], '1990-09-10'), - ).toBeTruthy(); + expect(isSame(onSelect.mock.calls[0][0], '1990-09-10')).toBeTruthy(); // Focus Time Panel panelKeyDown(wrapper, KeyCode.TAB); - expect( - wrapper.find('.rc-picker-time-panel-active').length, - ).toBeTruthy(); + expect(wrapper.find('.rc-picker-time-panel-active').length).toBeTruthy(); // Select onSelect.mockReset(); panelKeyDown(wrapper, KeyCode.UP); panelKeyDown(wrapper, KeyCode.DOWN); - expect( - isSame( - onSelect.mock.calls[0][0], - '1990-09-10 01:00:00', - 'second', - ), - ).toBeTruthy(); + expect(isSame(onSelect.mock.calls[0][0], '1990-09-10 01:00:00', 'second')).toBeTruthy(); // Next column select onSelect.mockReset(); panelKeyDown(wrapper, KeyCode.RIGHT); panelKeyDown(wrapper, KeyCode.UP); - expect( - isSame( - onSelect.mock.calls[0][0], - '1990-09-10 01:59:00', - 'second', - ), - ).toBeTruthy(); + expect(isSame(onSelect.mock.calls[0][0], '1990-09-10 01:59:00', 'second')).toBeTruthy(); // Enter to exit column edit onSelect.mockReset(); - expect( - wrapper.find('.rc-picker-time-panel-column-active').length, - ).toBeTruthy(); + expect(wrapper.find('.rc-picker-time-panel-column-active').length).toBeTruthy(); panelKeyDown(wrapper, KeyCode.ENTER); - expect( - wrapper.find('.rc-picker-time-panel-column-active').length, - ).toBeFalsy(); - expect( - isSame( - onSelect.mock.calls[0][0], - '1990-09-10 01:59:00', - 'second', - ), - ).toBeTruthy(); + expect(wrapper.find('.rc-picker-time-panel-column-active').length).toBeFalsy(); + expect(isSame(onSelect.mock.calls[0][0], '1990-09-10 01:59:00', 'second')).toBeTruthy(); // Close should not focus wrapper.find('.rc-picker-panel').simulate('blur'); - expect( - wrapper.find('.rc-picker-time-panel-active').length, - ).toBeFalsy(); + expect(wrapper.find('.rc-picker-time-panel-active').length).toBeFalsy(); }); }); }); @@ -295,13 +259,9 @@ describe('Picker.Keyboard', () => { it('time enter will trigger onSelect', () => { const onSelect = jest.fn(); - const wrapper = mount( - , - ); + const wrapper = mount(); panelKeyDown(wrapper, KeyCode.ENTER); - expect( - isSame(onSelect.mock.calls[0][0], '1990-09-03 00:00:00', 'second'), - ).toBeTruthy(); + expect(isSame(onSelect.mock.calls[0][0], '1990-09-03 00:00:00', 'second')).toBeTruthy(); }); describe('arrow trigger onSelect', () => { @@ -331,6 +291,31 @@ describe('Picker.Keyboard', () => { expect(isSame(onSelect.mock.calls[0][0], '1991-11-03')).toBeTruthy(); }); + it('quarter', () => { + const onSelect = jest.fn(); + const wrapper = mount( + , + ); + + // Left + panelKeyDown(wrapper, KeyCode.LEFT); + expect(isSame(onSelect.mock.calls[0][0], '1990-06-03')).toBeTruthy(); + + // Control + Right + onSelect.mockReset(); + panelKeyDown(wrapper, KeyCode.RIGHT, { ctrlKey: true }); + expect(isSame(onSelect.mock.calls[0][0], '1991-06-03')).toBeTruthy(); + + // Down + onSelect.mockReset(); + panelKeyDown(wrapper, KeyCode.DOWN); + expect(isSame(onSelect.mock.calls[0][0], '1992-06-03')).toBeTruthy(); + }); + it('year', () => { const onSelect = jest.fn(); const wrapper = mount( @@ -369,25 +354,19 @@ describe('Picker.Keyboard', () => { // Left panelKeyDown(wrapper, KeyCode.LEFT); panelKeyDown(wrapper, KeyCode.ENTER); - expect( - isSame(onPanelChange.mock.calls[0][0], '1980', 'year'), - ).toBeTruthy(); + expect(isSame(onPanelChange.mock.calls[0][0], '1980', 'year')).toBeTruthy(); // Control + Right onPanelChange.mockReset(); panelKeyDown(wrapper, KeyCode.RIGHT, { ctrlKey: true }); panelKeyDown(wrapper, KeyCode.ENTER); - expect( - isSame(onPanelChange.mock.calls[0][0], '2080', 'year'), - ).toBeTruthy(); + expect(isSame(onPanelChange.mock.calls[0][0], '2080', 'year')).toBeTruthy(); // Down onPanelChange.mockReset(); panelKeyDown(wrapper, KeyCode.DOWN); panelKeyDown(wrapper, KeyCode.ENTER); - expect( - isSame(onPanelChange.mock.calls[0][0], '2110', 'year'), - ).toBeTruthy(); + expect(isSame(onPanelChange.mock.calls[0][0], '2110', 'year')).toBeTruthy(); }); }); @@ -397,10 +376,7 @@ describe('Picker.Keyboard', () => { const onCalendarChange = jest.fn(); const onChange = jest.fn(); const wrapper = mount( - , + , ); // Start Date @@ -434,10 +410,7 @@ describe('Picker.Keyboard', () => { wrapper.keyDown(KeyCode.TAB, {}, 1); wrapper.keyDown(KeyCode.DOWN, {}, 1); wrapper.keyDown(KeyCode.ENTER, {}, 1); - expect(onCalendarChange.mock.calls[0][1]).toEqual([ - '1990-01-08', - '2000-01-08', - ]); + expect(onCalendarChange.mock.calls[0][1]).toEqual(['1990-01-08', '2000-01-08']); expect(onChange.mock.calls[0][1]).toEqual(['1990-01-08', '2000-01-08']); jest.useRealTimers(); diff --git a/tests/panel.spec.tsx b/tests/panel.spec.tsx index 0feebc879..d6e0ce377 100644 --- a/tests/panel.spec.tsx +++ b/tests/panel.spec.tsx @@ -69,20 +69,22 @@ describe('Picker.Panel', () => { expect(wrapper.find('.rc-picker-year-panel').length).toBeTruthy(); }); - it('month', () => { - const wrapper = mount(); - wrapper.find('.rc-picker-year-btn').simulate('click'); - wrapper.find('.rc-picker-decade-btn').simulate('click'); - expect(wrapper.find('.rc-picker-decade-panel').length).toBeTruthy(); + [['month', 'Aug'], ['quarter', 'Q3']].forEach(([picker, cell]) => { + it(picker, () => { + const wrapper = mount(); + wrapper.find('.rc-picker-year-btn').simulate('click'); + wrapper.find('.rc-picker-decade-btn').simulate('click'); + expect(wrapper.find('.rc-picker-decade-panel').length).toBeTruthy(); - wrapper.selectCell('1990-1999'); - expect(wrapper.find('.rc-picker-year-panel').length).toBeTruthy(); + wrapper.selectCell('1990-1999'); + expect(wrapper.find('.rc-picker-year-panel').length).toBeTruthy(); - wrapper.selectCell('1999'); - expect(wrapper.find('.rc-picker-month-panel').length).toBeTruthy(); + wrapper.selectCell('1999'); + expect(wrapper.find(`.rc-picker-${picker}-panel`).length).toBeTruthy(); - wrapper.selectCell('Aug'); - expect(wrapper.find('.rc-picker-month-panel').length).toBeTruthy(); + wrapper.selectCell(cell); + expect(wrapper.find(`.rc-picker-${picker}-panel`).length).toBeTruthy(); + }); }); }); @@ -154,16 +156,18 @@ describe('Picker.Panel', () => { expect(wrapper.find('.rc-picker-header-view').text()).toEqual('Sep1990'); }); - it('month', () => { - const wrapper = mount( - , - ); + ['month', 'quarter'].forEach(picker => { + it(picker, () => { + const wrapper = mount( + , + ); - wrapper.clickButton('super-prev'); - expect(wrapper.find('.rc-picker-header-view').text()).toEqual('1989'); + wrapper.clickButton('super-prev'); + expect(wrapper.find('.rc-picker-header-view').text()).toEqual('1989'); - wrapper.clickButton('super-next'); - expect(wrapper.find('.rc-picker-header-view').text()).toEqual('1990'); + wrapper.clickButton('super-next'); + expect(wrapper.find('.rc-picker-header-view').text()).toEqual('1990'); + }); }); it('year', () => { @@ -383,7 +387,7 @@ describe('Picker.Panel', () => { }); describe('hideHeader', () => { - ['decade', 'year', 'month', 'date', 'time'].forEach(mode => { + ['decade', 'year', 'month', 'quarter', 'date', 'time'].forEach(mode => { it(mode, () => { const wrapper = mount(); expect(wrapper.find('.rc-picker-header')).toHaveLength(0); diff --git a/tests/picker.spec.tsx b/tests/picker.spec.tsx index 68059c993..00ccc8260 100644 --- a/tests/picker.spec.tsx +++ b/tests/picker.spec.tsx @@ -26,6 +26,10 @@ describe('Picker.Basic', () => { mode: 'year', componentNames: ['YearPanel', 'YearHeader', 'YearBody'], }, + { + mode: 'quarter', + componentNames: ['QuarterPanel', 'QuarterHeader', 'QuarterBody'], + }, { mode: 'month', componentNames: ['MonthPanel', 'MonthHeader', 'MonthBody'], @@ -60,6 +64,10 @@ describe('Picker.Basic', () => { picker: 'year', componentNames: ['YearPanel', 'YearHeader', 'YearBody'], }, + { + picker: 'quarter', + componentNames: ['QuarterPanel', 'QuarterHeader', 'QuarterBody'], + }, { picker: 'month', componentNames: ['MonthPanel', 'MonthHeader', 'MonthBody'], @@ -459,7 +467,7 @@ describe('Picker.Basic', () => { expect(isSame(onSelect.mock.calls[0][0], '1990-09-03')).toBeTruthy(); }); - ['decade', 'year', 'month', 'week'].forEach(name => { + ['decade', 'year', 'quarter', 'month', 'week'].forEach(name => { it(`not works on ${name}`, () => { const wrapper = mount(); wrapper.openPicker(); @@ -584,7 +592,12 @@ describe('Picker.Basic', () => { ); expect(wrapper.find('input').props().value).toEqual('1999-09-03 00:00:00'); - [['date', '1999-09-03'], ['month', '1999-09'], ['year', '1999']].forEach(([picker, text]) => { + [ + ['date', '1999-09-03'], + ['month', '1999-09'], + ['quarter', '1999-Q3'], + ['year', '1999'], + ].forEach(([picker, text]) => { wrapper.setProps({ picker, showTime: false }); wrapper.update(); expect(wrapper.find('input').props().value).toEqual(text);