Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/components/date-picker/DatePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export default defineComponent({
const formatRef = computed(() =>
getDefaultFormat({
mode: props.mode,
format: props.format,
format: props.format || globalConfig.value.format,
valueType: props.valueType,
enableTimePicker: props.multiple ? false : props.enableTimePicker,
}),
Expand Down
1 change: 1 addition & 0 deletions packages/components/date-picker/DatePickerPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export default defineComponent({
mode: props.mode,
format: props.format,
enableTimePicker: props.enableTimePicker,
defaultTime: props.defaultTime,
}),
);

Expand Down
1 change: 1 addition & 0 deletions packages/components/date-picker/DateRangePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export default defineComponent({
enableTimePicker: props.enableTimePicker,
format: props.format,
valueType: props.valueType,
defaultTime: props.defaultTime,
}),
);

Expand Down
1 change: 1 addition & 0 deletions packages/components/date-picker/DateRangePickerPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export default defineComponent({
mode: props.mode,
enableTimePicker: props.enableTimePicker,
format: props.format,
defaultTime: props.defaultTime,
}),
);

Expand Down
170 changes: 169 additions & 1 deletion packages/components/date-picker/__tests__/date-picker.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import MockDate from 'mockdate';
import DatePicker, { DateRangePicker } from '@tdesign/components/date-picker';
import DatePicker, { DateRangePicker, DatePickerPanel, DateRangePickerPanel } from '@tdesign/components/date-picker';
import dayjs from 'dayjs';

// 固定时间,当使用 new Date() 时,返回固定时间,防止“当前时间”的副作用影响,导致 snapshot 变更,mockdate 插件见 https://github.com/boblauer/MockDate
MockDate.set('2020-12-28');
Expand Down Expand Up @@ -49,4 +51,170 @@ describe('DatePicker', () => {
});
expect(wrapper.element).toMatchSnapshot();
});

it("DatePicker: :defaultTime[string] & :valueType['time-stamp'] without enableTimePicker", async () => {
// 测试 DatePicker 当 valueType 为 time-stamp 且提供 defaultTime 但不启用 enableTimePicker 时
const defaultTime = '10:30:45';
const onChange = vi.fn();
const attachClass = 'date-picker-test-attach';

const wrapper = mount({
render() {
return (
<div class={attachClass}>
<DatePicker
defaultTime={defaultTime}
valueType={'time-stamp'}
onChange={onChange}
popupProps={{ attach: `.${attachClass}` }}
/>
</div>
);
},
});

const trigger = wrapper.find('.t-input');
await trigger.trigger('mousedown');
await trigger.trigger('mouseup');
await trigger.trigger('click');
await nextTick();
await new Promise((resolve) => setTimeout(resolve, 0));

// 在局部容器中查找日期单元格
const cells = Array.from(wrapper.element.querySelectorAll('td.t-date-picker__cell')) as HTMLElement[];
const targetCell = cells.find((cell) => {
return cell.textContent?.trim() === '15' && !cell.className.includes('--additional');
});

expect(targetCell).toBeTruthy();
if (targetCell) {
targetCell.click();
await nextTick();
}

expect(onChange).toHaveBeenCalled();

const value = onChange.mock.calls[0][0];
const ctx = onChange.mock.calls[0][1];
const expectedTimestamp = dayjs('2020-12-15 10:30:45').valueOf();

expect(value).toBe(expectedTimestamp);
expect(dayjs(ctx?.dayjsValue).format('YYYY-MM-DD HH:mm:ss')).toBe('2020-12-15 10:30:45');
});

