Skip to content

Commit

Permalink
feat(Datepicker): add cancel select range limit API (#2684)
Browse files Browse the repository at this point in the history
* feat(datepicker): support cancel range limit

* chore: update snapshot

* chore: fix lint
  • Loading branch information
uyarn authored Dec 28, 2023
1 parent c180d2a commit 23a40c4
Show file tree
Hide file tree
Showing 13 changed files with 264 additions and 15 deletions.
4 changes: 3 additions & 1 deletion src/date-picker/DateRangePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const DateRangePicker = forwardRef<HTMLDivElement, DateRangePickerProps>((origin
presetsPlacement,
panelPreselection,
onPick,
cancelRangeSelectLimit,
} = props;

const {
Expand Down Expand Up @@ -297,7 +298,7 @@ const DateRangePicker = forwardRef<HTMLDivElement, DateRangePickerProps>((origin
presetValue = preset();
}
if (!Array.isArray(presetValue)) {
log.error('DateRangePicker', `preset: ${preset} 预设值必须是数组!`);
log.error('DateRangePicker', `preset: ${preset} must be Array!`);
} else {
onChange(formatDate(presetValue, { format, targetFormat: valueType, autoSwap: true }), {
dayjsValue: presetValue.map((p) => parseToDayjs(p, format)),
Expand Down Expand Up @@ -354,6 +355,7 @@ const DateRangePicker = forwardRef<HTMLDivElement, DateRangePickerProps>((origin
presetsPlacement,
activeIndex,
popupVisible,
cancelRangeSelectLimit,
onCellClick,
onCellMouseEnter,
onCellMouseLeave,
Expand Down
2 changes: 1 addition & 1 deletion src/date-picker/DateRangePickerPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ const DateRangePickerPanel = forwardRef<HTMLDivElement, DateRangePickerPanelProp
const presetVal = typeof presetValue === 'function' ? presetValue() : presetValue;

if (!Array.isArray(presetVal)) {
log.error('DateRangePickerPanel', `preset: ${presetValue} 预设值必须是数组!`);
log.error('DateRangePickerPanel', `preset: ${presetValue} must be Array!`);
} else {
onChange(formatDate(presetVal, { format, autoSwap: true }), {
dayjsValue: presetVal.map((p) => parseToDayjs(p, format)),
Expand Down
10 changes: 10 additions & 0 deletions src/date-picker/_example/cancel-range-limit.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from 'react';
import { DateRangePicker, Space } from 'tdesign-react';

export default function CancelRangeLimitDatePicker() {
return (
<Space direction="vertical">
<DateRangePicker cancelRangeSelectLimit={true} clearable={true} />
</Space>
);
}
23 changes: 12 additions & 11 deletions src/date-picker/date-picker.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@ defaultTime | String | '00:00:00' | Time selector default value | N
disableDate | Object / Array / Function | - | Typescript:`DisableDate` `type DisableDate = Array<DateValue> \| DisableDateObj \| ((date: DateValue) => boolean)` `interface DisableDateObj { from?: string; to?: string; before?: string; after?: string }`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/date-picker/type.ts) | N
disabled | Boolean | - | make DatePicker to be disabled | N
enableTimePicker | Boolean | false | \- | N
firstDayOfWeek | Number | 7 | options1/2/3/4/5/6/7 | N
firstDayOfWeek | Number | 7 | options: 1/2/3/4/5/6/7 | N
format | String | 'YYYY-MM-DD' | \- | N
inputProps | Object | - | Typescript:`InputProps`[Input API Documents](./input?tab=api)[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/date-picker/type.ts) | N
mode | String | date | optionsyear/quarter/month/week/date | N
mode | String | date | options: year/quarter/month/week/date | N
placeholder | String / Array | undefined | Typescript:`string` | N
popupProps | Object | - | Typescript:`PopupProps`[Popup API Documents](./popup?tab=api)[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/date-picker/type.ts) | N
prefixIcon | TElement | - | Typescript:`TNode`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N
presets | Object | - | Typescript:`PresetDate` `interface PresetDate { [name: string]: DateValue \| (() => DateValue) }`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/date-picker/type.ts) | N
presetsPlacement | String | bottom | optionsleft/top/right/bottom | N
size | String | medium | optionssmall/medium/large。Typescript:`SizeEnum`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N
status | String | default | optionsdefault/success/warning/error | N
presetsPlacement | String | bottom | options: left/top/right/bottom | N
size | String | medium | options: small/medium/large。Typescript:`SizeEnum`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N
status | String | default | options: default/success/warning/error | N
suffixIcon | TElement | - | Typescript:`TNode`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N
timePickerProps | Object | - | Typescript:`TimePickerProps`[TimePicker API Documents](./time-picker?tab=api)[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/date-picker/type.ts) | N
tips | TNode | - | Typescript:`string \| TNode`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N
Expand All @@ -44,30 +44,31 @@ name | type | default | description | required
className | String | - | 类名 | N
style | Object | - | 样式,Typescript:`React.CSSProperties` | N
allowInput | Boolean | false | \- | N
cancelRangeSelectLimit | Boolean | false | The default date selection interaction is determined based on the order of dates clicked and will be restricted. For example, if a user first clicks on the start date input box and chooses a date, for instance, 2020-05-15, the interaction will automatically shift focus to the end date input box, waiting for the user to select the end time. At this point, the user can only select a date later than 2020-05-15 (previous dates will be grayed out and disabled, restricting the user's selection). When this value is set to `true`, this restriction is lifted. | N
clearable | Boolean | false | \- | N
defaultTime | Array | ["00:00:00", "23:59:59"] | Time selector default value。Typescript:`string[]` | N
disableDate | Object / Array / Function | - | Typescript:`DisableRangeDate` `type DisableRangeDate = Array<DateValue> \| DisableDateObj \| ((context: { date: DateRangeValue; partial: DateRangePickerPartial }) => boolean)` `interface DisableDateObj { from?: string; to?: string; before?: string; after?: string }` `type DateRangePickerPartial = 'start' \| 'end'`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/date-picker/type.ts) | N
disabled | Boolean | - | \- | N
enableTimePicker | Boolean | false | \- | N
firstDayOfWeek | Number | - | options1/2/3/4/5/6/7 | N
firstDayOfWeek | Number | - | options: 1/2/3/4/5/6/7 | N
format | String | - | \- | N
mode | String | date | optionsyear/quarter/month/week/date | N
mode | String | date | options: year/quarter/month/week/date | N
panelPreselection | Boolean | true | \- | N
placeholder | String / Array | - | Typescript:`string \| Array<string>` | N
popupProps | Object | - | Typescript:`PopupProps`[Popup API Documents](./popup?tab=api)[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/date-picker/type.ts) | N
prefixIcon | TElement | - | Typescript:`TNode`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N
presets | Object | - | Typescript:`PresetRange` `interface PresetRange { [range: string]: DateRange \| (() => DateRange)}` `type DateRange = [DateValue, DateValue]`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/date-picker/type.ts) | N
presetsPlacement | String | bottom | optionsleft/top/right/bottom | N
presetsPlacement | String | bottom | options: left/top/right/bottom | N
rangeInputProps | Object | - | Typescript:`RangeInputProps`[RangeInput API Documents](./range-input?tab=api)[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/date-picker/type.ts) | N
separator | String | - | \- | N
size | String | medium | optionssmall/medium/large。Typescript:`SizeEnum`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N
status | String | default | optionsdefault/success/warning/error | N
size | String | medium | options: small/medium/large。Typescript:`SizeEnum`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N
status | String | default | options: default/success/warning/error | N
suffixIcon | TElement | - | Typescript:`TNode`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N
timePickerProps | Object | - | Typescript:`TimePickerProps`[TimePicker API Documents](./time-picker?tab=api)[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/date-picker/type.ts) | N
tips | TNode | - | Typescript:`string \| TNode`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N
value | Array | [] | Typescript:`DateRangeValue` `type DateRangeValue = Array<DateValue>`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/date-picker/type.ts) | N
defaultValue | Array | [] | uncontrolled property。Typescript:`DateRangeValue` `type DateRangeValue = Array<DateValue>`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/date-picker/type.ts) | N
valueType | String | - | optionstime-stamp/Date/YYYY/YYYY-MM/YYYY-MM-DD/YYYY-MM-DD HH/YYYY-MM-DD HH:mm/YYYY-MM-DD HH:mm:ss/YYYY-MM-DD HH:mm:ss:SSS | N
valueType | String | - | options: time-stamp/Date/YYYY/YYYY-MM/YYYY-MM-DD/YYYY-MM-DD HH/YYYY-MM-DD HH:mm/YYYY-MM-DD HH:mm:ss/YYYY-MM-DD HH:mm:ss:SSS | N
onBlur | Function | | Typescript:`(context: { value: DateRangeValue; partial: DateRangePickerPartial; e: FocusEvent }) => void`<br/> | N
onChange | Function | | Typescript:`(value: DateRangeValue, context: { dayjsValue?: Dayjs[], trigger?: DatePickerTriggerSource }) => void`<br/>[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/date-picker/type.ts)。<br/>`import { Dayjs } from 'dayjs'`<br/> | N
onConfirm | Function | | Typescript:`(context: { date: Date[], e: MouseEvent, partial: DateRangePickerPartial }) => void`<br/> | N
Expand Down
1 change: 1 addition & 0 deletions src/date-picker/date-picker.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ onPresetClick | Function | | TS 类型:`(context: { preset: PresetDate, e: Mo
className | String | - | 类名 | N
style | Object | - | 样式,TS 类型:`React.CSSProperties` | N
allowInput | Boolean | false | 是否允许输入日期 | N
cancelRangeSelectLimit | Boolean | false | 默认的日期选择交互是根据点击前后日期的顺序来决定并且会加以限制。比如:用户先点击开始时间输入框,选择了一个日期例如2020-05-15,紧接着交互会自动将焦点跳到结束日期输入框,等待用户选择结束时间。此时用户只能选择大于2020-05-15的日期(之前的日期会被灰态禁止点击,限制用户的点击)。当该值传递`true`时,则取消该限制。 | N
clearable | Boolean | false | 是否显示清除按钮 | N
defaultTime | Array | ["00:00:00", "23:59:59"] | 时间选择器默认值,当 value/defaultValue 未设置值时有效。TS 类型:`string[]` | N
disableDate | Object / Array / Function | - | 禁用日期,示例:['A', 'B'] 表示日期 A 和日期 B 会被禁用。{ from: 'A', to: 'B' } 表示在 A 到 B 之间的日期会被禁用。{ before: 'A', after: 'B' } 表示在 A 之前和在 B 之后的日期都会被禁用。其中 A = '2021-01-01',B = '2021-02-01'。值类型为 Function 则表示返回值为 true 的日期会被禁用。TS 类型:`DisableRangeDate` `type DisableRangeDate = Array<DateValue> \| DisableDateObj \| ((context: { date: DateRangeValue; partial: DateRangePickerPartial }) => boolean)` `interface DisableDateObj { from?: string; to?: string; before?: string; after?: string }` `type DateRangePickerPartial = 'start' \| 'end'`[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/date-picker/type.ts) | N
Expand Down
1 change: 1 addition & 0 deletions src/date-picker/defaultProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export const datePickerDefaultProps: TdDatePickerProps = {

export const dateRangePickerDefaultProps: TdDateRangePickerProps = {
allowInput: false,
cancelRangeSelectLimit: false,
clearable: false,
defaultTime: ['00:00:00', '23:59:59'],
enableTimePicker: false,
Expand Down
2 changes: 1 addition & 1 deletion src/date-picker/hooks/useRangeValue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export default function useRange(props: TdDateRangePickerProps) {

if (props.enableTimePicker) {
if (!extractTimeFormat(format))
log.error('DatePicker', `format: ${format} 不规范,包含时间选择必须要有时间格式化 HH:mm:ss`);
log.error('DatePicker', `format: ${format} is invalid,time selection must include time formatting HH:mm:ss`);
}

// warning invalid value
Expand Down
2 changes: 1 addition & 1 deletion src/date-picker/hooks/useSingleValue.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default function useSingleValue(props: TdDatePickerProps) {

if (props.enableTimePicker) {
if (!extractTimeFormat(format))
log.error('DatePicker', `format: ${format} 不规范,包含时间选择必须要有时间格式化 HH:mm:ss`);
log.error('DatePicker', `format: ${format} is invalid,time selection must include time formatting HH:mm:ss`);
}

const [time, setTime] = useState(formatTime(value, format, timeFormat, props.defaultTime));
Expand Down
2 changes: 2 additions & 0 deletions src/date-picker/hooks/useTableData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export interface TableDataProps extends SinglePanelProps {
hoverEnd?: Date | undefined;
minDate: Date | null;
maxDate: Date | null;
cancelRangeSelectLimit?: boolean;
}

export default function useTableData(props: TableDataProps) {
Expand Down Expand Up @@ -45,6 +46,7 @@ export default function useTableData(props: TableDataProps) {
quarterLocal,
showWeekOfYear: mode === 'week',
dayjsLocale: local.dayjsLocale,
cancelRangeSelectLimit: props.cancelRangeSelectLimit,
};

if (mode === 'date') {
Expand Down
4 changes: 4 additions & 0 deletions src/date-picker/panel/RangePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export interface RangePanelProps extends TdDateRangePickerProps, StyledProps {
year?: number[];
month?: number[];
time?: string[];
cancelRangeSelectLimit?: boolean;
onClick?: (context: { e: React.MouseEvent<HTMLDivElement> }) => void;
onCellClick?: (date: Date, context: { e: React.MouseEvent<HTMLDivElement>; partial: 'start' | 'end' }) => void;
onCellMouseEnter?: (date: Date, context: { partial: 'start' | 'end' }) => void;
Expand Down Expand Up @@ -55,6 +56,7 @@ const RangePanel = forwardRef<HTMLDivElement, RangePanelProps>((props, ref) => {
onClick,
onConfirmClick,
onPresetClick,
cancelRangeSelectLimit,
} = props;

const { format } = getDefaultFormat({
Expand Down Expand Up @@ -93,6 +95,7 @@ const RangePanel = forwardRef<HTMLDivElement, RangePanelProps>((props, ref) => {
month: startMonth,
mode,
firstDayOfWeek,
cancelRangeSelectLimit,
...disableDateOptions,
});
const endTableData = useTableData({
Expand All @@ -105,6 +108,7 @@ const RangePanel = forwardRef<HTMLDivElement, RangePanelProps>((props, ref) => {
month: endMonth,
mode,
firstDayOfWeek,
cancelRangeSelectLimit,
...disableDateOptions,
});

Expand Down
5 changes: 5 additions & 0 deletions src/date-picker/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,11 @@ export interface TdDateRangePickerProps {
* @default false
*/
allowInput?: boolean;
/**
* 默认的日期选择交互是根据点击前后日期的顺序来决定并且会加以限制。比如:用户先点击开始时间输入框,选择了一个日期例如2020-05-15,紧接着交互会自动将焦点跳到结束日期输入框,等待用户选择结束时间。此时用户只能选择大于2020-05-15的日期(之前的日期会被灰态禁止点击,限制用户的点击)。当该值传递`true`时,则取消该限制。
* @default false
*/
cancelRangeSelectLimit?: boolean;
/**
* 是否显示清除按钮
* @default false
Expand Down
Loading

0 comments on commit 23a40c4

Please sign in to comment.