diff --git a/src/date-picker/DateRangePicker.tsx b/src/date-picker/DateRangePicker.tsx index 133dc8e9f5..9b987736c0 100644 --- a/src/date-picker/DateRangePicker.tsx +++ b/src/date-picker/DateRangePicker.tsx @@ -40,6 +40,7 @@ const DateRangePicker = forwardRef((origin presetsPlacement, panelPreselection, onPick, + cancelRangeSelectLimit, } = props; const { @@ -297,7 +298,7 @@ const DateRangePicker = forwardRef((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)), @@ -354,6 +355,7 @@ const DateRangePicker = forwardRef((origin presetsPlacement, activeIndex, popupVisible, + cancelRangeSelectLimit, onCellClick, onCellMouseEnter, onCellMouseLeave, diff --git a/src/date-picker/DateRangePickerPanel.tsx b/src/date-picker/DateRangePickerPanel.tsx index 809de895a6..cc33d646a2 100644 --- a/src/date-picker/DateRangePickerPanel.tsx +++ b/src/date-picker/DateRangePickerPanel.tsx @@ -233,7 +233,7 @@ const DateRangePickerPanel = forwardRef parseToDayjs(p, format)), diff --git a/src/date-picker/_example/cancel-range-limit.jsx b/src/date-picker/_example/cancel-range-limit.jsx new file mode 100644 index 0000000000..c1888f41c7 --- /dev/null +++ b/src/date-picker/_example/cancel-range-limit.jsx @@ -0,0 +1,10 @@ +import React from 'react'; +import { DateRangePicker, Space } from 'tdesign-react'; + +export default function CancelRangeLimitDatePicker() { + return ( + + + + ); +} diff --git a/src/date-picker/date-picker.en-US.md b/src/date-picker/date-picker.en-US.md index 81ffe6bc9d..c7ffe5ae3e 100644 --- a/src/date-picker/date-picker.en-US.md +++ b/src/date-picker/date-picker.en-US.md @@ -13,17 +13,17 @@ defaultTime | String | '00:00:00' | Time selector default value | N disableDate | Object / Array / Function | - | Typescript:`DisableDate` `type DisableDate = Array \| 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 | options:1/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 | options:year/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 | 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 +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 @@ -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 \| 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 | - | options:1/2/3/4/5/6/7 | N +firstDayOfWeek | Number | - | options: 1/2/3/4/5/6/7 | N format | String | - | \- | N -mode | String | date | options:year/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` | 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 | options:left/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 | 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 +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`。[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`。[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/date-picker/type.ts) | 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 +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`
| N onChange | Function | | Typescript:`(value: DateRangeValue, context: { dayjsValue?: Dayjs[], trigger?: DatePickerTriggerSource }) => void`
[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/date-picker/type.ts)。
`import { Dayjs } from 'dayjs'`
| N onConfirm | Function | | Typescript:`(context: { date: Date[], e: MouseEvent, partial: DateRangePickerPartial }) => void`
| N diff --git a/src/date-picker/date-picker.md b/src/date-picker/date-picker.md index c8ab595b76..c1e59d8ed7 100644 --- a/src/date-picker/date-picker.md +++ b/src/date-picker/date-picker.md @@ -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 \| 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 diff --git a/src/date-picker/defaultProps.ts b/src/date-picker/defaultProps.ts index 5b7a6cda09..170addfaff 100644 --- a/src/date-picker/defaultProps.ts +++ b/src/date-picker/defaultProps.ts @@ -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, diff --git a/src/date-picker/hooks/useRangeValue.ts b/src/date-picker/hooks/useRangeValue.ts index 2268d618cf..0ccabb75c8 100644 --- a/src/date-picker/hooks/useRangeValue.ts +++ b/src/date-picker/hooks/useRangeValue.ts @@ -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 diff --git a/src/date-picker/hooks/useSingleValue.tsx b/src/date-picker/hooks/useSingleValue.tsx index e3fc5b4c47..58faaedcaf 100644 --- a/src/date-picker/hooks/useSingleValue.tsx +++ b/src/date-picker/hooks/useSingleValue.tsx @@ -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)); diff --git a/src/date-picker/hooks/useTableData.tsx b/src/date-picker/hooks/useTableData.tsx index 19a049d0dd..ea2887410d 100644 --- a/src/date-picker/hooks/useTableData.tsx +++ b/src/date-picker/hooks/useTableData.tsx @@ -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) { @@ -45,6 +46,7 @@ export default function useTableData(props: TableDataProps) { quarterLocal, showWeekOfYear: mode === 'week', dayjsLocale: local.dayjsLocale, + cancelRangeSelectLimit: props.cancelRangeSelectLimit, }; if (mode === 'date') { diff --git a/src/date-picker/panel/RangePanel.tsx b/src/date-picker/panel/RangePanel.tsx index 782d953ebe..6d3c0d4951 100644 --- a/src/date-picker/panel/RangePanel.tsx +++ b/src/date-picker/panel/RangePanel.tsx @@ -19,6 +19,7 @@ export interface RangePanelProps extends TdDateRangePickerProps, StyledProps { year?: number[]; month?: number[]; time?: string[]; + cancelRangeSelectLimit?: boolean; onClick?: (context: { e: React.MouseEvent }) => void; onCellClick?: (date: Date, context: { e: React.MouseEvent; partial: 'start' | 'end' }) => void; onCellMouseEnter?: (date: Date, context: { partial: 'start' | 'end' }) => void; @@ -55,6 +56,7 @@ const RangePanel = forwardRef((props, ref) => { onClick, onConfirmClick, onPresetClick, + cancelRangeSelectLimit, } = props; const { format } = getDefaultFormat({ @@ -93,6 +95,7 @@ const RangePanel = forwardRef((props, ref) => { month: startMonth, mode, firstDayOfWeek, + cancelRangeSelectLimit, ...disableDateOptions, }); const endTableData = useTableData({ @@ -105,6 +108,7 @@ const RangePanel = forwardRef((props, ref) => { month: endMonth, mode, firstDayOfWeek, + cancelRangeSelectLimit, ...disableDateOptions, }); diff --git a/src/date-picker/type.ts b/src/date-picker/type.ts index 777d89bbc9..9563e1abf7 100644 --- a/src/date-picker/type.ts +++ b/src/date-picker/type.ts @@ -148,6 +148,11 @@ export interface TdDateRangePickerProps { * @default false */ allowInput?: boolean; + /** + * 默认的日期选择交互是根据点击前后日期的顺序来决定并且会加以限制。比如:用户先点击开始时间输入框,选择了一个日期例如2020-05-15,紧接着交互会自动将焦点跳到结束日期输入框,等待用户选择结束时间。此时用户只能选择大于2020-05-15的日期(之前的日期会被灰态禁止点击,限制用户的点击)。当该值传递`true`时,则取消该限制。 + * @default false + */ + cancelRangeSelectLimit?: boolean; /** * 是否显示清除按钮 * @default false diff --git a/test/snap/__snapshots__/csr.test.jsx.snap b/test/snap/__snapshots__/csr.test.jsx.snap index 6f2ee8b1e2..7c8d27eae9 100644 --- a/test/snap/__snapshots__/csr.test.jsx.snap +++ b/test/snap/__snapshots__/csr.test.jsx.snap @@ -70026,6 +70026,227 @@ exports[`csr snapshot test > csr test src/date-picker/_example/base.jsx 1`] = ` } `; +exports[`csr snapshot test > csr test src/date-picker/_example/cancel-range-limit.jsx 1`] = ` +{ + "asFragment": [Function], + "baseElement": +