it("DateRangePicker: :defaultTime[array] & :valueType['time-stamp'] without enableTimePicker", async () => {
// 测试 DateRangePicker 当 valueType 为 time-stamp 且提供 defaultTime 但不启用 enableTimePicker 时
const defaultTime = ['08:15:30', '18:45:20'];
const onChange = vi.fn();
const attachClass = 'date-range-picker-test-attach';

const wrapper = mount({
render() {
return (
<div class={attachClass}>
<DateRangePicker
defaultTime={defaultTime}
valueType={'time-stamp'}
onChange={onChange}
popupProps={{ attach: `.${attachClass}` }}
/>
</div>
);
},
});

const trigger = wrapper.find('.t-input');
await trigger.trigger('mousedown');
await trigger.trigger('mouseup');
await trigger.trigger('click');
await nextTick();
await new Promise((resolve) => setTimeout(resolve, 0));

// 选择开始和结束日期
const cells = Array.from(wrapper.element.querySelectorAll('td.t-date-picker__cell')) as HTMLElement[];
const matchCell = (text: string) =>
cells.find((cell) => cell.textContent?.trim() === text && !cell.className.includes('--additional'));
const startCell = matchCell('10');
const endCell = matchCell('20');

expect(startCell).toBeTruthy();
expect(endCell).toBeTruthy();
if (startCell) {
startCell.click();
await nextTick();
}
if (endCell) {
endCell.click();
await nextTick();
}

expect(onChange).toHaveBeenCalled();
const value = onChange.mock.calls[0][0] as number[];
const ctx = onChange.mock.calls[0][1];
const expectedRange = [dayjs('2020-12-10 08:15:30').valueOf(), dayjs('2020-12-20 18:45:20').valueOf()];

expect(Array.isArray(value)).toBe(true);
expect(value).toHaveLength(2);

expect(value[0]).toBe(expectedRange[0]);
expect(value[1]).toBe(expectedRange[1]);

const dayjsValues = ctx?.dayjsValue;
expect(Array.isArray(dayjsValues)).toBe(true);
expect(dayjs(dayjsValues[0]).format('YYYY-MM-DD HH:mm:ss')).toBe('2020-12-10 08:15:30');
expect(dayjs(dayjsValues[1]).format('YYYY-MM-DD HH:mm:ss')).toBe('2020-12-20 18:45:20');
});

it('DatePickerPanel: defaultTime applied to dayjsValue (no valueType)', async () => {
// Panel 不支持 valueType,这里仅传入 defaultTime 并验证 dayjsValue 的精确时间
const defaultTime = '12:34:56';
const onChange = vi.fn();

const wrapper = mount({
render() {
return <DatePickerPanel defaultTime={defaultTime} onChange={onChange} />;
},
});

// 查找非附加日期单元格(例如 '15')并点击
const cells = wrapper.findAll('td.t-date-picker__cell');
const targetCell = cells.find((c) => c.text() === '15' && !c.classes().some((cn) => cn.includes('--additional')));
expect(targetCell).toBeTruthy();
if (targetCell) await targetCell.trigger('click');

expect(onChange).toHaveBeenCalled();
const ctx = onChange.mock.calls[0][1];
// 仅校验 dayjsValue 对应的精确时间
// 验证 dayjsValue 包含正确的时间(不关心第一个参数类型)
expect(dayjs(ctx?.dayjsValue).format('YYYY-MM-DD HH:mm:ss')).toBe('2020-12-15 12:34:56');
});

it('DateRangePickerPanel: defaultTime applied to dayjsValue array (no valueType)', async () => {
// Panel 不支持 valueType,这里仅传入 defaultTime 并验证 dayjsValue 数组的精确时间
const defaultTime = ['01:02:03', '04:05:06'];
const onChange = vi.fn();

const wrapper = mount({
render() {
return <DateRangePickerPanel defaultTime={defaultTime} onChange={onChange} />;
},
});

// 点击两个非附加日期单元格(例如 '10' 和 '20')以选择范围
const cells = wrapper.findAll('td.t-date-picker__cell');
const start = cells.find((c) => c.text() === '10' && !c.classes().some((cn) => cn.includes('--additional')));
const end = cells.find((c) => c.text() === '20' && !c.classes().some((cn) => cn.includes('--additional')));
expect(start).toBeTruthy();
expect(end).toBeTruthy();
if (start) await start.trigger('click');
if (end) await end.trigger('click');

expect(onChange).toHaveBeenCalled();
const ctx = onChange.mock.calls[0][1];
// 仅验证 dayjsValue 包含正确的时间
const dayjsValues = ctx?.dayjsValue;
expect(Array.isArray(dayjsValues)).toBe(true);
expect(dayjs(dayjsValues[0]).format('YYYY-MM-DD HH:mm:ss')).toBe('2020-12-10 01:02:03');
expect(dayjs(dayjsValues[1]).format('YYYY-MM-DD HH:mm:ss')).toBe('2020-12-20 04:05:06');
});
});
16 changes: 6 additions & 10 deletions packages/components/date-picker/_example/base.vue
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
<template>
<t-space direction="vertical">
<t-date-picker v-model="date2" @change="handleChange" />
<t-date-picker
v-model="date"
placeholder="可清除、可输入的日期选择器"
clearable
allow-input
<t-date-range-picker
value-type="time-stamp"
format="YYYY-MM-DD"
:default-time="defaultTime"
@change="handleChange"
/>
</t-space>
</template>

