@@ -10,7 +10,7 @@ import classNames from 'classnames';
1010
1111import parseTNode from '../_util/parseTNode' ;
1212import { Button , ButtonProps } from '../button' ;
13- import { TDateType , CalendarValue } from './type' ;
13+ import { TDateType , CalendarValue , TCalendarValue } from './type' ;
1414import { usePrefixClass } from '../hooks/useClass' ;
1515import useDefaultProps from '../hooks/useDefaultProps' ;
1616import { calendarDefaultProps } from './defaultProps' ;
@@ -46,27 +46,67 @@ const CalendarTemplate = forwardRef<HTMLDivElement, CalendarProps>((_props, ref)
4646 } ) ;
4747 const firstDayOfWeek = props . firstDayOfWeek || 0 ;
4848
49- useEffect ( ( ) => {
50- if ( Array . isArray ( props . value ) ) {
51- setSelectedDate ( props . value ?. map ( ( item ) => new Date ( item ) ) ) ;
52- } else if ( props . value ) {
53- setSelectedDate ( new Date ( props . value ) ) ;
54- } else {
55- setSelectedDate ( props . type === 'multiple' ? [ new Date ( ) ] : new Date ( ) ) ;
56- }
57- } , [ props . type , props . value ] ) ;
58-
5949 const getYearMonthDay = ( date : Date ) => ( {
6050 year : date . getFullYear ( ) ,
6151 month : date . getMonth ( ) ,
6252 date : date . getDate ( ) ,
6353 } ) ;
6454
65- const today = new Date ( ) ;
66- const minDate = props . minDate ? new Date ( props . minDate ) : today ;
67- const maxDate = props . maxDate
68- ? new Date ( props . maxDate )
69- : new Date ( today . getFullYear ( ) , today . getMonth ( ) + 6 , today . getDate ( ) ) ;
55+ const today = useMemo ( ( ) => new Date ( ) , [ ] ) ;
56+ const minDate = useMemo ( ( ) => ( props . minDate ? new Date ( props . minDate ) : today ) , [ props . minDate , today ] ) ;
57+ const maxDate = useMemo (
58+ ( ) =>
59+ props . maxDate ? new Date ( props . maxDate ) : new Date ( today . getFullYear ( ) , today . getMonth ( ) + 6 , today . getDate ( ) ) ,
60+ [ props . maxDate , today ] ,
61+ ) ;
62+
63+ const dateTypeHandler = useMemo ( ( ) => {
64+ const now = minDate ;
65+
66+ const createRangePair = ( baseDate : Date ) : [ Date , Date ] =>
67+ props . allowSameDay ? [ baseDate , baseDate ] : [ baseDate , new Date ( baseDate . getTime ( ) + 24 * 3600 * 1000 ) ] ;
68+
69+ const convertToDateArray = ( value : TCalendarValue [ ] ) : Date [ ] => value . map ( ( item ) => new Date ( item ) ) ;
70+
71+ return {
72+ // 初始化空日期
73+ initialize : {
74+ single : ( ) => now ,
75+ multiple : ( ) => [ now ] ,
76+ range : ( ) => createRangePair ( now ) ,
77+ } ,
78+ // 转换已有值
79+ transform : {
80+ single : ( value : TCalendarValue ) : Date => new Date ( value ) ,
81+
82+ multiple : ( value : TCalendarValue [ ] ) : Date [ ] => {
83+ const dates = convertToDateArray ( value ) ;
84+ return dates . length ? dates : [ now ] ;
85+ } ,
86+ range : ( value : TCalendarValue [ ] ) : Date [ ] => {
87+ const dates = convertToDateArray ( value ) ;
88+ // 传入值为空数组或只有一个值时
89+ if ( dates . length <= 1 ) {
90+ return createRangePair ( dates [ 0 ] || now ) ;
91+ }
92+ return dates ;
93+ } ,
94+ } ,
95+ } ;
96+ } , [ props . allowSameDay , minDate ] ) ;
97+
98+ useEffect ( ( ) => {
99+ if ( ! props . value ) {
100+ setSelectedDate ( dateTypeHandler . initialize [ props . type ] ?.( ) ) ;
101+ } else {
102+ const d =
103+ props . type === 'single'
104+ ? dateTypeHandler . transform . single ?.( props . value as TCalendarValue )
105+ : dateTypeHandler . transform [ props . type ] ?.( props . value as TCalendarValue [ ] ) ;
106+
107+ setSelectedDate ( d ) ;
108+ }
109+ } , [ props . type , props . value , dateTypeHandler ] ) ;
70110
71111 const days = useMemo ( ( ) => {
72112 const raw = local . weekdays ;
@@ -251,13 +291,18 @@ const CalendarTemplate = forwardRef<HTMLDivElement, CalendarProps>((_props, ref)
251291 switch ( props . type ) {
252292 case 'range' : {
253293 if ( Array . isArray ( selectedDate ) ) {
254- if ( selectedDate . length === 1 && selected >= selectedDate [ 0 ] ) {
255- newSelected = selectedDate [ 0 ] > selected ? [ selected ] : [ selectedDate [ 0 ] , selected ] ;
294+ if ( selectedDate . length === 1 ) {
295+ const firstDate = selectedDate [ 0 ] ;
296+ if ( selected . getTime ( ) === new Date ( firstDate ) . getTime ( ) ) {
297+ newSelected = props . allowSameDay ? [ firstDate , selected ] : [ selected ] ;
298+ } else if ( selected < firstDate ) {
299+ newSelected = [ selected ] ;
300+ } else {
301+ newSelected = [ firstDate , selected ] ;
302+ }
256303 } else {
257304 newSelected = [ selected ] ;
258305 }
259- } else {
260- newSelected = [ selected ] ;
261306 }
262307 break ;
263308 }
0 commit comments