Skip to content

Commit 7259519

Browse files
authored
refactor: multiple default use !needConfirm & fix min-max limitation check logic (#747)
* refactor: multiple no needConfirm * fix: clear * docs: add limit * chore: fix part of limitation * chore: all header * chore: limitation * chore: clean up * chore: fix ts
1 parent deecac7 commit 7259519

File tree

20 files changed

+324
-123
lines changed

20 files changed

+324
-123
lines changed

docs/demo/limitation.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
title: limitation
3+
nav:
4+
title: Demo
5+
path: /demo
6+
---
7+
8+
<code src="../examples/limitation.tsx"></code>

docs/demo/multiple.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
title: multiple
3+
nav:
4+
title: Demo
5+
path: /demo
6+
---
7+
8+
<code src="../examples/multiple.tsx"></code>

docs/examples/limitation.tsx

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import * as React from 'react';
2+
import '../../assets/index.less';
3+
import SinglePicker from '../../src/PickerInput/SinglePicker';
4+
5+
import dayjs from 'dayjs';
6+
import 'dayjs/locale/ar';
7+
import 'dayjs/locale/zh-cn';
8+
import LocalizedFormat from 'dayjs/plugin/localizedFormat';
9+
import dayjsGenerateConfig from '../../src/generate/dayjs';
10+
import zhCN from '../../src/locale/zh_CN';
11+
12+
dayjs.locale('zh-cn');
13+
dayjs.extend(LocalizedFormat);
14+
15+
console.clear();
16+
17+
(window as any).dayjs = dayjs;
18+
19+
const sharedLocale = {
20+
locale: zhCN,
21+
generateConfig: dayjsGenerateConfig,
22+
style: { width: 300 },
23+
};
24+
25+
export default () => {
26+
return (
27+
<div>
28+
<SinglePicker
29+
{...sharedLocale}
30+
// defaultPickerValue={dayjs('2019-09-15')}
31+
defaultValue={dayjs('2020-09-03')}
32+
minDate={dayjs('2019-08-01')}
33+
maxDate={dayjs('2020-10-31')}
34+
// open
35+
/>
36+
<SinglePicker
37+
{...sharedLocale}
38+
defaultValue={dayjs('2020-09-03')}
39+
minDate={dayjs('2019-08-01')}
40+
maxDate={dayjs('2020-10-31')}
41+
picker="month"
42+
/>
43+
<SinglePicker
44+
{...sharedLocale}
45+
defaultValue={dayjs('2020-09-03')}
46+
minDate={dayjs('2019-08-01')}
47+
maxDate={dayjs('2020-10-31')}
48+
picker="quarter"
49+
/>
50+
</div>
51+
);
52+
};

docs/examples/multiple.tsx

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import * as React from 'react';
2+
import '../../assets/index.less';
3+
import type { PickerRef } from '../../src/interface';
4+
import SinglePicker from '../../src/PickerInput/SinglePicker';
5+
6+
import dayjs from 'dayjs';
7+
import 'dayjs/locale/ar';
8+
import 'dayjs/locale/zh-cn';
9+
import LocalizedFormat from 'dayjs/plugin/localizedFormat';
10+
import dayjsGenerateConfig from '../../src/generate/dayjs';
11+
import zhCN from '../../src/locale/zh_CN';
12+
13+
dayjs.locale('zh-cn');
14+
dayjs.extend(LocalizedFormat);
15+
16+
console.clear();
17+
18+
(window as any).dayjs = dayjs;
19+
20+
const sharedLocale = {
21+
locale: zhCN,
22+
generateConfig: dayjsGenerateConfig,
23+
style: { width: 300 },
24+
};
25+
26+
export default () => {
27+
const singleRef = React.useRef<PickerRef>(null);
28+
29+
return (
30+
<div>
31+
<SinglePicker {...sharedLocale} multiple ref={singleRef} onOpenChange={console.error} />
32+
<SinglePicker {...sharedLocale} multiple ref={singleRef} needConfirm />
33+
</div>
34+
);
35+
};

src/PickerInput/Popup/PopupPanel.tsx

Lines changed: 10 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ export type PopupPanelProps<DateType extends object = any> = MustProp<DateType>
1313
Omit<PickerPanelProps<DateType>, 'onPickerValueChange' | 'showTime'> &
1414
FooterProps<DateType> & {
1515
multiplePanel?: boolean;
16-
minDate?: DateType;
17-
maxDate?: DateType;
1816
range?: boolean;
1917

2018
onPickerValueChange: (date: DateType) => void;
@@ -23,17 +21,8 @@ export type PopupPanelProps<DateType extends object = any> = MustProp<DateType>
2321
export default function PopupPanel<DateType extends object = any>(
2422
props: PopupPanelProps<DateType>,
2523
) {
26-
const {
27-
picker,
28-
multiplePanel,
29-
pickerValue,
30-
onPickerValueChange,
31-
onSubmit,
32-
minDate,
33-
maxDate,
34-
range,
35-
hoverValue,
36-
} = props;
24+
const { picker, multiplePanel, pickerValue, onPickerValueChange, onSubmit, range, hoverValue } =
25+
props;
3726
const { prefixCls, generateConfig } = React.useContext(PickerContext);
3827

3928
// ======================== Offset ========================
@@ -63,36 +52,6 @@ export default function PopupPanel<DateType extends object = any>(
6352

6453
const hideHeader = picker === 'time';
6554

66-
// ====================== Limitation ======================
67-
const needLimit = React.useCallback(
68-
(currentPickerValue: DateType) => {
69-
let hidePrev = false;
70-
let hideNext = false;
71-
72-
const dateBeforePickerValue = internalOffsetDate(currentPickerValue, -1);
73-
if (minDate && generateConfig.isAfter(minDate, dateBeforePickerValue)) {
74-
hidePrev = true;
75-
}
76-
77-
const dateAfterPickerValue = internalOffsetDate(currentPickerValue, 1);
78-
if (maxDate && generateConfig.isAfter(dateAfterPickerValue, maxDate)) {
79-
hideNext = true;
80-
}
81-
82-
return {
83-
hidePrev,
84-
hideNext,
85-
};
86-
},
87-
[minDate, maxDate, internalOffsetDate, generateConfig],
88-
);
89-
90-
const firstPanelNeedLimit = React.useMemo(() => needLimit(pickerValue), [pickerValue, needLimit]);
91-
const secondPanelNeedLimit = React.useMemo(
92-
() => needLimit(nextPickerValue),
93-
[nextPickerValue, needLimit],
94-
);
95-
9655
// ======================== Props =========================
9756
const pickerProps = {
9857
...props,
@@ -113,12 +72,18 @@ export default function PopupPanel<DateType extends object = any>(
11372
return (
11473
<div className={`${prefixCls}-panels`}>
11574
<PickerHackContext.Provider
116-
value={{ ...sharedContext, hideNext: true, hidePrev: firstPanelNeedLimit.hidePrev }}
75+
value={{
76+
...sharedContext,
77+
hideNext: true,
78+
}}
11779
>
11880
<PickerPanel<DateType> {...pickerProps} />
11981
</PickerHackContext.Provider>
12082
<PickerHackContext.Provider
121-
value={{ ...sharedContext, hidePrev: true, hideNext: secondPanelNeedLimit.hideNext }}
83+
value={{
84+
...sharedContext,
85+
hidePrev: true,
86+
}}
12287
>
12388
<PickerPanel<DateType>
12489
{...pickerProps}
@@ -135,7 +100,6 @@ export default function PopupPanel<DateType extends object = any>(
135100
<PickerHackContext.Provider
136101
value={{
137102
...sharedContext,
138-
...firstPanelNeedLimit,
139103
}}
140104
>
141105
<PickerPanel {...pickerProps} />

src/PickerInput/hooks/useFilledProps.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,9 @@ export default function useFilledProps<
128128
const internalPicker: InternalMode = picker === 'date' && showTime ? 'datetime' : picker;
129129

130130
/** The picker is `datetime` or `time` */
131-
const complexPicker = internalPicker === 'time' || internalPicker === 'datetime' || multiple;
132-
const mergedNeedConfirm = needConfirm ?? complexPicker;
131+
const multipleInteractivePicker = internalPicker === 'time' || internalPicker === 'datetime';
132+
const complexPicker = multipleInteractivePicker || multiple;
133+
const mergedNeedConfirm = needConfirm ?? multipleInteractivePicker;
133134

134135
// ========================== Time ==========================
135136
// Auto `format` need to check `showTime.showXXX` first.

src/PickerInput/hooks/useRangeValue.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ export function useInnerValue<ValueType extends DateType[], DateType extends obj
137137
clone[i] = clone[i] || null;
138138
}
139139
} else if (order) {
140-
clone = orderDates(clone, generateConfig);
140+
clone = orderDates(clone.filter((date) => date) as ValueType, generateConfig);
141141
}
142142

143143
// Update merged value

src/PickerPanel/DatePanel/index.tsx

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ export default function DatePanel<DateType extends object = any>(props: DatePane
4646
// ========================== Base ==========================
4747
const [info, now] = useInfo(props, mode);
4848
const weekFirstDay = generateConfig.locale.getWeekFirstDay(locale.locale);
49-
const baseDate = getWeekStartDate(locale.locale, generateConfig, pickerValue);
49+
const monthStartDate = generateConfig.setDate(pickerValue, 1);
50+
const baseDate = getWeekStartDate(locale.locale, generateConfig, monthStartDate);
5051
const month = generateConfig.getMonth(pickerValue);
5152

5253
// =========================== PrefixColumn ===========================
@@ -176,12 +177,16 @@ export default function DatePanel<DateType extends object = any>(props: DatePane
176177
<PanelContext.Provider value={info}>
177178
<div className={classNames(panelPrefixCls, showWeek && `${panelPrefixCls}-show-week`)}>
178179
{/* Header */}
179-
<PanelHeader
180-
onOffset={(offset) => {
181-
onPickerValueChange(generateConfig.addMonth(pickerValue, offset));
182-
}}
183-
onSuperOffset={(offset) => {
184-
onPickerValueChange(generateConfig.addYear(pickerValue, offset));
180+
<PanelHeader<DateType>
181+
offset={(distance) => generateConfig.addMonth(pickerValue, distance)}
182+
superOffset={(distance) => generateConfig.addYear(pickerValue, distance)}
183+
onChange={onPickerValueChange}
184+
// Limitation
185+
getStart={(date) => generateConfig.setDate(date, 1)}
186+
getEnd={(date) => {
187+
let clone = generateConfig.setDate(date, 1);
188+
clone = generateConfig.addMonth(clone, 1);
189+
return generateConfig.addDate(clone, -1);
185190
}}
186191
>
187192
{monthYearNodes}

src/PickerPanel/DecadePanel/index.tsx

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as React from 'react';
22
import type { DisabledDate, SharedPanelProps } from '../../interface';
3-
import { formatValue } from '../../utils/dateUtil';
3+
import { formatValue, isInRange, isSameDecade } from '../../utils/dateUtil';
44
import { PanelContext, useInfo } from '../context';
55
import PanelBody from '../PanelBody';
66
import PanelHeader from '../PanelHeader';
@@ -15,13 +15,20 @@ export default function DecadePanel<DateType extends object = any>(
1515

1616
// ========================== Base ==========================
1717
const [info] = useInfo(props, 'decade');
18-
const startYear = Math.floor(generateConfig.getYear(pickerValue) / 100) * 100;
19-
const endYear = startYear + 99;
2018

21-
const baseDate = generateConfig.setYear(pickerValue, startYear - 10);
19+
const getStartYear = (date: DateType) => {
20+
const startYear = Math.floor(generateConfig.getYear(pickerValue) / 100) * 100;
21+
return generateConfig.setYear(date, startYear);
22+
};
23+
const getEndYear = (date: DateType) => {
24+
const startYear = getStartYear(date);
25+
return generateConfig.addYear(startYear, 99);
26+
};
27+
28+
const startYearDate = getStartYear(pickerValue);
29+
const endYearDate = getEndYear(pickerValue);
2230

23-
const startYearDate = generateConfig.setYear(baseDate, startYear);
24-
const endYearDate = generateConfig.setYear(startYearDate, endYear);
31+
const baseDate = generateConfig.addYear(startYearDate, -10);
2532

2633
// ========================= Cells ==========================
2734
const getCellDate = (date: DateType, offset: number) => {
@@ -46,9 +53,11 @@ export default function DecadePanel<DateType extends object = any>(
4653
};
4754

4855
const getCellClassName = (date: DateType) => {
49-
const dateYear = generateConfig.getYear(date);
5056
return {
51-
[`${prefixCls}-cell-in-view`]: startYear <= dateYear && dateYear <= endYear,
57+
[`${prefixCls}-cell-in-view`]:
58+
isSameDecade(generateConfig, date, startYearDate) ||
59+
isSameDecade(generateConfig, date, endYearDate) ||
60+
isInRange(generateConfig, startYearDate, endYearDate, date),
5261
};
5362
};
5463

@@ -88,9 +97,11 @@ export default function DecadePanel<DateType extends object = any>(
8897
<div className={panelPrefixCls}>
8998
{/* Header */}
9099
<PanelHeader
91-
onSuperOffset={(offset) => {
92-
onPickerValueChange(generateConfig.addYear(pickerValue, offset * 100));
93-
}}
100+
superOffset={(distance) => generateConfig.addYear(pickerValue, distance * 100)}
101+
onChange={onPickerValueChange}
102+
// Limitation
103+
getStart={getStartYear}
104+
getEnd={getEndYear}
94105
>
95106
{yearNode}
96107
</PanelHeader>

src/PickerPanel/MonthPanel/index.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,11 @@ export default function MonthPanel<DateType extends object = any>(
9191
<div className={panelPrefixCls}>
9292
{/* Header */}
9393
<PanelHeader
94-
onSuperOffset={(offset) => {
95-
onPickerValueChange(generateConfig.addYear(pickerValue, offset));
96-
}}
94+
superOffset={(distance) => generateConfig.addYear(pickerValue, distance)}
95+
onChange={onPickerValueChange}
96+
// Limitation
97+
getStart={(date) => generateConfig.setMonth(date, 0)}
98+
getEnd={(date) => generateConfig.setMonth(date, 11)}
9799
>
98100
{yearNode}
99101
</PanelHeader>

0 commit comments

Comments
 (0)