@@ -3,28 +3,30 @@ import dayjs from 'dayjs';
33import { CalendarIcon as TdCalendarIcon } from 'tdesign-icons-vue' ;
44import isDate from 'lodash/isDate' ;
55
6- import { usePrefixClass } from '../hooks/useConfig' ;
6+ import { usePrefixClass , useConfig } from '../hooks/useConfig' ;
77import { useGlobalIcon } from '../hooks/useGlobalIcon' ;
88import useSingle from './hooks/useSingle' ;
99import {
1010 parseToDayjs , getDefaultFormat , formatTime , formatDate ,
1111} from '../_common/js/date-picker/format' ;
1212import {
13- subtractMonth , addMonth , extractTimeObj , covertToDate ,
13+ subtractMonth , addMonth , extractTimeObj , covertToDate , isSame ,
1414} from '../_common/js/date-picker/utils' ;
15- import type { DateValue } from './type' ;
15+ import type { DateMultipleValue , DateValue } from './type' ;
1616import props from './props' ;
1717
1818import TSelectInput from '../select-input' ;
1919import TSinglePanel from './panel/SinglePanel' ;
2020import useFormDisabled from '../hooks/useFormDisabled' ;
21+ import type { TagInputRemoveContext } from '../tag-input' ;
2122
2223export default defineComponent ( {
2324 name : 'TDatePicker' ,
2425 props,
2526 setup ( props , { emit } ) {
2627 const COMPONENT_NAME = usePrefixClass ( 'date-picker' ) ;
2728 const { CalendarIcon } = useGlobalIcon ( { CalendarIcon : TdCalendarIcon } ) ;
29+ const { global } = useConfig ( 'datePicker' ) ;
2830
2931 const {
3032 inputValue,
@@ -45,13 +47,14 @@ export default defineComponent({
4547 mode : props . mode ,
4648 format : props . format ,
4749 valueType : props . valueType ,
48- enableTimePicker : props . enableTimePicker ,
50+ enableTimePicker : props . multiple ? false : props . enableTimePicker ,
4951 } ) ) ;
5052
5153 const { formDisabled } = useFormDisabled ( ) ;
5254 const isDisabled = computed ( ( ) => formDisabled . value || props . disabled ) ;
5355
5456 watch ( popupVisible , ( visible ) => {
57+ if ( props . multiple ) return ;
5558 // Date valueType、week mode 、quarter mode nad empty string don't need to be parsed
5659 const dateValue = value . value && ! isDate ( value . value ) && ! [ 'week' , 'quarter' ] . includes ( props . mode )
5760 ? covertToDate ( value . value as string , formatRef . value ?. valueType )
@@ -66,8 +69,8 @@ export default defineComponent({
6669
6770 // 面板展开重置数据
6871 if ( visible ) {
69- year . value = parseToDayjs ( value . value , formatRef . value . format ) . year ( ) ;
70- month . value = parseToDayjs ( value . value , formatRef . value . format ) . month ( ) ;
72+ year . value = parseToDayjs ( value . value as DateValue , formatRef . value . format ) . year ( ) ;
73+ month . value = parseToDayjs ( value . value as DateValue , formatRef . value . format ) . month ( ) ;
7174 time . value = formatTime ( value . value , formatRef . value . format , formatRef . value . timeFormat , props . defaultTime ) ;
7275 } else {
7376 isHoverCell . value = false ;
@@ -76,6 +79,7 @@ export default defineComponent({
7679
7780 // 日期 hover
7881 function onCellMouseEnter ( date : Date ) {
82+ if ( props . multiple ) return ;
7983 isHoverCell . value = true ;
8084 inputValue . value = formatDate ( date , {
8185 format : formatRef . value . format ,
@@ -84,6 +88,7 @@ export default defineComponent({
8488
8589 // 日期 leave
8690 function onCellMouseLeave ( ) {
91+ if ( props . multiple ) return ;
8792 isHoverCell . value = false ;
8893 inputValue . value = formatDate ( cacheValue . value , {
8994 format : formatRef . value . format ,
@@ -103,6 +108,14 @@ export default defineComponent({
103108 format : formatRef . value . format ,
104109 } ) ;
105110 } else {
111+ if ( props . multiple ) {
112+ const newDate = processDate ( date ) ;
113+ onChange ?.( newDate , {
114+ dayjsValue : parseToDayjs ( date , formatRef . value . format ) ,
115+ trigger : 'pick' ,
116+ } ) ;
117+ return ;
118+ }
106119 onChange ?.(
107120 formatDate ( date , {
108121 format : formatRef . value . format ,
@@ -228,21 +241,56 @@ export default defineComponent({
228241 month . value = nextMonth ;
229242 }
230243
244+ function processDate ( date : Date ) {
245+ const val = value . value as DateMultipleValue ;
246+ const isSameDate = val . some ( ( val ) => isSame ( dayjs ( val ) . toDate ( ) , date ) ) ;
247+ let currentDate : DateMultipleValue ;
248+
249+ if ( ! isSameDate ) {
250+ currentDate = val . concat (
251+ formatDate ( date , { format : formatRef . value . format , targetFormat : formatRef . value . valueType } ) ,
252+ ) ;
253+ } else {
254+ currentDate = val . filter (
255+ ( val ) => formatDate ( val , { format : formatRef . value . format , targetFormat : formatRef . value . valueType } )
256+ !== formatDate ( date , { format : formatRef . value . format , targetFormat : formatRef . value . valueType } ) ,
257+ ) ;
258+ }
259+
260+ return currentDate . sort ( ( a , b ) => dayjs ( a ) . valueOf ( ) - dayjs ( b ) . valueOf ( ) ) ;
261+ }
262+
263+ const onTagRemoveClick = ( ctx : TagInputRemoveContext ) => {
264+ const removeDate = dayjs ( ctx . item ) . toDate ( ) ;
265+ const newDate = processDate ( removeDate ) ;
266+ onChange ?.( newDate , {
267+ dayjsValue : parseToDayjs ( removeDate , formatRef . value . format ) ,
268+ trigger : 'tag-remove' ,
269+ } ) ;
270+ } ;
271+
272+ const onTagClearClick = ( { e } : { e : MouseEvent } ) => {
273+ e . stopPropagation ( ) ;
274+ popupVisible . value = false ;
275+ onChange ?.( [ ] , { dayjsValue : dayjs ( ) , trigger : 'clear' } ) ;
276+ } ;
277+
231278 const panelProps : any = computed ( ( ) => ( {
232- value : cacheValue . value as string ,
279+ value : cacheValue . value ,
233280 year : year . value ,
234281 month : month . value ,
235282 format : formatRef . value . format ,
236283 mode : props . mode ,
237284 presets : props . presets ,
238- time : time . value as string ,
285+ time : props . multiple ? '' : time . value ,
239286 disableDate : props . disableDate ,
240287 disableTime : props . disableTime ,
241288 firstDayOfWeek : props . firstDayOfWeek ,
242289 timePickerProps : props . timePickerProps ,
243- enableTimePicker : props . enableTimePicker ,
290+ enableTimePicker : props . multiple ? false : props . enableTimePicker ,
244291 presetsPlacement : props . presetsPlacement ,
245292 popupVisible : popupVisible . value ,
293+ multiple : props . multiple ,
246294 onCellClick,
247295 onCellMouseEnter,
248296 onCellMouseLeave,
@@ -263,7 +311,10 @@ export default defineComponent({
263311 popupVisible,
264312 panelProps,
265313 isDisabled,
314+ onTagRemoveClick,
315+ onTagClearClick,
266316 CalendarIcon,
317+ global,
267318 } ;
268319 } ,
269320 render ( ) {
@@ -275,6 +326,8 @@ export default defineComponent({
275326 popupVisible,
276327 panelProps,
277328 isDisabled,
329+ onTagRemoveClick,
330+ onTagClearClick,
278331 CalendarIcon,
279332 } = this ;
280333
@@ -292,16 +345,25 @@ export default defineComponent({
292345 disabled = { isDisabled }
293346 readonly = { this . readonly }
294347 value = { inputValue }
295- inputValue = { inputValue }
348+ inputValue = { this . multiple ? '' : inputValue }
296349 label = { this . label }
297350 status = { this . status }
298351 tips = { this . tips }
299352 popupProps = { datePickerPopupProps }
300- inputProps = { { suffixIcon : renderSuffixIcon ( ) , ...datePickerInputProps } }
353+ inputProps = { { ...datePickerInputProps } }
301354 popupVisible = { popupVisible }
302355 clearable = { this . clearable }
303356 allowInput = { this . allowInput && ! this . readonly }
304357 panel = { ( ) => < TSinglePanel { ...{ props : panelProps } } /> }
358+ multiple = { this . multiple }
359+ placeholder = {
360+ this . placeholder ?? ( this . global . placeholder as { [ key in typeof this . mode ] : string } ) [ this . mode ]
361+ }
362+ suffixIcon = { renderSuffixIcon ( ) }
363+ tagInputProps = { {
364+ onRemove : onTagRemoveClick ,
365+ } }
366+ onClear = { onTagClearClick }
305367 />
306368 </ div >
307369 ) ;
0 commit comments