<script setup>
import { ref } from 'vue';
const defaultTime = ['00:00:00', '23:59:59'];

const date = ref('');
const date2 = ref('');
const date = ref([]);

Check warning on line 16 in packages/components/date-picker/_example/base.vue

View workflow job for this annotation

GitHub Actions / lint

'date' is assigned a value but never used. Allowed unused vars must match /^_/u

function handleChange(value, context) {
console.log('onChange:', value, context);
console.log('timestamp:', context.dayjsValue.valueOf());
console.log('YYYYMMDD:', context.dayjsValue.format('YYYYMMDD'));
}
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export default defineComponent({
value: [String, Number, Array, Date],
internalYear: Array as PropType<Array<number>>,
disableTime: Function as PropType<TdDateRangePickerProps['disableTime']>,
defaultTime: [String, Array] as PropType<TdDatePickerProps['defaultTime'] | TdDateRangePickerProps['defaultTime']>,
},
setup(props) {
const COMPONENT_NAME = usePrefixClass('date-picker__panel');
Expand All @@ -46,6 +47,7 @@ export default defineComponent({
mode: props.mode,
format: props.format,
enableTimePicker: props.enableTimePicker,
defaultTime: props.defaultTime,
});

const disableTimeOptions = () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export default defineComponent({
month: Array as PropType<Array<number>>,
time: Array as PropType<Array<string>>,
cancelRangeSelectLimit: Boolean,
defaultTime: Array as PropType<TdDateRangePickerProps['defaultTime']>,
onClick: Function,
onCellClick: Function,
onCellMouseEnter: Function,
Expand All @@ -57,6 +58,7 @@ export default defineComponent({
mode: props.mode,
format: props.format,
enableTimePicker: props.enableTimePicker,
defaultTime: props.defaultTime,
})?.format,
);

Expand Down Expand Up @@ -148,6 +150,7 @@ export default defineComponent({
onCellMouseLeave: props.onCellMouseLeave,
onTimePickerChange: props.onTimePickerChange,
disableTime: props.disableTime,
defaultTime: props.defaultTime,
}));

return () => (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export default defineComponent({
popupVisible: Boolean,
multiple: Boolean,
needConfirm: Boolean,
defaultTime: [String, Array] as PropType<TdDatePickerProps['defaultTime']>,
onPanelClick: Function,
onCellClick: Function,
onCellMouseEnter: Function,
Expand All @@ -52,6 +53,7 @@ export default defineComponent({
mode: props.mode,
format: props.format,
enableTimePicker: props.enableTimePicker,
defaultTime: props.defaultTime,
})?.format,
);

Expand Down Expand Up @@ -100,6 +102,7 @@ export default defineComponent({
onCellMouseEnter: props.onCellMouseEnter,
onCellMouseLeave: props.onCellMouseLeave,
onTimePickerChange: props.onTimePickerChange,
defaultTime: props.defaultTime,
}));

const extraProps = computed(() => ({
Expand Down
1 change: 1 addition & 0 deletions packages/components/date-picker/hooks/useRange.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export function useRange(props: TdDateRangePickerProps) {
format: props.format,
valueType: props.valueType,
enableTimePicker: props.enableTimePicker,
defaultTime: props.defaultTime,
}),
);

Expand Down
1 change: 1 addition & 0 deletions packages/components/date-picker/hooks/useRangeValue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export function useRangeValue(props: TdDateRangePickerProps) {
format: props.format,
valueType: props.valueType,
enableTimePicker: props.enableTimePicker,
defaultTime: props.defaultTime,
}),
);

Expand Down
1 change: 1 addition & 0 deletions packages/components/date-picker/hooks/useSingle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export function useSingle(props: TdDatePickerProps) {
format: props.format,
valueType: props.valueType,
enableTimePicker: props.multiple ? false : props.enableTimePicker,
defaultTime: props.defaultTime,
}),
);

Expand Down
1 change: 1 addition & 0 deletions packages/components/date-picker/hooks/useSingleValue.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export function useSingleValue(props: TdDatePickerProps) {
mode: props.mode,
format: props.format,
enableTimePicker: props.multiple ? false : props.enableTimePicker,
defaultTime: props.defaultTime,
}),
);

Expand Down
Loading