From 647a3acb42502aa785ce09e5cbdece5274e78083 Mon Sep 17 00:00:00 2001 From: HaixingOoO <974758671@qq.com> Date: Tue, 3 Dec 2024 22:16:16 +0800 Subject: [PATCH] feat(datepicker): support week multiple --- src/date-picker/DatePicker.tsx | 10 ++++--- src/date-picker/_example/multiple.tsx | 24 ++++++++++++++--- src/date-picker/base/Table.tsx | 37 +++++++++++++++++++++++--- src/date-picker/panel/PanelContent.tsx | 3 ++- 4 files changed, 62 insertions(+), 12 deletions(-) diff --git a/src/date-picker/DatePicker.tsx b/src/date-picker/DatePicker.tsx index f5208a8396..a2ad5538d4 100644 --- a/src/date-picker/DatePicker.tsx +++ b/src/date-picker/DatePicker.tsx @@ -15,6 +15,7 @@ import useDefaultProps from '../hooks/useDefaultProps'; import useLatest from '../hooks/useLatest'; import useUpdateEffect from '../hooks/useUpdateEffect'; import type { TagInputRemoveContext } from '../tag-input'; +import { useLocaleReceiver } from '../locale/LocalReceiver'; export interface DatePickerProps extends TdDatePickerProps, StyledProps {} @@ -63,6 +64,7 @@ const DatePicker = forwardRef((originalProps, r setCacheValue, } = useSingle(props); + const [local] = useLocaleReceiver('datePicker'); const { format, timeFormat, valueType } = getDefaultFormat({ mode, format: props.format, @@ -240,7 +242,9 @@ const DatePicker = forwardRef((originalProps, r }, []); function processDate(date: Date) { - const isSameDate = (value as DateMultipleValue).some((val) => isSame(dayjs(val).toDate(), date)); + const isSameDate = (value as DateMultipleValue).some((val) => + isSame(parseToDayjs(val, format).toDate(), date, mode, local.dayjsLocale), + ); let currentDate: DateMultipleValue; if (!isSameDate) { @@ -248,8 +252,8 @@ const DatePicker = forwardRef((originalProps, r } else { currentDate = (value as DateMultipleValue).filter( (val) => - formatDate(val, { format, targetFormat: valueType }) !== - formatDate(date, { format, targetFormat: valueType }), + formatDate(val, { format, targetFormat: valueType, dayjsLocale: local.dayjsLocale }) !== + formatDate(date, { format, targetFormat: valueType, dayjsLocale: local.dayjsLocale }), ); } diff --git a/src/date-picker/_example/multiple.tsx b/src/date-picker/_example/multiple.tsx index ad047fdd74..9c0cff5263 100644 --- a/src/date-picker/_example/multiple.tsx +++ b/src/date-picker/_example/multiple.tsx @@ -1,9 +1,9 @@ import React, { useState } from 'react'; -import { DatePicker } from 'tdesign-react'; +import { DatePicker, Space } from 'tdesign-react'; import type { DatePickerProps, DateMultipleValue } from 'tdesign-react'; export default function YearDatePicker() { - const [defaultValue, setDefaultValue] = useState(['2000-01-04', '2000-01-03', '2000-01-05']); + const [defaultValue, setDefaultValue] = useState(['2000-01-04', '2000-01-03', '2000-01-10']); const handleChange: DatePickerProps['onChange'] = (value: DateMultipleValue, context) => { console.log('onChange:', value, context); @@ -11,14 +11,30 @@ export default function YearDatePicker() { }; return ( -
+ + {/* */} -
+ {/* */} + ); } diff --git a/src/date-picker/base/Table.tsx b/src/date-picker/base/Table.tsx index a92e0e4abc..19b5bd9131 100644 --- a/src/date-picker/base/Table.tsx +++ b/src/date-picker/base/Table.tsx @@ -1,15 +1,16 @@ import React, { useMemo } from 'react'; import classNames from 'classnames'; +import type { Dayjs } from 'dayjs'; import { useLocaleReceiver } from '../../locale/LocalReceiver'; import useConfig from '../../hooks/useConfig'; import DatePickerCell from './Cell'; -import { TdDatePickerProps } from '../type'; +import type { DateMultipleValue, DateRangeValue, DateValue, TdDatePickerProps } from '../type'; import { SinglePanelProps } from '../panel/SinglePanel'; import { PanelContentProps } from '../panel/PanelContent'; import { parseToDayjs } from '../../_common/js/date-picker/format'; export interface DatePickerTableProps - extends Pick, + extends Pick, Pick, Pick { data?: Array; @@ -55,8 +56,22 @@ const DatePickerTable = (props: DatePickerTableProps) => { // eslint-disable-next-line react-hooks/exhaustive-deps }, [mode, value, format]); + const multipleValueYearWeek = useMemo(() => { + if (mode !== 'week' || (Array.isArray(value) && !value.length)) return []; + + const DateMultipleValue = (value as DateMultipleValue).map((v) => v && parseToDayjs(v, format)); + + return DateMultipleValue.map((item) => { + const year = item?.year?.(); + const week = item?.locale?.(local.dayjsLocale)?.week?.(); + + return { year, week }; + }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [mode, value, format]); + // 高亮周区间 - const weekRowClass = (value, targetDayjs) => { + const weekRowClass = (value: DateValue | DateRangeValue, targetDayjs: Dayjs) => { if (mode !== 'week' || !value) return {}; if (Array.isArray(value)) { @@ -85,6 +100,20 @@ const DatePickerTable = (props: DatePickerTableProps) => { }; }; + // multiple + const multipleWeekRowClass = (value: DateMultipleValue, targetDayjs: Dayjs) => { + if (mode !== 'week' || (Array.isArray(value) && !value.length)) return {}; + + const isSomeYearWeek = multipleValueYearWeek.some( + (item) => item.year === targetDayjs.year() && item.week === targetDayjs.week(), + ); + return { + [`${classPrefix}-date-picker__table-${mode}-row--active`]: isSomeYearWeek, + }; + }; + + const activeRowCss = props.multiple ? multipleWeekRowClass : weekRowClass; + return (
onCellMouseLeave?.({ e })}> @@ -102,7 +131,7 @@ const DatePickerTable = (props: DatePickerTableProps) => { {row.map((col: any, j: number) => ( diff --git a/src/date-picker/panel/PanelContent.tsx b/src/date-picker/panel/PanelContent.tsx index a9c19cfbe5..4441a5e993 100644 --- a/src/date-picker/panel/PanelContent.tsx +++ b/src/date-picker/panel/PanelContent.tsx @@ -19,7 +19,7 @@ export interface PanelContentProps { timePickerProps: SinglePanelProps['timePickerProps']; firstDayOfWeek: SinglePanelProps['firstDayOfWeek']; time: SinglePanelProps['time']; - + multiple: SinglePanelProps['multiple']; popupVisible?: boolean; tableData: any[]; onMonthChange: SinglePanelProps['onMonthChange'] | RangePanelProps['onMonthChange']; @@ -104,6 +104,7 @@ export default function PanelContent(props: PanelContentProps) { time={time} format={format} firstDayOfWeek={firstDayOfWeek} + multiple={props.multiple} onCellClick={(date: Date, { e }) => onCellClick?.(date, { e, partial })} onCellMouseEnter={(date: Date) => onCellMouseEnter?.(date, { partial })} onCellMouseLeave={onCellMouseLeave}