11<template >
22 <section class =" v-calendar" :class =" [position, {'long': range}]" >
33 <div class =" input-field" :class =" {'long': range}" >
4- <svg class =" datepicker" version =" 1.1" xmlns =" http://www.w3.org/2000/svg" width =" 32" height =" 32" viewBox =" 0 0 32 32" >
5- <title >calendar</title >
6- <path
7- d =" M10 12h4v4h-4zM16 12h4v4h-4zM22 12h4v4h-4zM4 24h4v4h-4zM10 24h4v4h-4zM16 24h4v4h-4zM10 18h4v4h-4zM16 18h4v4h-4zM22 18h4v4h-4zM4 18h4v4h-4zM26 0v2h-4v-2h-14v2h-4v-2h-4v32h30v-32h-4zM28 30h-26v-22h26v22z"
8- ></path >
9- </svg >
104 <input
115 type =" text"
126 :class =" [inputClass]"
7+ :placeholder =" placeholder"
138 @click =" isShowPicker= !isShowPicker"
9+ :disabled =" disabled"
1410 :value =" formattedValue" readonly />
11+ <svg class =" datepicker" version =" 1.1" xmlns =" http://www.w3.org/2000/svg" width =" 32" height =" 32" viewBox =" 0 0 32 32" >
12+ <path d =" M10 12h4v4h-4zM16 12h4v4h-4zM22 12h4v4h-4zM4 24h4v4h-4zM10 24h4v4h-4zM16 24h4v4h-4zM10 18h4v4h-4zM16 18h4v4h-4zM22 18h4v4h-4zM4 18h4v4h-4zM26 0v2h-4v-2h-14v2h-4v-2h-4v32h30v-32h-4zM28 30h-26v-22h26v22z" ></path >
13+ </svg >
1514 </div >
1615 <div class =" content"
1716 v-if =" isShowPicker" >
6968</template >
7069
7170<script >
72- import Calendar from ' ./datepicker '
71+ import Calendar from ' calendar-data-generate '
7372
7473export default {
7574 name: ' VueDatePicker' ,
7675 data () {
7776 return {
78- calendarWiew: ' day' ,
7977 isShowPicker: false ,
8078 currentDate: {
8179 year: new Date ().getFullYear (),
8280 month: new Date ().getMonth (),
8381 date: new Date ().getDate (),
84- firstDayOfWeek: this .firstDayOfWeek ,
82+ firstDayOfWeek: this .firstDayOfWeek
8583 },
8684 currentDateEnd: {
8785 year: new Date ().getFullYear (),
8886 month: new Date ().getMonth (),
8987 date: new Date ().getDate (),
9088 firstDayOfWeek: this .firstDayOfWeek
9189 },
92- selectedDate: this .range ? [null , null ] : null
90+ selectedDate: this .range ? [null , null ] : null ,
91+ calendarView: ' days' ,
92+ calendarEndView: ' days'
9393 }
9494 },
9595 props: {
96+ value: {},
9697 textFormat: {
9798 type: String ,
9899 default: ' short'
99100 },
100101 dateFormat: {
101102 type: Object ,
102- default : function () {
103- return { day: ' 2-digit' , month: ' long' , year: ' numeric' }
104- },
103+ default : () => {
104+ return { day: ' 2-digit' , month: ' short' , year: ' numeric' }
105+ }
106+ },
107+ format: {
108+ type: String ,
109+ default: ' '
110+ },
111+ rangeSeperator: {
112+ type: String ,
113+ default: ' ~'
105114 },
106115 position: {
107116 type: String ,
108117 default: ' left'
109118 },
110- value: {
111- type: [Array , String , Date ]
112- },
113119 range: {
114120 type: Boolean ,
115121 default: false
@@ -124,7 +130,7 @@ export default {
124130 },
125131 firstDayOfWeek: {
126132 type: String ,
127- validator : val => [' monday' , ' sunday' ].contains (val),
133+ validator : val => [' monday' , ' sunday' ].indexOf (val) > - 1 ,
128134 default: ' monday'
129135 },
130136 disabledStartDate: {
@@ -144,11 +150,19 @@ export default {
144150 to: null
145151 }
146152 }
153+ },
154+ disabled: {
155+ type: Boolean ,
156+ default: false
157+ },
158+ placeholder: {
159+ type: String ,
160+ default: ' Select Date'
147161 }
148162 },
149163 computed: {
150- disabledStartDateCalc () {
151- let unSelectedDate = {
164+ disabledStartDateCalc () {
165+ const unSelectedDate = {
152166 from: null ,
153167 to: null
154168 }
@@ -161,13 +175,13 @@ export default {
161175 return unSelectedDate
162176 },
163177 disabledEndDateCalc () {
164- let unSelectedDate = {
178+ const unSelectedDate = {
165179 from: null ,
166180 to: null
167181 }
168182 if (this .range ) {
169183 let disabledDate = new Date (this .selectedDate [0 ])
170- disabledDate = (! this .disabledEndDate .to || disabledDate .getTime () > this .disabledStartDate .to .getTime ()) ? disabledDate : this .disabledStartDate . from
184+ disabledDate = (! this .disabledEndDate .to || disabledDate .getTime () > this .disabledEndDate .to .getTime ()) ? disabledDate : this .disabledEndDate . to
171185 unSelectedDate .to = disabledDate
172186 unSelectedDate .from = this .disabledEndDate .from
173187 }
@@ -189,63 +203,98 @@ export default {
189203 this .lang ,
190204 this .textFormat ,
191205 { ... this .dateFormat },
192- this . range ? this .disabledEndDateCalc : this . disabledEndDate
206+ this .disabledEndDateCalc
193207 )
194208 },
195- formattedValue () {
209+ formattedValue () {
196210 if (! this .range ) {
197211 return this .formatDate (this .selectedDate )
198- }
199- return ` ${ this .formatDate (this .selectedDate [0 ])} ~ ${ this .formatDate (this .selectedDate [1 ])} `
212+ } else if ( this . selectedDate . filter ( Boolean ). length != 2 ) return null
213+ return ` ${ this .formatDate (this .selectedDate [0 ])} ${ this . rangeSeperator } ${ this .formatDate (this .selectedDate [1 ])} `
200214 }
201215 },
202216 methods: {
203217 formatDate (value ) {
204- return new Date (value).toLocaleDateString (this .lang , { ... this .dateFormat })
218+ if (! value) return null
219+ if (this .range && this .value .filter (Boolean ).length === 0 ) return null
220+ return new Date (value).toLocaleDateString (this .locale , { ... this .dateFormat })
205221 },
206- prevMount (type ) {
207- const currentDate = type === ' start' ? this .currentDate : this .currentDateEnd
222+ prevMount (picker ) {
223+ const currentDate = picker === ' start' ? this .currentDate : this .currentDateEnd
208224 currentDate .month = currentDate .month - 1
209225 if (currentDate .month === - 1 ) {
210226 currentDate .year = currentDate .year - 1
211227 currentDate .month = 11
212228 }
213229 },
214- nextMount (type ) {
215- const currentDate = type === ' start' ? this .currentDate : this .currentDateEnd
230+ nextMount (picker ) {
231+ const currentDate = picker === ' start' ? this .currentDate : this .currentDateEnd
216232 currentDate .month = currentDate .month + 1
217233 if (currentDate .month === 12 ) {
218234 currentDate .year = currentDate .year + 1
219235 currentDate .month = 0
220236 }
221237 },
222- handlerDate (fullDate , type = null ) {
238+ handlerDate (fullDate , picker = null ) {
223239 if (! this .range ) {
224240 this .setDate (fullDate)
225241 return
226242 }
227243 const selectedDates = [
228- type === ' start' ? fullDate : this .selectedDate [0 ],
229- type === ' end' ? fullDate : this .selectedDate [1 ]
244+ picker === ' start' ? fullDate : this .selectedDate [0 ],
245+ picker === ' end' ? fullDate : this .selectedDate [1 ]
230246 ]
231247 this .setDate (selectedDates)
232248 },
233249 setDate (selectedDates ) {
234- this .$emit (' input' , selectedDates)
235250 this .selectedDate = selectedDates
251+ this .emitInputAction ()
252+ },
253+ emitInputAction () {
254+ this .$emit (' input' , this .selectedDate )
255+ this .close ()
236256 },
237- isInSelectedDate (date ) {
257+ isInSelectedDate (date ) {
258+ if (! this .range ) return null
238259 return new Date (this .selectedDate [0 ]).getTime () <= date .getTime () && new Date (this .selectedDate [1 ]).getTime () >= date .getTime ()
239260 },
240- changeView (view ) {
241- this .calendarWiew = view
261+ close () {
262+ this .isShowPicker = false
263+ },
264+ setCurrents () {
265+ if (this .range ) {
266+ if (this .value [0 ]) {
267+ this .currentDate .year = new Date (this .value [0 ]).getFullYear ()
268+ this .currentDate .month = new Date (this .value [0 ]).getMonth ()
269+ this .currentDate .date = new Date (this .value [0 ]).getDate ()
270+ }
271+ if (this .value [1 ]) {
272+ this .currentDateEnd .year = new Date (this .value [1 ]).getFullYear ()
273+ this .currentDateEnd .month = new Date (this .value [1 ]).getMonth ()
274+ this .currentDateEnd .date = new Date (this .value [1 ]).getDate ()
275+ }
276+ } else if (this .value ) {
277+ this .currentDate .year = new Date (this .value ).getFullYear ()
278+ this .currentDate .month = new Date (this .value ).getMonth ()
279+ this .currentDate .date = new Date (this .value ).getDate ()
280+ }
242281 }
243282 },
244- mounted () {
283+ mounted () {
284+ this .setCurrents ()
245285 this .setDate (this .value )
286+ this .$watch (' value' , () => {
287+ this .setCurrents ()
288+ this .setDate (this .value )
289+ })
290+ this .$watch (' selectedDate' , (value ) => {
291+ if (! value && this .value === value) return
292+ this .$emit (' change' , value)
293+ })
246294 window .addEventListener (' click' , (e ) => {
247- const el = e .target .closest (' .v-calendar' )
248- if (! el) this .isShowPicker = false
295+ const Datepicker = this .$el
296+ const isThis = Datepicker .contains (e .target )
297+ if (! isThis) this .close ()
249298 })
250299 }
251300}
@@ -279,9 +328,15 @@ export default {
279328 position : relative ;
280329 min-width : 140px ;
281330}
331+
332+ .v-calendar .input-field input :disabled ~ svg {
333+ fill : #7b8187 ;
334+ }
335+
282336.v-calendar .input-field.long {
283337 min-width : 290px ;
284338}
339+
285340.v-calendar .input-field input {
286341 padding-left : 40px ;
287342 padding-right : 20px ;
@@ -304,8 +359,10 @@ export default {
304359}
305360.v-calendar .calendar {
306361 padding : 20px ;
307- width : 300px ;
362+ width : max-content ;
363+
308364}
365+
309366.v-calendar .calendar.textLong {
310367 width : 580px ;
311368}
@@ -357,14 +414,14 @@ export default {
357414}
358415.v-calendar .calendar .days {
359416 display : grid ;
360- grid-template-columns : repeat (7 , calc ( 100 % / 7 ));
417+ grid-template-columns : repeat (7 , minmax ( max-content , 1 fr ));
361418 border-radius : 6px ;
362419}
363420.v-calendar .calendar .days .day {
364421 background : transparent ;
365422 border : 0 ;
366423 text-align : center ;
367- padding : 10 px ;
424+ padding : 7 px ;
368425 font-size : 0.8em ;
369426 color : #7b8187 ;
370427 cursor : pointer ;
0 commit comments