Skip to content
Merged
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
15 changes: 8 additions & 7 deletions docs/examples/debug.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,9 @@ export default () => {
<SinglePicker
// Shared
{...sharedLocale}
picker="week"
multiple
// picker="week"
// multiple
showTime
defaultValue={[
dayjs(),
// dayjs('2000-01-01'),
Expand Down Expand Up @@ -186,12 +187,12 @@ export default () => {
}}
/>
<br />
{/* <RangePicker
<RangePicker
{...sharedLocale}
value={rangeValue}
disabledDate={() => true}
picker="time"
showTime
showTime={{
defaultValue: [dayjs('2000-01-01 01:02:03'), dayjs('2000-01-01 05:06:07')],
}}
changeOnBlur={false}
showNow
panelRender={(ori) => <>2333{ori}</>}
Expand Down Expand Up @@ -226,7 +227,7 @@ export default () => {
start: 'inputStart',
end: 'inputEnd',
}}
/> */}
/>
<br />

<button
Expand Down
27 changes: 3 additions & 24 deletions src/PickerInput/hooks/useRangePickerValue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import useLayoutEffect from 'rc-util/lib/hooks/useLayoutEffect';
import * as React from 'react';
import type { GenerateConfig } from '../../generate';
import type { InternalMode, Locale, PanelMode } from '../../interface';
import { isSame } from '../../utils/dateUtil';
import { fillTime, isSame } from '../../utils/dateUtil';
import type { RangePickerProps } from '../RangePicker';

export function offsetPanelDate<DateType = any>(
Expand Down Expand Up @@ -34,28 +34,6 @@ export function offsetPanelDate<DateType = any>(

const EMPTY_LIST = [];

/** Merge the `showTime.defaultValue` into `pickerValue` */
function fillTimePickerValue<DateType>(
generateConfig: GenerateConfig<DateType>,
date: DateType,
timePickerValue?: DateType,
) {
let tmpDate = date;

const getFn = ['getHour', 'getMinute', 'getSecond', 'getMillisecond'] as const;
const setFn = ['setHour', 'setMinute', 'setSecond', 'setMillisecond'] as const;

setFn.forEach((fn, index) => {
if (timePickerValue) {
tmpDate = generateConfig[fn](tmpDate, generateConfig[getFn[index]](timePickerValue));
} else {
tmpDate = generateConfig[fn](tmpDate, 0);
}
});

return tmpDate;
}

export default function useRangePickerValue<DateType extends object, ValueType extends DateType[]>(
generateConfig: GenerateConfig<DateType>,
locale: Locale,
Expand Down Expand Up @@ -100,7 +78,8 @@ export default function useRangePickerValue<DateType extends object, ValueType e
// Current PickerValue
const currentPickerValue = React.useMemo(
() =>
fillTimePickerValue(
// Merge the `showTime.defaultValue` into `pickerValue`
fillTime(
generateConfig,
[mergedStartPickerValue, mergedEndPickerValue][mergedActiveIndex],
timeDefaultValue[mergedActiveIndex],
Expand Down
27 changes: 23 additions & 4 deletions src/PickerPanel/DateTimePanel/index.tsx
Original file line number Diff line number Diff line change
@@ -1,27 +1,46 @@
import * as React from 'react';
import useTimeInfo from '../../hooks/useTimeInfo';
import type { SharedPanelProps } from '../../interface';
import { fillTime } from '../../utils/dateUtil';
import DatePanel from '../DatePanel';
import TimePanel from '../TimePanel';

export default function DateTimePanel<DateType extends object = any>(
props: SharedPanelProps<DateType>,
) {
const { prefixCls, generateConfig, showTime, onSelect } = props;
const { prefixCls, generateConfig, showTime, onSelect, value, pickerValue, onHover } = props;

const panelPrefixCls = `${prefixCls}-datetime-panel`;

// ============================== Select ==============================
// =============================== Time ===============================
const [getValidTime] = useTimeInfo(generateConfig, showTime);

// Merge the time info from `value` or `pickerValue`
const mergeTime = (date: DateType) => {
if (value) {
return fillTime(generateConfig, date, value);
}

return fillTime(generateConfig, date, pickerValue);
};

// ============================== Hover ===============================
const onDateHover = (date: DateType) => {
onHover(date ? mergeTime(date) : date);
};

// ============================== Select ==============================
const onDateSelect = (date: DateType) => {
onSelect(getValidTime(date, date));
// Merge with current time
const cloneDate = mergeTime(date);

onSelect(getValidTime(cloneDate, cloneDate));
};

// ============================== Render ==============================
return (
<div className={panelPrefixCls}>
<DatePanel {...props} onSelect={onDateSelect} />
<DatePanel {...props} onSelect={onDateSelect} onHover={onDateHover} />
<TimePanel {...props} />
</div>
);
Expand Down
87 changes: 24 additions & 63 deletions src/utils/dateUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,6 @@ import type { CustomFormat, InternalMode, Locale, NullableDateType } from '../in

export const WEEK_DAY_COUNT = 7;

// export function isNullEqual<T>(value1: T, value2: T): boolean | undefined {
// if (!value1 && !value2) {
// return true;
// }
// if (!value1 || !value2) {
// return false;
// }
// return undefined;
// }

/**
* Wrap the compare logic.
* This will compare the each of value is empty first.
Expand Down Expand Up @@ -79,16 +69,6 @@ export function isSameMonth<DateType>(
month1: NullableDateType<DateType>,
month2: NullableDateType<DateType>,
) {
// const equal = isNullEqual(month1, month2);
// if (typeof equal === 'boolean') {
// return equal;
// }

// return (
// isSameYear(generateConfig, month1, month2) &&
// generateConfig.getMonth(month1!) === generateConfig.getMonth(month2!)
// );

return nullableCompare(
month1,
month2,
Expand All @@ -103,17 +83,6 @@ export function isSameDate<DateType>(
date1: NullableDateType<DateType>,
date2: NullableDateType<DateType>,
) {
// const equal = isNullEqual(date1, date2);
// if (typeof equal === 'boolean') {
// return equal;
// }

// return (
// generateConfig.getYear(date1!) === generateConfig.getYear(date2!) &&
// generateConfig.getMonth(date1!) === generateConfig.getMonth(date2!) &&
// generateConfig.getDate(date1!) === generateConfig.getDate(date2!)
// );

return nullableCompare(
date1,
date2,
Expand All @@ -129,17 +98,6 @@ export function isSameTime<DateType>(
time1: NullableDateType<DateType>,
time2: NullableDateType<DateType>,
) {
// const equal = isNullEqual(time1, time2);
// if (typeof equal === 'boolean') {
// return equal;
// }

// return (
// generateConfig.getHour(time1!) === generateConfig.getHour(time2!) &&
// generateConfig.getMinute(time1!) === generateConfig.getMinute(time2!) &&
// generateConfig.getSecond(time1!) === generateConfig.getSecond(time2!)
// );

return nullableCompare(
time1,
time2,
Expand All @@ -158,15 +116,6 @@ export function isSameTimestamp<DateType>(
time1: NullableDateType<DateType>,
time2: NullableDateType<DateType>,
) {
// return (
// // Same object
// time1 === time2 ||
// // Date
// (isSameDate(generateConfig, time1, time2) &&
// isSameTime(generateConfig, time1, time2) &&
// generateConfig.getMillisecond(time1) === generateConfig.getMillisecond(time2))
// );

return nullableCompare(
time1,
time2,
Expand All @@ -183,18 +132,6 @@ export function isSameWeek<DateType>(
date1: NullableDateType<DateType>,
date2: NullableDateType<DateType>,
) {
// const equal = isNullEqual(date1, date2);
// if (typeof equal === 'boolean') {
// return equal;
// }

// const weekStartDate1 = getWeekStartDate(locale, generateConfig, date1);
// const weekStartDate2 = getWeekStartDate(locale, generateConfig, date2);

// return (
// isSameYear(generateConfig, weekStartDate1, weekStartDate2) &&
// generateConfig.locale.getWeek(locale, date1) === generateConfig.locale.getWeek(locale, date2)
// );
return nullableCompare(date1, date2, () => {
const weekStartDate1 = getWeekStartDate(locale, generateConfig, date1);
const weekStartDate2 = getWeekStartDate(locale, generateConfig, date2);
Expand Down Expand Up @@ -300,3 +237,27 @@ export function formatValue<DateType>(
? format(value)
: generateConfig.locale.format(locale.locale, value, format);
}

/**
* Fill the time info into Date if provided.
*/
export function fillTime<DateType>(
generateConfig: GenerateConfig<DateType>,
date: DateType,
time?: DateType,
) {
let tmpDate = date;

const getFn = ['getHour', 'getMinute', 'getSecond', 'getMillisecond'] as const;
const setFn = ['setHour', 'setMinute', 'setSecond', 'setMillisecond'] as const;

setFn.forEach((fn, index) => {
if (time) {
tmpDate = generateConfig[fn](tmpDate, generateConfig[getFn[index]](time));
} else {
tmpDate = generateConfig[fn](tmpDate, 0);
}
});

return tmpDate;
}
30 changes: 28 additions & 2 deletions tests/picker.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1287,10 +1287,36 @@ describe('Picker.Basic', () => {
/>,
);

// console.log(document.body.innerHTML);

expect(document.querySelector('.rc-picker-time-panel .rc-picker-header').textContent).toBe(
'03:05:07',
);
});

it('select date should keep time with showTime', () => {
const onCalendarChange = jest.fn();
const { container } = render(<DayPicker showTime onCalendarChange={onCalendarChange} />);

openPicker(container);

// Select time column
selectColumn(0, 13);
expect(onCalendarChange).toHaveBeenCalledWith(
expect.anything(),
'1990-09-03 13:00:00',
expect.anything(),
);

// Hover date
const cell = findCell(18);
fireEvent.mouseEnter(cell);
expect(container.querySelector('input')).toHaveValue('1990-09-18 13:00:00');

// Click to trigger onChange
fireEvent.click(cell);
expect(onCalendarChange).toHaveBeenCalledWith(
expect.anything(),
'1990-09-18 13:00:00',
expect.anything(),
);
});
});