Skip to content

Commit 90312c8

Browse files
authored
feat(DatePicker): support disableTime API (#3324)
* fix(TimePicker): fixed only support hh:mm format * fix(TimePicker): disabled position only is start * fix(Upload): fixed vue error on uploadPastedFiles is false * docs: add readonly in api * feat(DatePicker): add disableTime prop
1 parent d7bb099 commit 90312c8

14 files changed

+118
-34
lines changed

src/date-picker/DatePicker.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ export default defineComponent({
237237
presets: props.presets,
238238
time: time.value as string,
239239
disableDate: props.disableDate,
240+
disableTime: props.disableTime,
240241
firstDayOfWeek: props.firstDayOfWeek,
241242
timePickerProps: props.timePickerProps,
242243
enableTimePicker: props.enableTimePicker,

src/date-picker/DateRangePicker.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,7 @@ export default defineComponent({
403403
presets: props.presets,
404404
time: time.value,
405405
disableDate: props.disableDate,
406+
disableTime: props.disableTime,
406407
firstDayOfWeek: props.firstDayOfWeek,
407408
timePickerProps: props.timePickerProps,
408409
enableTimePicker: props.enableTimePicker,

src/date-picker/DateRangePickerPanel.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export default defineComponent({
2626
defaultValue: dateRangePickerProps.defaultValue,
2727
disabled: dateRangePickerProps.disabled,
2828
disableDate: dateRangePickerProps.disableDate,
29+
disableTime: dateRangePickerProps.disableTime,
2930
enableTimePicker: dateRangePickerProps.enableTimePicker,
3031
firstDayOfWeek: dateRangePickerProps.firstDayOfWeek,
3132
format: dateRangePickerProps.format,
@@ -391,6 +392,7 @@ export default defineComponent({
391392
presets: props.presets,
392393
time: time.value,
393394
disableDate: props.disableDate,
395+
disableTime: props.disableTime,
394396
firstDayOfWeek: props.firstDayOfWeek,
395397
timePickerProps: props.timePickerProps,
396398
enableTimePicker: props.enableTimePicker,

src/date-picker/_example-composition/disable-date.vue

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@
2323
placeholder="禁用日期精确到时间"
2424
enable-time-picker
2525
:disable-date="{ before: dayjs().subtract(1, 'day').format() }"
26-
:time-picker-props="timePickerProps"
27-
@pick="(date) => (pickDate = dayjs(date).format('YYYY-MM-DD'))"
26+
:disable-time="disableTime"
2827
/>
2928
<t-date-range-picker
3029
placeholder="禁用最近 5 天外的日期"
@@ -37,18 +36,14 @@
3736
</template>
3837

3938
<script setup>
40-
import { ref, computed } from 'vue';
4139
import dayjs from 'dayjs';
4240
43-
const pickDate = ref('');
44-
const timePickerProps = computed(() => ({
45-
disableTime: () => {
46-
if (pickDate.value === dayjs().format('YYYY-MM-DD')) {
47-
return {
48-
hour: [0, 1, 2, 3, 4, 5, 6],
49-
};
50-
}
51-
return {};
52-
},
53-
}));
41+
const disableTime = (time) => {
42+
if (dayjs(time).format('YYYY-MM-DD') === dayjs().format('YYYY-MM-DD')) {
43+
return {
44+
hour: [0, 1, 2, 3, 4, 5, 6],
45+
};
46+
}
47+
return {};
48+
};
5449
</script>

src/date-picker/_example/disable-date.vue

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@
2323
placeholder="禁用日期精确到时间"
2424
enable-time-picker
2525
:disable-date="{ before: dayjs().subtract(1, 'day').format() }"
26-
:time-picker-props="timePickerProps"
27-
@pick="(date) => (pickDate = dayjs(date).format('YYYY-MM-DD'))"
26+
:disable-time="disableTime"
2827
/>
2928
<t-date-range-picker
3029
placeholder="禁用最近 5 天外的日期"
@@ -41,20 +40,16 @@ import dayjs from 'dayjs';
4140
4241
export default {
4342
data() {
44-
return { pickDate: '', dayjs };
43+
return { dayjs };
4544
},
46-
computed: {
47-
timePickerProps() {
48-
return {
49-
disableTime: () => {
50-
if (this.pickDate === dayjs().format('YYYY-MM-DD')) {
51-
return {
52-
hour: [0, 1, 2, 3, 4, 5, 6],
53-
};
54-
}
55-
return {};
56-
},
57-
};
45+
methods: {
46+
disableTime: (time) => {
47+
if (dayjs(time).format('YYYY-MM-DD') === dayjs().format('YYYY-MM-DD')) {
48+
return {
49+
hour: [0, 1, 2, 3, 4, 5, 6],
50+
};
51+
}
52+
return {};
5853
},
5954
},
6055
};

src/date-picker/date-picker.en-US.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ borderless | Boolean | false | \- | N
1111
clearable | Boolean | false | \- | N
1212
defaultTime | String | '00:00:00' | Time selector default value | N
1313
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-vue/tree/develop/src/date-picker/type.ts) | N
14+
disableTime | Function | - | disable time config function。Typescript:`(time: Date) => Partial<{ hour: Array<number>, minute: Array<number>, second: Array<number>, millisecond: Array<number> }>`[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/date-picker/type.ts) | N
1415
disabled | Boolean | - | make DatePicker to be disabled | N
1516
enableTimePicker | Boolean | false | \- | N
1617
firstDayOfWeek | Number | 7 | options: 1/2/3/4/5/6/7 | N
@@ -60,6 +61,7 @@ borderless | Boolean | false | \- | N
6061
clearable | Boolean | false | \- | N
6162
defaultTime | Array | ["00:00:00", "23:59:59"] | Time selector default value。Typescript:`string[]` | N
6263
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-vue/tree/develop/src/date-picker/type.ts) | N
64+
disableTime | Function | - | Typescript:`(times: [Date \| null, Date \| null], context: { partial: DateRangePickerPartial }) => Partial<{ hour: Array<number>, minute: Array<number>, second: Array<number> }>`[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/date-picker/type.ts) | N
6365
disabled | Boolean | - | \- | N
6466
enableTimePicker | Boolean | false | \- | N
6567
firstDayOfWeek | Number | - | options: 1/2/3/4/5/6/7 | N
@@ -108,7 +110,7 @@ preset-click | `(context: { preset: PresetDate, e: MouseEvent })` | \-
108110
name | type | default | description | required
109111
-- | -- | -- | -- | --
110112
defaultTime | String | '00:00:00' | Time selector default value | N
111-
`Pick<DatePickerProps, 'value' \| 'defaultValue' \| 'disableDate' \| 'enableTimePicker' \| 'firstDayOfWeek' \| 'format' \| 'mode' \| 'presets' \| 'presetsPlacement' \| 'timePickerProps'>` | \- | - | extends `Pick<DatePickerProps, 'value' \| 'defaultValue' \| 'disableDate' \| 'enableTimePicker' \| 'firstDayOfWeek' \| 'format' \| 'mode' \| 'presets' \| 'presetsPlacement' \| 'timePickerProps'>` | N
113+
`Pick<DatePickerProps, 'value' \| 'defaultValue' \| 'disableDate' \| 'disableTime' \| 'enableTimePicker' \| 'firstDayOfWeek' \| 'format' \| 'mode' \| 'presets' \| 'presetsPlacement' \| 'timePickerProps'>` | \- | - | extends `Pick<DatePickerProps, 'value' \| 'defaultValue' \| 'disableDate' \| 'disableTime' \| 'enableTimePicker' \| 'firstDayOfWeek' \| 'format' \| 'mode' \| 'presets' \| 'presetsPlacement' \| 'timePickerProps'>` | N
112114
onCellClick | Function | | Typescript:`(context: { date: Date, e: MouseEvent }) => void`<br/> | N
113115
onChange | Function | | Typescript:`(value: DateValue, context: { dayjsValue?: Dayjs, e?: MouseEvent, trigger?: DatePickerTriggerSource }) => void`<br/> | N
114116
onConfirm | Function | | Typescript:`(context: { date: Date, e: MouseEvent }) => void`<br/> | N

src/date-picker/date-picker.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ borderless | Boolean | false | 无边框模式 | N
1111
clearable | Boolean | false | 是否显示清除按钮 | N
1212
defaultTime | String | '00:00:00' | 时间选择器默认值,当 value/defaultValue 未设置值时有效 | N
1313
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 类型:`DisableDate` `type DisableDate = Array<DateValue> \| DisableDateObj \| ((date: DateValue) => boolean)` `interface DisableDateObj { from?: string; to?: string; before?: string; after?: string }`[详细类型定义](https://github.com/Tencent/tdesign-vue/tree/develop/src/date-picker/type.ts) | N
14+
disableTime | Function | - | 禁用时间项的配置函数。TS 类型:`(time: Date) => Partial<{ hour: Array<number>, minute: Array<number>, second: Array<number>, millisecond: Array<number> }>`[详细类型定义](https://github.com/Tencent/tdesign-vue/tree/develop/src/date-picker/type.ts) | N
1415
disabled | Boolean | - | 是否禁用组件 | N
1516
enableTimePicker | Boolean | false | 是否显示时间选择 | N
1617
firstDayOfWeek | Number | 7 | 第一天从星期几开始。可选项:1/2/3/4/5/6/7 | N
@@ -60,6 +61,7 @@ borderless | Boolean | false | 无边框模式 | N
6061
clearable | Boolean | false | 是否显示清除按钮 | N
6162
defaultTime | Array | ["00:00:00", "23:59:59"] | 时间选择器默认值,当 value/defaultValue 未设置值时有效。TS 类型:`string[]` | N
6263
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-vue/tree/develop/src/date-picker/type.ts) | N
64+
disableTime | Function | - | 禁用时间项的配置函数。TS 类型:`(times: [Date \| null, Date \| null], context: { partial: DateRangePickerPartial }) => Partial<{ hour: Array<number>, minute: Array<number>, second: Array<number> }>`[详细类型定义](https://github.com/Tencent/tdesign-vue/tree/develop/src/date-picker/type.ts) | N
6365
disabled | Boolean | - | 是否禁用组件 | N
6466
enableTimePicker | Boolean | false | 是否显示时间选择 | N
6567
firstDayOfWeek | Number | - | 第一天从星期几开始。可选项:1/2/3/4/5/6/7 | N
@@ -108,7 +110,7 @@ preset-click | `(context: { preset: PresetDate, e: MouseEvent })` | 点击预设
108110
名称 | 类型 | 默认值 | 描述 | 必传
109111
-- | -- | -- | -- | --
110112
defaultTime | String | '00:00:00' | 时间选择器默认值,当 value/defaultValue 未设置值时有效 | N
111-
`Pick<DatePickerProps, 'value' \| 'defaultValue' \| 'disableDate' \| 'enableTimePicker' \| 'firstDayOfWeek' \| 'format' \| 'mode' \| 'presets' \| 'presetsPlacement' \| 'timePickerProps'>` | \- | - | 继承 `Pick<DatePickerProps, 'value' \| 'defaultValue' \| 'disableDate' \| 'enableTimePicker' \| 'firstDayOfWeek' \| 'format' \| 'mode' \| 'presets' \| 'presetsPlacement' \| 'timePickerProps'>` 中的全部属性 | N
113+
`Pick<DatePickerProps, 'value' \| 'defaultValue' \| 'disableDate' \| 'disableTime' \| 'enableTimePicker' \| 'firstDayOfWeek' \| 'format' \| 'mode' \| 'presets' \| 'presetsPlacement' \| 'timePickerProps'>` | \- | - | 继承 `Pick<DatePickerProps, 'value' \| 'defaultValue' \| 'disableDate' \| 'disableTime' \| 'enableTimePicker' \| 'firstDayOfWeek' \| 'format' \| 'mode' \| 'presets' \| 'presetsPlacement' \| 'timePickerProps'>` 中的全部属性 | N
112114
onCellClick | Function | | TS 类型:`(context: { date: Date, e: MouseEvent }) => void`<br/>点击日期单元格时触发 | N
113115
onChange | Function | | TS 类型:`(value: DateValue, context: { dayjsValue?: Dayjs, e?: MouseEvent, trigger?: DatePickerTriggerSource }) => void`<br/>选中值发生变化时触发。参数 `context.trigger` 表示触发当前事件的来源,不同的模式触发来源也会不同 | N
114116
onConfirm | Function | | TS 类型:`(context: { date: Date, e: MouseEvent }) => void`<br/>如果存在“确定”按钮,则点击“确定”按钮时触发 | N
@@ -137,7 +139,7 @@ year-change | `(context: { year: number, date: Date, trigger: DatePickerYearChan
137139
名称 | 类型 | 默认值 | 描述 | 必传
138140
-- | -- | -- | -- | --
139141
defaultTime | Array | ["00:00:00", "23:59:59"] | 时间选择器默认值,当 value/defaultValue 未设置值时有效。TS 类型:`string[]` | N
140-
`Pick<DateRangePickerProps, 'value'\| 'defaultValue' \| 'disableDate' \| 'enableTimePicker' \| 'firstDayOfWeek' \| 'format' \| 'mode' \| 'presets' \| 'presetsPlacement' \| 'panelPreselection' \| 'timePickerProps'>` | \- | - | 继承 `Pick<DateRangePickerProps, 'value'\| 'defaultValue' \| 'disableDate' \| 'enableTimePicker' \| 'firstDayOfWeek' \| 'format' \| 'mode' \| 'presets' \| 'presetsPlacement' \| 'panelPreselection' \| 'timePickerProps'>` 中的全部属性 | N
142+
`Pick<DateRangePickerProps, 'value'\| 'defaultValue' \| 'disableDate' \| 'disableTime' \| 'enableTimePicker' \| 'firstDayOfWeek' \| 'format' \| 'mode' \| 'presets' \| 'presetsPlacement' \| 'panelPreselection' \| 'timePickerProps'>` | \- | - | 继承 `Pick<DateRangePickerProps, 'value'\| 'defaultValue' \| 'disableDate' \| 'disableTime' \| 'enableTimePicker' \| 'firstDayOfWeek' \| 'format' \| 'mode' \| 'presets' \| 'presetsPlacement' \| 'panelPreselection' \| 'timePickerProps'>` 中的全部属性 | N
141143
onCellClick | Function | | TS 类型:`(context: { date: Date[], partial: DateRangePickerPartial, e: MouseEvent }) => void`<br/>点击日期单元格时触发 | N
142144
onChange | Function | | TS 类型:`(value: DateRangeValue, context: { dayjsValue?: Dayjs[], partial: DateRangePickerPartial, e?: MouseEvent, trigger?: DatePickerTriggerSource }) => void`<br/>选中值发生变化时触发。参数 `context.trigger` 表示触发当前事件的来源,不同的模式触发来源也会不同 | N
143145
onConfirm | Function | | TS 类型:`(context: { date: Date[], e: MouseEvent }) => void`<br/>如果存在“确定”按钮,则点击“确定”按钮时触发 | N

src/date-picker/date-range-picker-props.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ export default {
2323
disableDate: {
2424
type: [Object, Array, Function] as PropType<TdDateRangePickerProps['disableDate']>,
2525
},
26+
/** 禁用时间项的配置函数 */
27+
disableTime: {
28+
type: Function as PropType<TdDateRangePickerProps['disableTime']>,
29+
},
2630
/** 是否禁用组件 */
2731
disabled: Boolean,
2832
/** 只读状态,值为真会隐藏输入框,且无法打开下拉框 */

src/date-picker/panel/PanelContent.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ export default defineComponent({
8787
{...{
8888
key: this.partial,
8989
props: {
90+
position: this.partial,
9091
format: timeFormat,
9192
value: this.time,
9293
onChange: this.onTimePickerChange,

src/date-picker/panel/RangePanel.tsx

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
import { defineComponent, PropType, computed } from '@vue/composition-api';
2+
import isFunction from 'lodash/isFunction';
23
import { useConfig, usePrefixClass } from '../../hooks/useConfig';
34
import TPanelContent from './PanelContent';
45
import TExtraContent from './ExtraContent';
56
import { TdDateRangePickerProps } from '../type';
67
import { getDefaultFormat, parseToDayjs } from '../../_common/js/date-picker/format';
78
import useTableData from '../hooks/useTableData';
89
import useDisableDate from '../hooks/useDisableDate';
10+
import { TdTimePickerProps, TdTimeRangePickerProps } from '../../time-picker';
11+
import { parseToDateTime } from '../utils';
912

1013
export default defineComponent({
1114
name: 'TRangePanel',
@@ -14,6 +17,7 @@ export default defineComponent({
1417
activeIndex: Number,
1518
isFirstValueSelected: Boolean,
1619
disableDate: [Object, Array, Function] as PropType<TdDateRangePickerProps['disableDate']>,
20+
disableTime: Function as PropType<TdDateRangePickerProps['disableTime']>,
1721
mode: {
1822
type: String as PropType<TdDateRangePickerProps['mode']>,
1923
default: 'date',
@@ -75,6 +79,26 @@ export default defineComponent({
7579
: undefined,
7680
}));
7781

82+
const disableTime: TdTimeRangePickerProps['disableTime'] = (h: number, m: number, s: number, context) => {
83+
if (!isFunction(props.disableTime)) {
84+
return {};
85+
}
86+
87+
const [startTime, endTime] = props.value || [];
88+
89+
if (context.partial) {
90+
return (props.disableTime as TdDateRangePickerProps['disableTime'])(
91+
[parseToDateTime(startTime, format, [h, m, s]), parseToDateTime(endTime, format)],
92+
context,
93+
);
94+
}
95+
96+
return (props.disableTime as TdDateRangePickerProps['disableTime'])(
97+
[parseToDateTime(startTime, format), parseToDateTime(endTime, format, [h, m, s])],
98+
context,
99+
);
100+
};
101+
78102
const startTableData = computed(() => useTableData({
79103
isRange: true,
80104
start: props.value[0] ? parseToDayjs(props.value[0] as string, format).toDate() : undefined,
@@ -120,7 +144,10 @@ export default defineComponent({
120144

121145
popupVisible: props.popupVisible,
122146
enableTimePicker: props.enableTimePicker,
123-
timePickerProps: props.timePickerProps,
147+
timePickerProps: {
148+
disableTime,
149+
...(props.timePickerProps as TdTimePickerProps),
150+
},
124151
onMonthChange: props.onMonthChange,
125152
onYearChange: props.onYearChange,
126153
onJumperClick: props.onJumperClick,

src/date-picker/panel/SinglePanel.tsx

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
import { defineComponent, PropType, computed } from '@vue/composition-api';
2+
import isFunction from 'lodash/isFunction';
23
import { useConfig, usePrefixClass } from '../../hooks/useConfig';
34
import TPanelContent from './PanelContent';
45
import TExtraContent from './ExtraContent';
56
import { TdDatePickerProps } from '../type';
67
import { getDefaultFormat, parseToDayjs } from '../../_common/js/date-picker/format';
78
import useTableData from '../hooks/useTableData';
89
import useDisableDate from '../hooks/useDisableDate';
10+
import { TdTimePickerProps } from '../../time-picker';
11+
import { parseToDateTime } from '../utils';
912

1013
export default defineComponent({
1114
name: 'TSinglePanel',
1215
props: {
1316
disableDate: [Object, Array, Function] as PropType<TdDatePickerProps['disableDate']>,
17+
disableTime: Function as PropType<TdDatePickerProps['disableTime']>,
1418
mode: {
1519
type: String as PropType<TdDatePickerProps['mode']>,
1620
default: 'date',
@@ -56,6 +60,14 @@ export default defineComponent({
5660
disableDate: props.disableDate,
5761
}));
5862

63+
const disableTime: TdTimePickerProps['disableTime'] = (h: number, m: number, s: number, ms: number) => {
64+
if (!isFunction(props.disableTime) || !props.value) {
65+
return {};
66+
}
67+
68+
return props.disableTime(parseToDateTime(props.value, format, [h, m, s, ms]));
69+
};
70+
5971
const tableData = computed(() => useTableData({
6072
year: props.year,
6173
month: props.month,
@@ -75,7 +87,10 @@ export default defineComponent({
7587
tableData: tableData.value,
7688
popupVisible: props.popupVisible,
7789
enableTimePicker: props.enableTimePicker,
78-
timePickerProps: props.timePickerProps,
90+
timePickerProps: {
91+
disableTime,
92+
...(props.timePickerProps as TdTimePickerProps),
93+
},
7994
time: props.time,
8095
onMonthChange: props.onMonthChange,
8196
onYearChange: props.onYearChange,

src/date-picker/props.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ export default {
2323
disableDate: {
2424
type: [Object, Array, Function] as PropType<TdDatePickerProps['disableDate']>,
2525
},
26+
/** 禁用时间项的配置函数 */
27+
disableTime: {
28+
type: Function as PropType<TdDatePickerProps['disableTime']>,
29+
},
2630
/** 是否禁用组件 */
2731
disabled: Boolean,
2832
/** 只读状态,值为真会隐藏输入框,且无法打开下拉框 */

0 commit comments

Comments
 (0)