goodteditor-ui 1.0.12 → 1.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +7 -7
- package/.prettierrc +14 -14
- package/README.md +35 -35
- package/babel.config.js +5 -5
- package/dist/js.png +0 -0
- package/index.js +51 -51
- package/jsconfig.json +13 -13
- package/package.json +57 -57
- package/src/App.vue +36 -36
- package/src/components/ui/Avatar.md +68 -68
- package/src/components/ui/Avatar.vue +177 -177
- package/src/components/ui/Badge.md +20 -20
- package/src/components/ui/Badge.vue +75 -75
- package/src/components/ui/Collapse.md +90 -90
- package/src/components/ui/Collapse.vue +86 -86
- package/src/components/ui/ColorPicker/Alpha.vue +114 -114
- package/src/components/ui/ColorPicker/Colors.vue +117 -117
- package/src/components/ui/ColorPicker/Hue.vue +113 -113
- package/src/components/ui/ColorPicker/Preview.vue +55 -55
- package/src/components/ui/ColorPicker/Saturation.vue +123 -123
- package/src/components/ui/ColorPicker/mixin.js +105 -105
- package/src/components/ui/ColorPicker.md +17 -17
- package/src/components/ui/ColorPicker.vue +314 -314
- package/src/components/ui/Datalist.md +41 -41
- package/src/components/ui/Datalist.vue +157 -157
- package/src/components/ui/DatePicker.md +168 -168
- package/src/components/ui/DatePicker.vue +527 -527
- package/src/components/ui/FileSelector.md +105 -105
- package/src/components/ui/FileSelector.vue +82 -82
- package/src/components/ui/Grid.md +130 -130
- package/src/components/ui/Grid.vue +92 -92
- package/src/components/ui/Image.md +59 -59
- package/src/components/ui/Image.vue +57 -57
- package/src/components/ui/InputAutocomplete.md +115 -115
- package/src/components/ui/InputAutocomplete.vue +341 -341
- package/src/components/ui/InputColorPicker.md +51 -51
- package/src/components/ui/InputColorPicker.vue +151 -151
- package/src/components/ui/InputDatePicker.md +121 -121
- package/src/components/ui/InputDatePicker.vue +310 -310
- package/src/components/ui/InputTags.md +51 -51
- package/src/components/ui/InputTags.vue +184 -184
- package/src/components/ui/InputTimePicker.md +25 -25
- package/src/components/ui/InputTimePicker.vue +253 -253
- package/src/components/ui/InputUnits.md +20 -20
- package/src/components/ui/InputUnits.vue +257 -257
- package/src/components/ui/Lazy.md +37 -37
- package/src/components/ui/Lazy.vue +92 -92
- package/src/components/ui/Pagination.md +74 -74
- package/src/components/ui/Pagination.vue +138 -138
- package/src/components/ui/Paginator.md +34 -34
- package/src/components/ui/Paginator.vue +83 -83
- package/src/components/ui/Popover.md +34 -34
- package/src/components/ui/Popover.vue +258 -209
- package/src/components/ui/Popup.md +59 -59
- package/src/components/ui/Popup.vue +150 -150
- package/src/components/ui/ResponsiveContainer.md +58 -58
- package/src/components/ui/ResponsiveContainer.vue +99 -99
- package/src/components/ui/Select.md +187 -187
- package/src/components/ui/Select.vue +420 -420
- package/src/components/ui/TimePicker.md +50 -50
- package/src/components/ui/TimePicker.vue +252 -252
- package/src/components/ui/Tooltip.md +114 -52
- package/src/components/ui/Tooltip.vue +113 -113
- package/src/components/ui/utils/FormComponent.js +107 -107
- package/src/components/ui/utils/Helpers.js +84 -61
- package/src/components/ui/utils/WithPopover.js +99 -81
- package/src/main.js +8 -8
- package/styleguide.config.js +37 -37
- package/vue.config.js +8 -8
- package/.idea/codeStyles/Project.xml +0 -51
- package/.idea/codeStyles/codeStyleConfig.xml +0 -5
- package/.idea/goodt-ui.iml +0 -12
- package/.idea/inspectionProfiles/Project_Default.xml +0 -6
- package/.idea/modules.xml +0 -8
- package/.idea/vcs.xml +0 -6
|
@@ -1,527 +1,527 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="ui-date-picker">
|
|
3
|
-
<div class="panel d-inline-flex flex-col scroll-hide">
|
|
4
|
-
<div class="row row-collapse row-vgap-none flex-nowrap">
|
|
5
|
-
<div class="col col-auto" v-if="$scopedSlots.left">
|
|
6
|
-
<!--
|
|
7
|
-
@slot Custom left content
|
|
8
|
-
-->
|
|
9
|
-
<slot name="left"></slot>
|
|
10
|
-
</div>
|
|
11
|
-
<div class="col col-auto">
|
|
12
|
-
<!--
|
|
13
|
-
@slot Custom header content
|
|
14
|
-
@binding {Function} prevYear select previous year
|
|
15
|
-
@binding {Function} prevMonth select previous month
|
|
16
|
-
@binding {Function} nextYear select next year
|
|
17
|
-
@binding {Function} nextMonth select next month
|
|
18
|
-
@binding {Function} setMonth set month by index (0 = january)
|
|
19
|
-
@binding {Function} setYear set year (4-digit)
|
|
20
|
-
@binding {Function} setToday set today's date
|
|
21
|
-
@binding {Number} month current month index (0 = january)
|
|
22
|
-
@binding {String} monthName current month name
|
|
23
|
-
@binding {Number} year current year (4-digit)
|
|
24
|
-
-->
|
|
25
|
-
<slot
|
|
26
|
-
name="header"
|
|
27
|
-
v-bind="{
|
|
28
|
-
prevYear,
|
|
29
|
-
prevMonth,
|
|
30
|
-
nextYear,
|
|
31
|
-
nextMonth,
|
|
32
|
-
setMonth,
|
|
33
|
-
setYear,
|
|
34
|
-
setToday,
|
|
35
|
-
month,
|
|
36
|
-
monthName: monthNames[month],
|
|
37
|
-
year,
|
|
38
|
-
}"
|
|
39
|
-
>
|
|
40
|
-
<div
|
|
41
|
-
class="ui-date-picker-header text-small mar-bot-3 bg-primary color-white pad-3"
|
|
42
|
-
>
|
|
43
|
-
<div class="flex-shrink nobr">
|
|
44
|
-
<div class="icon cursor-pointer" @click="prevYear">
|
|
45
|
-
<i class="mdi mdi-chevron-double-left"></i>
|
|
46
|
-
</div>
|
|
47
|
-
<div class="icon cursor-pointer" @click="prevMonth">
|
|
48
|
-
<i class="mdi mdi-chevron-left"></i>
|
|
49
|
-
</div>
|
|
50
|
-
</div>
|
|
51
|
-
<div class="flex-grow flex-h-center d-flex">
|
|
52
|
-
<span>{{ monthNames[month] }}</span>
|
|
53
|
-
<input class="color-inherit" type="number" v-model.number="year" />
|
|
54
|
-
</div>
|
|
55
|
-
<div class="flex-shrink nobr">
|
|
56
|
-
<div class="icon cursor-pointer" @click="nextMonth">
|
|
57
|
-
<i class="mdi mdi-chevron-right"></i>
|
|
58
|
-
</div>
|
|
59
|
-
<div class="icon cursor-pointer" @click="nextYear">
|
|
60
|
-
<i class="mdi mdi-chevron-double-right"></i>
|
|
61
|
-
</div>
|
|
62
|
-
</div>
|
|
63
|
-
</div>
|
|
64
|
-
</slot>
|
|
65
|
-
<div class="ui-date-picker-grid pad-3">
|
|
66
|
-
<div
|
|
67
|
-
class="ui-date-picker-day-cell text-small"
|
|
68
|
-
v-for="dayIndex of dayNamesIndexes"
|
|
69
|
-
:key="`day-${dayIndex}`"
|
|
70
|
-
>
|
|
71
|
-
<!--
|
|
72
|
-
@slot Custom day content
|
|
73
|
-
@binding {Number} dayIndex day index (0 = sunday)
|
|
74
|
-
@binding {String} dayName day name
|
|
75
|
-
@binding {Boolean} isWeekend whether a weekend day
|
|
76
|
-
-->
|
|
77
|
-
<slot
|
|
78
|
-
name="cell-day"
|
|
79
|
-
v-bind="{
|
|
80
|
-
dayIndex,
|
|
81
|
-
dayName: dayNames[dayIndex],
|
|
82
|
-
isWeekend: isWeekendDay(dayIndex),
|
|
83
|
-
}"
|
|
84
|
-
>
|
|
85
|
-
<div class="color-grey-dark">
|
|
86
|
-
{{ dayNames[dayIndex] }}
|
|
87
|
-
</div>
|
|
88
|
-
</slot>
|
|
89
|
-
</div>
|
|
90
|
-
<div
|
|
91
|
-
class="ui-date-picker-date-cell text-small"
|
|
92
|
-
v-for="n in currentMonthDates"
|
|
93
|
-
:key="`${n.getMonth()}-${n.getDate()}`"
|
|
94
|
-
>
|
|
95
|
-
<!--
|
|
96
|
-
@slot Custom date content
|
|
97
|
-
@binding {Date} date date
|
|
98
|
-
@binding {Date} dateStart range start date
|
|
99
|
-
@binding {Date} dateEnd range end date
|
|
100
|
-
@binding {Number} month current view month
|
|
101
|
-
@binding {Number} year current view year
|
|
102
|
-
@binding {Boolean} isCurrentMonthDate is date in current month view
|
|
103
|
-
@binding {Boolean} isDisabledDate is date disabled
|
|
104
|
-
@binding {Boolean} isInRange is date in range
|
|
105
|
-
@binding {Boolean} isRangeStart is date = range start
|
|
106
|
-
@binding {Boolean} isRangeEnd is date = range end
|
|
107
|
-
@binding {Boolean} isSelected is date selected
|
|
108
|
-
@binding {Boolean} isToday is date today
|
|
109
|
-
@binding {Boolean} isWeekend is date a weekend day
|
|
110
|
-
@binding {Function} setDate set date
|
|
111
|
-
-->
|
|
112
|
-
<slot
|
|
113
|
-
name="cell-date"
|
|
114
|
-
v-bind="{
|
|
115
|
-
date: n,
|
|
116
|
-
dateStart,
|
|
117
|
-
dateEnd,
|
|
118
|
-
month,
|
|
119
|
-
year,
|
|
120
|
-
isCurrentMonthDate: isCurrentMonthDate(n),
|
|
121
|
-
isDisabledDate: isDisabledDate(n),
|
|
122
|
-
isInRange: isRangeDate(n),
|
|
123
|
-
isRangeStart: isRangeStartDate(n),
|
|
124
|
-
isRangeEnd: isRangeEndDate(n),
|
|
125
|
-
isSelected: isSelectedDate(n),
|
|
126
|
-
isToday: isTodayDate(n),
|
|
127
|
-
isWeekend: isWeekendDate(n),
|
|
128
|
-
setDate,
|
|
129
|
-
}"
|
|
130
|
-
>
|
|
131
|
-
<div
|
|
132
|
-
class="btn btn-icon btn-small"
|
|
133
|
-
:class="{
|
|
134
|
-
'btn-primary': isSelectedDate(n) || isRangeDate(n),
|
|
135
|
-
'radius-right-none':
|
|
136
|
-
isRangeStartDate(n) && !isRangeEndDate(n) && dateEnd,
|
|
137
|
-
'radius-left-none':
|
|
138
|
-
!isRangeStartDate(n) && isRangeEndDate(n),
|
|
139
|
-
'radius-none':
|
|
140
|
-
isRangeDate(n) &&
|
|
141
|
-
!isRangeStartDate(n) &&
|
|
142
|
-
!isRangeEndDate(n),
|
|
143
|
-
'disabled radius-none': isDisabledDate(n),
|
|
144
|
-
}"
|
|
145
|
-
@click="setDate(n)"
|
|
146
|
-
>
|
|
147
|
-
<template v-if="isSelectedDate(n) || isRangeDate(n)">
|
|
148
|
-
<div>{{ n.getDate() }}</div>
|
|
149
|
-
</template>
|
|
150
|
-
<template v-else-if="isTodayDate(n)">
|
|
151
|
-
<div class="color-primary">{{ n.getDate() }}</div>
|
|
152
|
-
</template>
|
|
153
|
-
<template v-else-if="!isCurrentMonthDate(n)">
|
|
154
|
-
<div class="text-muted">{{ n.getDate() }}</div>
|
|
155
|
-
</template>
|
|
156
|
-
<template v-else>
|
|
157
|
-
<div class="color-body">{{ n.getDate() }}</div>
|
|
158
|
-
</template>
|
|
159
|
-
</div>
|
|
160
|
-
</slot>
|
|
161
|
-
</div>
|
|
162
|
-
</div>
|
|
163
|
-
</div>
|
|
164
|
-
<div class="col col-auto" v-if="$scopedSlots.right">
|
|
165
|
-
<!--
|
|
166
|
-
@slot Custom right content
|
|
167
|
-
-->
|
|
168
|
-
<slot name="right"></slot>
|
|
169
|
-
</div>
|
|
170
|
-
</div>
|
|
171
|
-
</div>
|
|
172
|
-
</div>
|
|
173
|
-
</template>
|
|
174
|
-
<style lang="less" scoped>
|
|
175
|
-
.ui-date-picker {
|
|
176
|
-
display: inline-flex;
|
|
177
|
-
color: var(--color-body);
|
|
178
|
-
&-header {
|
|
179
|
-
display: flex;
|
|
180
|
-
align-items: center;
|
|
181
|
-
input {
|
|
182
|
-
width: 3em;
|
|
183
|
-
border: none;
|
|
184
|
-
background: transparent;
|
|
185
|
-
outline: none;
|
|
186
|
-
text-align: center;
|
|
187
|
-
margin: 0;
|
|
188
|
-
padding: 0;
|
|
189
|
-
outline: none;
|
|
190
|
-
-moz-appearance: textfield;
|
|
191
|
-
&::-webkit-outer-spin-button,
|
|
192
|
-
&::-webkit-inner-spin-button {
|
|
193
|
-
-webkit-appearance: none;
|
|
194
|
-
margin: 0;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
&-grid {
|
|
199
|
-
display: grid;
|
|
200
|
-
grid-template-columns: repeat(7, 1fr);
|
|
201
|
-
grid-auto-rows: 1fr;
|
|
202
|
-
row-gap: 1px;
|
|
203
|
-
}
|
|
204
|
-
&-day-cell,
|
|
205
|
-
&-date-cell {
|
|
206
|
-
position: relative;
|
|
207
|
-
display: flex;
|
|
208
|
-
align-items: center;
|
|
209
|
-
justify-content: center;
|
|
210
|
-
}
|
|
211
|
-
.flex-nowrap {
|
|
212
|
-
flex-wrap: nowrap;
|
|
213
|
-
}
|
|
214
|
-
.radius-left-none {
|
|
215
|
-
border-top-left-radius: 0;
|
|
216
|
-
border-bottom-left-radius: 0;
|
|
217
|
-
}
|
|
218
|
-
.radius-right-none {
|
|
219
|
-
border-top-right-radius: 0;
|
|
220
|
-
border-bottom-right-radius: 0;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
</style>
|
|
224
|
-
<script>
|
|
225
|
-
import { isDateValid } from './utils/Helpers';
|
|
226
|
-
|
|
227
|
-
export default {
|
|
228
|
-
props: {
|
|
229
|
-
/**
|
|
230
|
-
* @model
|
|
231
|
-
*/
|
|
232
|
-
value: {
|
|
233
|
-
type: [Date, Array],
|
|
234
|
-
default: null,
|
|
235
|
-
validation(val) {
|
|
236
|
-
if (Array.isArray(val)) {
|
|
237
|
-
return val.find(el => !this.isValid(el)) == null;
|
|
238
|
-
} else {
|
|
239
|
-
return this.isValid(val);
|
|
240
|
-
}
|
|
241
|
-
},
|
|
242
|
-
},
|
|
243
|
-
/**
|
|
244
|
-
* Min date (inclusive)
|
|
245
|
-
*/
|
|
246
|
-
min: {
|
|
247
|
-
type: Date,
|
|
248
|
-
default: null,
|
|
249
|
-
},
|
|
250
|
-
/**
|
|
251
|
-
* Max date (inclusive)
|
|
252
|
-
*/
|
|
253
|
-
max: {
|
|
254
|
-
type: Date,
|
|
255
|
-
default: null,
|
|
256
|
-
},
|
|
257
|
-
/**
|
|
258
|
-
* Allowed date filter function(date:Date):Boolean
|
|
259
|
-
*/
|
|
260
|
-
allowed: {
|
|
261
|
-
type: Function,
|
|
262
|
-
default: () => true,
|
|
263
|
-
},
|
|
264
|
-
/**
|
|
265
|
-
* Range mode
|
|
266
|
-
*/
|
|
267
|
-
range: {
|
|
268
|
-
type: Boolean,
|
|
269
|
-
default: false,
|
|
270
|
-
},
|
|
271
|
-
/**
|
|
272
|
-
* Day names starting from 'Sunday'
|
|
273
|
-
*/
|
|
274
|
-
dayNames: {
|
|
275
|
-
type: Array,
|
|
276
|
-
default() {
|
|
277
|
-
return ['Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'];
|
|
278
|
-
},
|
|
279
|
-
},
|
|
280
|
-
/**
|
|
281
|
-
* Weekend day indexes (0 = Sunday; 6 = Saturday)
|
|
282
|
-
*/
|
|
283
|
-
weekendDays: {
|
|
284
|
-
type: Array,
|
|
285
|
-
default() {
|
|
286
|
-
return [0, 6];
|
|
287
|
-
},
|
|
288
|
-
},
|
|
289
|
-
/**
|
|
290
|
-
* Month names starting from 'January'
|
|
291
|
-
*/
|
|
292
|
-
monthNames: {
|
|
293
|
-
type: Array,
|
|
294
|
-
default() {
|
|
295
|
-
return [
|
|
296
|
-
'Январь',
|
|
297
|
-
'Февраль',
|
|
298
|
-
'Март',
|
|
299
|
-
'Апрель',
|
|
300
|
-
'Май',
|
|
301
|
-
'Июнь',
|
|
302
|
-
'Июль',
|
|
303
|
-
'Август',
|
|
304
|
-
'Сентябрь',
|
|
305
|
-
'Октябрь',
|
|
306
|
-
'Ноябрь',
|
|
307
|
-
'Декабрь',
|
|
308
|
-
];
|
|
309
|
-
},
|
|
310
|
-
},
|
|
311
|
-
/**
|
|
312
|
-
* Which day is the first day of the week (0 = Sunday; 6 = Saturday)
|
|
313
|
-
*/
|
|
314
|
-
dayOfWeek: {
|
|
315
|
-
type: Number,
|
|
316
|
-
default: 1,
|
|
317
|
-
validation(val) {
|
|
318
|
-
return val >= 0 && val < 7;
|
|
319
|
-
},
|
|
320
|
-
},
|
|
321
|
-
},
|
|
322
|
-
data() {
|
|
323
|
-
return {
|
|
324
|
-
date: null,
|
|
325
|
-
dateStart: null,
|
|
326
|
-
dateEnd: null,
|
|
327
|
-
month: null,
|
|
328
|
-
year: null,
|
|
329
|
-
syncMonthYear: true,
|
|
330
|
-
};
|
|
331
|
-
},
|
|
332
|
-
computed: {
|
|
333
|
-
dayNamesIndexes() {
|
|
334
|
-
let a = [];
|
|
335
|
-
for (let i = this.dayOfWeek; i < 7 + this.dayOfWeek; ++i) {
|
|
336
|
-
a.push(i >= 7 ? i - 7 : i);
|
|
337
|
-
}
|
|
338
|
-
return a;
|
|
339
|
-
},
|
|
340
|
-
firstDayOfMonth() {
|
|
341
|
-
let n = new Date(this.year, this.month, 1).getDay() - this.dayOfWeek;
|
|
342
|
-
return n < 0 ? 7 + n : n;
|
|
343
|
-
},
|
|
344
|
-
lastDayOfMonth() {
|
|
345
|
-
let n = new Date(this.year, this.month + 1, 0).getDay() - this.dayOfWeek;
|
|
346
|
-
return n < 0 ? 7 + n : n;
|
|
347
|
-
},
|
|
348
|
-
daysInMonth() {
|
|
349
|
-
return new Date(this.year, this.month + 1, 0).getDate();
|
|
350
|
-
},
|
|
351
|
-
currentMonthDates() {
|
|
352
|
-
let dates = [...new Array(this.daysInMonth)].map(
|
|
353
|
-
(v, i) => new Date(this.year, this.month, i + 1)
|
|
354
|
-
);
|
|
355
|
-
return [...this.prevMonthDates, ...dates, ...this.nextMonthDates];
|
|
356
|
-
},
|
|
357
|
-
prevMonthDates() {
|
|
358
|
-
let n = this.firstDayOfMonth;
|
|
359
|
-
let pmd = new Date(this.year, this.month, 0).getDate();
|
|
360
|
-
return [...new Array(n)]
|
|
361
|
-
.map((v, i) => new Date(this.year, this.month - 1, pmd - i))
|
|
362
|
-
.reverse();
|
|
363
|
-
},
|
|
364
|
-
nextMonthDates() {
|
|
365
|
-
let n = 6 - this.lastDayOfMonth;
|
|
366
|
-
return [...new Array(n)].map((v, i) => new Date(this.year, this.month + 1, i + 1));
|
|
367
|
-
},
|
|
368
|
-
},
|
|
369
|
-
watch: {
|
|
370
|
-
value: {
|
|
371
|
-
handler(val) {
|
|
372
|
-
let d = new Date();
|
|
373
|
-
if (this.range && Array.isArray(val)) {
|
|
374
|
-
let [start, end] = val;
|
|
375
|
-
this.dateStart = start || null;
|
|
376
|
-
this.dateEnd = end || null;
|
|
377
|
-
d = start || d;
|
|
378
|
-
} else {
|
|
379
|
-
this.date = val;
|
|
380
|
-
d = val || d;
|
|
381
|
-
}
|
|
382
|
-
if (this.syncMonthYear) {
|
|
383
|
-
this.month = d.getMonth();
|
|
384
|
-
this.year = d.getFullYear();
|
|
385
|
-
}
|
|
386
|
-
this.syncMonthYear = true;
|
|
387
|
-
},
|
|
388
|
-
immediate: true,
|
|
389
|
-
},
|
|
390
|
-
range() {
|
|
391
|
-
this.date = null;
|
|
392
|
-
this.dateStart = null;
|
|
393
|
-
this.dateEnd = null;
|
|
394
|
-
this._triggerChange();
|
|
395
|
-
},
|
|
396
|
-
},
|
|
397
|
-
methods: {
|
|
398
|
-
isValid(date) {
|
|
399
|
-
return isDateValid(date);
|
|
400
|
-
},
|
|
401
|
-
prevMonth() {
|
|
402
|
-
let n = this.month - 1;
|
|
403
|
-
this.month = n < 0 ? 11 : n;
|
|
404
|
-
this.year -= n < 0 ? 1 : 0;
|
|
405
|
-
},
|
|
406
|
-
prevYear() {
|
|
407
|
-
this.year = this.year - 1;
|
|
408
|
-
},
|
|
409
|
-
nextMonth() {
|
|
410
|
-
let n = this.month + 1;
|
|
411
|
-
this.month = n > 11 ? 0 : n;
|
|
412
|
-
this.year += n > 11 ? 1 : 0;
|
|
413
|
-
},
|
|
414
|
-
nextYear() {
|
|
415
|
-
this.year = this.year + 1;
|
|
416
|
-
},
|
|
417
|
-
setYear(n) {
|
|
418
|
-
this.year = n;
|
|
419
|
-
},
|
|
420
|
-
setMonth(n) {
|
|
421
|
-
this.month = n;
|
|
422
|
-
},
|
|
423
|
-
setDate(date) {
|
|
424
|
-
let d = this.isValid(date) ? date : new Date(this.year, this.month, date);
|
|
425
|
-
|
|
426
|
-
if (this.range) {
|
|
427
|
-
if (!this.dateStart || (this.dateStart && this.dateEnd)) {
|
|
428
|
-
this.dateStart = d;
|
|
429
|
-
this.dateEnd = null;
|
|
430
|
-
} else {
|
|
431
|
-
if (d < this.dateStart) {
|
|
432
|
-
this.dateEnd = this.dateStart;
|
|
433
|
-
this.dateStart = d;
|
|
434
|
-
} else if (d > this.dateStart) {
|
|
435
|
-
this.dateEnd = d;
|
|
436
|
-
} else {
|
|
437
|
-
return;
|
|
438
|
-
}
|
|
439
|
-
this._triggerChange();
|
|
440
|
-
}
|
|
441
|
-
} else {
|
|
442
|
-
this.date = d;
|
|
443
|
-
this._triggerChange();
|
|
444
|
-
}
|
|
445
|
-
/**
|
|
446
|
-
* Set date event
|
|
447
|
-
* @property {Date} date
|
|
448
|
-
*/
|
|
449
|
-
this.$emit('set-date', d);
|
|
450
|
-
},
|
|
451
|
-
setToday() {
|
|
452
|
-
this.date = new Date();
|
|
453
|
-
this.month = this.date.getMonth();
|
|
454
|
-
this.year = this.date.getFullYear();
|
|
455
|
-
this._triggerChange();
|
|
456
|
-
/**
|
|
457
|
-
* Set date event
|
|
458
|
-
* @property {Date} date
|
|
459
|
-
*/
|
|
460
|
-
this.$emit('set-date', this.date);
|
|
461
|
-
},
|
|
462
|
-
isCurrentMonthDate(date) {
|
|
463
|
-
if (this.isValid(date)) {
|
|
464
|
-
return this.month == date.getMonth();
|
|
465
|
-
}
|
|
466
|
-
return true;
|
|
467
|
-
},
|
|
468
|
-
isDisabledDate(date) {
|
|
469
|
-
let d = this.isValid(date) ? date : new Date(this.year, this.month, date);
|
|
470
|
-
let { min, max, allowed } = this;
|
|
471
|
-
return (min && d < min) || (max && d > max) || (allowed && !allowed(d));
|
|
472
|
-
},
|
|
473
|
-
isRangeStartDate(date) {
|
|
474
|
-
let d = this.isValid(date) ? date : new Date(this.year, this.month, date);
|
|
475
|
-
return this.dateStart && +d == +this.dateStart;
|
|
476
|
-
},
|
|
477
|
-
isRangeEndDate(date) {
|
|
478
|
-
let d = this.isValid(date) ? date : new Date(this.year, this.month, date);
|
|
479
|
-
return this.dateEnd && +d == +this.dateEnd;
|
|
480
|
-
},
|
|
481
|
-
isRangeDate(date) {
|
|
482
|
-
let d = this.isValid(date) ? date : new Date(this.year, this.month, date);
|
|
483
|
-
if (this.dateStart && +d == +this.dateStart) {
|
|
484
|
-
return true;
|
|
485
|
-
}
|
|
486
|
-
return this.dateStart && this.dateEnd && d >= this.dateStart && d <= this.dateEnd;
|
|
487
|
-
},
|
|
488
|
-
isSelectedDate(date) {
|
|
489
|
-
let d = this.isValid(date) ? date : new Date(this.year, this.month, date);
|
|
490
|
-
return this.date && +this.date == +date;
|
|
491
|
-
},
|
|
492
|
-
isWeekendDate(date) {
|
|
493
|
-
let d = this.isValid(date) ? date : new Date(this.year, this.month, date);
|
|
494
|
-
return this.weekendDays.includes(d.getDay());
|
|
495
|
-
},
|
|
496
|
-
isTodayDate(date) {
|
|
497
|
-
let d = this.isValid(date) ? date : new Date(this.year, this.month, date);
|
|
498
|
-
let now = new Date();
|
|
499
|
-
return (
|
|
500
|
-
now.getFullYear() === d.getFullYear() &&
|
|
501
|
-
now.getMonth() === d.getMonth() &&
|
|
502
|
-
now.getDate() === d.getDate()
|
|
503
|
-
);
|
|
504
|
-
},
|
|
505
|
-
isWeekendDay(day) {
|
|
506
|
-
return this.weekendDays.includes(day);
|
|
507
|
-
},
|
|
508
|
-
_triggerChange() {
|
|
509
|
-
let val = this.date;
|
|
510
|
-
if (this.range) {
|
|
511
|
-
val = this.dateStart && this.dateEnd ? [this.dateStart, this.dateEnd] : [];
|
|
512
|
-
}
|
|
513
|
-
this.syncMonthYear = false;
|
|
514
|
-
/**
|
|
515
|
-
* Date change event
|
|
516
|
-
* @property {Date} date
|
|
517
|
-
*/
|
|
518
|
-
this.$emit('input', val);
|
|
519
|
-
/**
|
|
520
|
-
* Date change event
|
|
521
|
-
* @property {Date} date
|
|
522
|
-
*/
|
|
523
|
-
this.$emit('change', val);
|
|
524
|
-
},
|
|
525
|
-
},
|
|
526
|
-
};
|
|
527
|
-
</script>
|
|
1
|
+
<template>
|
|
2
|
+
<div class="ui-date-picker">
|
|
3
|
+
<div class="panel d-inline-flex flex-col scroll-hide">
|
|
4
|
+
<div class="row row-collapse row-vgap-none flex-nowrap">
|
|
5
|
+
<div class="col col-auto" v-if="$scopedSlots.left">
|
|
6
|
+
<!--
|
|
7
|
+
@slot Custom left content
|
|
8
|
+
-->
|
|
9
|
+
<slot name="left"></slot>
|
|
10
|
+
</div>
|
|
11
|
+
<div class="col col-auto">
|
|
12
|
+
<!--
|
|
13
|
+
@slot Custom header content
|
|
14
|
+
@binding {Function} prevYear select previous year
|
|
15
|
+
@binding {Function} prevMonth select previous month
|
|
16
|
+
@binding {Function} nextYear select next year
|
|
17
|
+
@binding {Function} nextMonth select next month
|
|
18
|
+
@binding {Function} setMonth set month by index (0 = january)
|
|
19
|
+
@binding {Function} setYear set year (4-digit)
|
|
20
|
+
@binding {Function} setToday set today's date
|
|
21
|
+
@binding {Number} month current month index (0 = january)
|
|
22
|
+
@binding {String} monthName current month name
|
|
23
|
+
@binding {Number} year current year (4-digit)
|
|
24
|
+
-->
|
|
25
|
+
<slot
|
|
26
|
+
name="header"
|
|
27
|
+
v-bind="{
|
|
28
|
+
prevYear,
|
|
29
|
+
prevMonth,
|
|
30
|
+
nextYear,
|
|
31
|
+
nextMonth,
|
|
32
|
+
setMonth,
|
|
33
|
+
setYear,
|
|
34
|
+
setToday,
|
|
35
|
+
month,
|
|
36
|
+
monthName: monthNames[month],
|
|
37
|
+
year,
|
|
38
|
+
}"
|
|
39
|
+
>
|
|
40
|
+
<div
|
|
41
|
+
class="ui-date-picker-header text-small mar-bot-3 bg-primary color-white pad-3"
|
|
42
|
+
>
|
|
43
|
+
<div class="flex-shrink nobr">
|
|
44
|
+
<div class="icon cursor-pointer" @click="prevYear">
|
|
45
|
+
<i class="mdi mdi-chevron-double-left"></i>
|
|
46
|
+
</div>
|
|
47
|
+
<div class="icon cursor-pointer" @click="prevMonth">
|
|
48
|
+
<i class="mdi mdi-chevron-left"></i>
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
<div class="flex-grow flex-h-center d-flex">
|
|
52
|
+
<span>{{ monthNames[month] }}</span>
|
|
53
|
+
<input class="color-inherit" type="number" v-model.number="year" />
|
|
54
|
+
</div>
|
|
55
|
+
<div class="flex-shrink nobr">
|
|
56
|
+
<div class="icon cursor-pointer" @click="nextMonth">
|
|
57
|
+
<i class="mdi mdi-chevron-right"></i>
|
|
58
|
+
</div>
|
|
59
|
+
<div class="icon cursor-pointer" @click="nextYear">
|
|
60
|
+
<i class="mdi mdi-chevron-double-right"></i>
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
</slot>
|
|
65
|
+
<div class="ui-date-picker-grid pad-3">
|
|
66
|
+
<div
|
|
67
|
+
class="ui-date-picker-day-cell text-small"
|
|
68
|
+
v-for="dayIndex of dayNamesIndexes"
|
|
69
|
+
:key="`day-${dayIndex}`"
|
|
70
|
+
>
|
|
71
|
+
<!--
|
|
72
|
+
@slot Custom day content
|
|
73
|
+
@binding {Number} dayIndex day index (0 = sunday)
|
|
74
|
+
@binding {String} dayName day name
|
|
75
|
+
@binding {Boolean} isWeekend whether a weekend day
|
|
76
|
+
-->
|
|
77
|
+
<slot
|
|
78
|
+
name="cell-day"
|
|
79
|
+
v-bind="{
|
|
80
|
+
dayIndex,
|
|
81
|
+
dayName: dayNames[dayIndex],
|
|
82
|
+
isWeekend: isWeekendDay(dayIndex),
|
|
83
|
+
}"
|
|
84
|
+
>
|
|
85
|
+
<div class="color-grey-dark">
|
|
86
|
+
{{ dayNames[dayIndex] }}
|
|
87
|
+
</div>
|
|
88
|
+
</slot>
|
|
89
|
+
</div>
|
|
90
|
+
<div
|
|
91
|
+
class="ui-date-picker-date-cell text-small"
|
|
92
|
+
v-for="n in currentMonthDates"
|
|
93
|
+
:key="`${n.getMonth()}-${n.getDate()}`"
|
|
94
|
+
>
|
|
95
|
+
<!--
|
|
96
|
+
@slot Custom date content
|
|
97
|
+
@binding {Date} date date
|
|
98
|
+
@binding {Date} dateStart range start date
|
|
99
|
+
@binding {Date} dateEnd range end date
|
|
100
|
+
@binding {Number} month current view month
|
|
101
|
+
@binding {Number} year current view year
|
|
102
|
+
@binding {Boolean} isCurrentMonthDate is date in current month view
|
|
103
|
+
@binding {Boolean} isDisabledDate is date disabled
|
|
104
|
+
@binding {Boolean} isInRange is date in range
|
|
105
|
+
@binding {Boolean} isRangeStart is date = range start
|
|
106
|
+
@binding {Boolean} isRangeEnd is date = range end
|
|
107
|
+
@binding {Boolean} isSelected is date selected
|
|
108
|
+
@binding {Boolean} isToday is date today
|
|
109
|
+
@binding {Boolean} isWeekend is date a weekend day
|
|
110
|
+
@binding {Function} setDate set date
|
|
111
|
+
-->
|
|
112
|
+
<slot
|
|
113
|
+
name="cell-date"
|
|
114
|
+
v-bind="{
|
|
115
|
+
date: n,
|
|
116
|
+
dateStart,
|
|
117
|
+
dateEnd,
|
|
118
|
+
month,
|
|
119
|
+
year,
|
|
120
|
+
isCurrentMonthDate: isCurrentMonthDate(n),
|
|
121
|
+
isDisabledDate: isDisabledDate(n),
|
|
122
|
+
isInRange: isRangeDate(n),
|
|
123
|
+
isRangeStart: isRangeStartDate(n),
|
|
124
|
+
isRangeEnd: isRangeEndDate(n),
|
|
125
|
+
isSelected: isSelectedDate(n),
|
|
126
|
+
isToday: isTodayDate(n),
|
|
127
|
+
isWeekend: isWeekendDate(n),
|
|
128
|
+
setDate,
|
|
129
|
+
}"
|
|
130
|
+
>
|
|
131
|
+
<div
|
|
132
|
+
class="btn btn-icon btn-small"
|
|
133
|
+
:class="{
|
|
134
|
+
'btn-primary': isSelectedDate(n) || isRangeDate(n),
|
|
135
|
+
'radius-right-none':
|
|
136
|
+
isRangeStartDate(n) && !isRangeEndDate(n) && dateEnd,
|
|
137
|
+
'radius-left-none':
|
|
138
|
+
!isRangeStartDate(n) && isRangeEndDate(n),
|
|
139
|
+
'radius-none':
|
|
140
|
+
isRangeDate(n) &&
|
|
141
|
+
!isRangeStartDate(n) &&
|
|
142
|
+
!isRangeEndDate(n),
|
|
143
|
+
'disabled radius-none': isDisabledDate(n),
|
|
144
|
+
}"
|
|
145
|
+
@click="setDate(n)"
|
|
146
|
+
>
|
|
147
|
+
<template v-if="isSelectedDate(n) || isRangeDate(n)">
|
|
148
|
+
<div>{{ n.getDate() }}</div>
|
|
149
|
+
</template>
|
|
150
|
+
<template v-else-if="isTodayDate(n)">
|
|
151
|
+
<div class="color-primary">{{ n.getDate() }}</div>
|
|
152
|
+
</template>
|
|
153
|
+
<template v-else-if="!isCurrentMonthDate(n)">
|
|
154
|
+
<div class="text-muted">{{ n.getDate() }}</div>
|
|
155
|
+
</template>
|
|
156
|
+
<template v-else>
|
|
157
|
+
<div class="color-body">{{ n.getDate() }}</div>
|
|
158
|
+
</template>
|
|
159
|
+
</div>
|
|
160
|
+
</slot>
|
|
161
|
+
</div>
|
|
162
|
+
</div>
|
|
163
|
+
</div>
|
|
164
|
+
<div class="col col-auto" v-if="$scopedSlots.right">
|
|
165
|
+
<!--
|
|
166
|
+
@slot Custom right content
|
|
167
|
+
-->
|
|
168
|
+
<slot name="right"></slot>
|
|
169
|
+
</div>
|
|
170
|
+
</div>
|
|
171
|
+
</div>
|
|
172
|
+
</div>
|
|
173
|
+
</template>
|
|
174
|
+
<style lang="less" scoped>
|
|
175
|
+
.ui-date-picker {
|
|
176
|
+
display: inline-flex;
|
|
177
|
+
color: var(--color-body);
|
|
178
|
+
&-header {
|
|
179
|
+
display: flex;
|
|
180
|
+
align-items: center;
|
|
181
|
+
input {
|
|
182
|
+
width: 3em;
|
|
183
|
+
border: none;
|
|
184
|
+
background: transparent;
|
|
185
|
+
outline: none;
|
|
186
|
+
text-align: center;
|
|
187
|
+
margin: 0;
|
|
188
|
+
padding: 0;
|
|
189
|
+
outline: none;
|
|
190
|
+
-moz-appearance: textfield;
|
|
191
|
+
&::-webkit-outer-spin-button,
|
|
192
|
+
&::-webkit-inner-spin-button {
|
|
193
|
+
-webkit-appearance: none;
|
|
194
|
+
margin: 0;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
&-grid {
|
|
199
|
+
display: grid;
|
|
200
|
+
grid-template-columns: repeat(7, 1fr);
|
|
201
|
+
grid-auto-rows: 1fr;
|
|
202
|
+
row-gap: 1px;
|
|
203
|
+
}
|
|
204
|
+
&-day-cell,
|
|
205
|
+
&-date-cell {
|
|
206
|
+
position: relative;
|
|
207
|
+
display: flex;
|
|
208
|
+
align-items: center;
|
|
209
|
+
justify-content: center;
|
|
210
|
+
}
|
|
211
|
+
.flex-nowrap {
|
|
212
|
+
flex-wrap: nowrap;
|
|
213
|
+
}
|
|
214
|
+
.radius-left-none {
|
|
215
|
+
border-top-left-radius: 0;
|
|
216
|
+
border-bottom-left-radius: 0;
|
|
217
|
+
}
|
|
218
|
+
.radius-right-none {
|
|
219
|
+
border-top-right-radius: 0;
|
|
220
|
+
border-bottom-right-radius: 0;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
</style>
|
|
224
|
+
<script>
|
|
225
|
+
import { isDateValid } from './utils/Helpers';
|
|
226
|
+
|
|
227
|
+
export default {
|
|
228
|
+
props: {
|
|
229
|
+
/**
|
|
230
|
+
* @model
|
|
231
|
+
*/
|
|
232
|
+
value: {
|
|
233
|
+
type: [Date, Array],
|
|
234
|
+
default: null,
|
|
235
|
+
validation(val) {
|
|
236
|
+
if (Array.isArray(val)) {
|
|
237
|
+
return val.find(el => !this.isValid(el)) == null;
|
|
238
|
+
} else {
|
|
239
|
+
return this.isValid(val);
|
|
240
|
+
}
|
|
241
|
+
},
|
|
242
|
+
},
|
|
243
|
+
/**
|
|
244
|
+
* Min date (inclusive)
|
|
245
|
+
*/
|
|
246
|
+
min: {
|
|
247
|
+
type: Date,
|
|
248
|
+
default: null,
|
|
249
|
+
},
|
|
250
|
+
/**
|
|
251
|
+
* Max date (inclusive)
|
|
252
|
+
*/
|
|
253
|
+
max: {
|
|
254
|
+
type: Date,
|
|
255
|
+
default: null,
|
|
256
|
+
},
|
|
257
|
+
/**
|
|
258
|
+
* Allowed date filter function(date:Date):Boolean
|
|
259
|
+
*/
|
|
260
|
+
allowed: {
|
|
261
|
+
type: Function,
|
|
262
|
+
default: () => true,
|
|
263
|
+
},
|
|
264
|
+
/**
|
|
265
|
+
* Range mode
|
|
266
|
+
*/
|
|
267
|
+
range: {
|
|
268
|
+
type: Boolean,
|
|
269
|
+
default: false,
|
|
270
|
+
},
|
|
271
|
+
/**
|
|
272
|
+
* Day names starting from 'Sunday'
|
|
273
|
+
*/
|
|
274
|
+
dayNames: {
|
|
275
|
+
type: Array,
|
|
276
|
+
default() {
|
|
277
|
+
return ['Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'];
|
|
278
|
+
},
|
|
279
|
+
},
|
|
280
|
+
/**
|
|
281
|
+
* Weekend day indexes (0 = Sunday; 6 = Saturday)
|
|
282
|
+
*/
|
|
283
|
+
weekendDays: {
|
|
284
|
+
type: Array,
|
|
285
|
+
default() {
|
|
286
|
+
return [0, 6];
|
|
287
|
+
},
|
|
288
|
+
},
|
|
289
|
+
/**
|
|
290
|
+
* Month names starting from 'January'
|
|
291
|
+
*/
|
|
292
|
+
monthNames: {
|
|
293
|
+
type: Array,
|
|
294
|
+
default() {
|
|
295
|
+
return [
|
|
296
|
+
'Январь',
|
|
297
|
+
'Февраль',
|
|
298
|
+
'Март',
|
|
299
|
+
'Апрель',
|
|
300
|
+
'Май',
|
|
301
|
+
'Июнь',
|
|
302
|
+
'Июль',
|
|
303
|
+
'Август',
|
|
304
|
+
'Сентябрь',
|
|
305
|
+
'Октябрь',
|
|
306
|
+
'Ноябрь',
|
|
307
|
+
'Декабрь',
|
|
308
|
+
];
|
|
309
|
+
},
|
|
310
|
+
},
|
|
311
|
+
/**
|
|
312
|
+
* Which day is the first day of the week (0 = Sunday; 6 = Saturday)
|
|
313
|
+
*/
|
|
314
|
+
dayOfWeek: {
|
|
315
|
+
type: Number,
|
|
316
|
+
default: 1,
|
|
317
|
+
validation(val) {
|
|
318
|
+
return val >= 0 && val < 7;
|
|
319
|
+
},
|
|
320
|
+
},
|
|
321
|
+
},
|
|
322
|
+
data() {
|
|
323
|
+
return {
|
|
324
|
+
date: null,
|
|
325
|
+
dateStart: null,
|
|
326
|
+
dateEnd: null,
|
|
327
|
+
month: null,
|
|
328
|
+
year: null,
|
|
329
|
+
syncMonthYear: true,
|
|
330
|
+
};
|
|
331
|
+
},
|
|
332
|
+
computed: {
|
|
333
|
+
dayNamesIndexes() {
|
|
334
|
+
let a = [];
|
|
335
|
+
for (let i = this.dayOfWeek; i < 7 + this.dayOfWeek; ++i) {
|
|
336
|
+
a.push(i >= 7 ? i - 7 : i);
|
|
337
|
+
}
|
|
338
|
+
return a;
|
|
339
|
+
},
|
|
340
|
+
firstDayOfMonth() {
|
|
341
|
+
let n = new Date(this.year, this.month, 1).getDay() - this.dayOfWeek;
|
|
342
|
+
return n < 0 ? 7 + n : n;
|
|
343
|
+
},
|
|
344
|
+
lastDayOfMonth() {
|
|
345
|
+
let n = new Date(this.year, this.month + 1, 0).getDay() - this.dayOfWeek;
|
|
346
|
+
return n < 0 ? 7 + n : n;
|
|
347
|
+
},
|
|
348
|
+
daysInMonth() {
|
|
349
|
+
return new Date(this.year, this.month + 1, 0).getDate();
|
|
350
|
+
},
|
|
351
|
+
currentMonthDates() {
|
|
352
|
+
let dates = [...new Array(this.daysInMonth)].map(
|
|
353
|
+
(v, i) => new Date(this.year, this.month, i + 1)
|
|
354
|
+
);
|
|
355
|
+
return [...this.prevMonthDates, ...dates, ...this.nextMonthDates];
|
|
356
|
+
},
|
|
357
|
+
prevMonthDates() {
|
|
358
|
+
let n = this.firstDayOfMonth;
|
|
359
|
+
let pmd = new Date(this.year, this.month, 0).getDate();
|
|
360
|
+
return [...new Array(n)]
|
|
361
|
+
.map((v, i) => new Date(this.year, this.month - 1, pmd - i))
|
|
362
|
+
.reverse();
|
|
363
|
+
},
|
|
364
|
+
nextMonthDates() {
|
|
365
|
+
let n = 6 - this.lastDayOfMonth;
|
|
366
|
+
return [...new Array(n)].map((v, i) => new Date(this.year, this.month + 1, i + 1));
|
|
367
|
+
},
|
|
368
|
+
},
|
|
369
|
+
watch: {
|
|
370
|
+
value: {
|
|
371
|
+
handler(val) {
|
|
372
|
+
let d = new Date();
|
|
373
|
+
if (this.range && Array.isArray(val)) {
|
|
374
|
+
let [start, end] = val;
|
|
375
|
+
this.dateStart = start || null;
|
|
376
|
+
this.dateEnd = end || null;
|
|
377
|
+
d = start || d;
|
|
378
|
+
} else {
|
|
379
|
+
this.date = val;
|
|
380
|
+
d = val || d;
|
|
381
|
+
}
|
|
382
|
+
if (this.syncMonthYear) {
|
|
383
|
+
this.month = d.getMonth();
|
|
384
|
+
this.year = d.getFullYear();
|
|
385
|
+
}
|
|
386
|
+
this.syncMonthYear = true;
|
|
387
|
+
},
|
|
388
|
+
immediate: true,
|
|
389
|
+
},
|
|
390
|
+
range() {
|
|
391
|
+
this.date = null;
|
|
392
|
+
this.dateStart = null;
|
|
393
|
+
this.dateEnd = null;
|
|
394
|
+
this._triggerChange();
|
|
395
|
+
},
|
|
396
|
+
},
|
|
397
|
+
methods: {
|
|
398
|
+
isValid(date) {
|
|
399
|
+
return isDateValid(date);
|
|
400
|
+
},
|
|
401
|
+
prevMonth() {
|
|
402
|
+
let n = this.month - 1;
|
|
403
|
+
this.month = n < 0 ? 11 : n;
|
|
404
|
+
this.year -= n < 0 ? 1 : 0;
|
|
405
|
+
},
|
|
406
|
+
prevYear() {
|
|
407
|
+
this.year = this.year - 1;
|
|
408
|
+
},
|
|
409
|
+
nextMonth() {
|
|
410
|
+
let n = this.month + 1;
|
|
411
|
+
this.month = n > 11 ? 0 : n;
|
|
412
|
+
this.year += n > 11 ? 1 : 0;
|
|
413
|
+
},
|
|
414
|
+
nextYear() {
|
|
415
|
+
this.year = this.year + 1;
|
|
416
|
+
},
|
|
417
|
+
setYear(n) {
|
|
418
|
+
this.year = n;
|
|
419
|
+
},
|
|
420
|
+
setMonth(n) {
|
|
421
|
+
this.month = n;
|
|
422
|
+
},
|
|
423
|
+
setDate(date) {
|
|
424
|
+
let d = this.isValid(date) ? date : new Date(this.year, this.month, date);
|
|
425
|
+
|
|
426
|
+
if (this.range) {
|
|
427
|
+
if (!this.dateStart || (this.dateStart && this.dateEnd)) {
|
|
428
|
+
this.dateStart = d;
|
|
429
|
+
this.dateEnd = null;
|
|
430
|
+
} else {
|
|
431
|
+
if (d < this.dateStart) {
|
|
432
|
+
this.dateEnd = this.dateStart;
|
|
433
|
+
this.dateStart = d;
|
|
434
|
+
} else if (d > this.dateStart) {
|
|
435
|
+
this.dateEnd = d;
|
|
436
|
+
} else {
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
this._triggerChange();
|
|
440
|
+
}
|
|
441
|
+
} else {
|
|
442
|
+
this.date = d;
|
|
443
|
+
this._triggerChange();
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Set date event
|
|
447
|
+
* @property {Date} date
|
|
448
|
+
*/
|
|
449
|
+
this.$emit('set-date', d);
|
|
450
|
+
},
|
|
451
|
+
setToday() {
|
|
452
|
+
this.date = new Date();
|
|
453
|
+
this.month = this.date.getMonth();
|
|
454
|
+
this.year = this.date.getFullYear();
|
|
455
|
+
this._triggerChange();
|
|
456
|
+
/**
|
|
457
|
+
* Set date event
|
|
458
|
+
* @property {Date} date
|
|
459
|
+
*/
|
|
460
|
+
this.$emit('set-date', this.date);
|
|
461
|
+
},
|
|
462
|
+
isCurrentMonthDate(date) {
|
|
463
|
+
if (this.isValid(date)) {
|
|
464
|
+
return this.month == date.getMonth();
|
|
465
|
+
}
|
|
466
|
+
return true;
|
|
467
|
+
},
|
|
468
|
+
isDisabledDate(date) {
|
|
469
|
+
let d = this.isValid(date) ? date : new Date(this.year, this.month, date);
|
|
470
|
+
let { min, max, allowed } = this;
|
|
471
|
+
return (min && d < min) || (max && d > max) || (allowed && !allowed(d));
|
|
472
|
+
},
|
|
473
|
+
isRangeStartDate(date) {
|
|
474
|
+
let d = this.isValid(date) ? date : new Date(this.year, this.month, date);
|
|
475
|
+
return this.dateStart && +d == +this.dateStart;
|
|
476
|
+
},
|
|
477
|
+
isRangeEndDate(date) {
|
|
478
|
+
let d = this.isValid(date) ? date : new Date(this.year, this.month, date);
|
|
479
|
+
return this.dateEnd && +d == +this.dateEnd;
|
|
480
|
+
},
|
|
481
|
+
isRangeDate(date) {
|
|
482
|
+
let d = this.isValid(date) ? date : new Date(this.year, this.month, date);
|
|
483
|
+
if (this.dateStart && +d == +this.dateStart) {
|
|
484
|
+
return true;
|
|
485
|
+
}
|
|
486
|
+
return this.dateStart && this.dateEnd && d >= this.dateStart && d <= this.dateEnd;
|
|
487
|
+
},
|
|
488
|
+
isSelectedDate(date) {
|
|
489
|
+
let d = this.isValid(date) ? date : new Date(this.year, this.month, date);
|
|
490
|
+
return this.date && +this.date == +date;
|
|
491
|
+
},
|
|
492
|
+
isWeekendDate(date) {
|
|
493
|
+
let d = this.isValid(date) ? date : new Date(this.year, this.month, date);
|
|
494
|
+
return this.weekendDays.includes(d.getDay());
|
|
495
|
+
},
|
|
496
|
+
isTodayDate(date) {
|
|
497
|
+
let d = this.isValid(date) ? date : new Date(this.year, this.month, date);
|
|
498
|
+
let now = new Date();
|
|
499
|
+
return (
|
|
500
|
+
now.getFullYear() === d.getFullYear() &&
|
|
501
|
+
now.getMonth() === d.getMonth() &&
|
|
502
|
+
now.getDate() === d.getDate()
|
|
503
|
+
);
|
|
504
|
+
},
|
|
505
|
+
isWeekendDay(day) {
|
|
506
|
+
return this.weekendDays.includes(day);
|
|
507
|
+
},
|
|
508
|
+
_triggerChange() {
|
|
509
|
+
let val = this.date;
|
|
510
|
+
if (this.range) {
|
|
511
|
+
val = this.dateStart && this.dateEnd ? [this.dateStart, this.dateEnd] : [];
|
|
512
|
+
}
|
|
513
|
+
this.syncMonthYear = false;
|
|
514
|
+
/**
|
|
515
|
+
* Date change event
|
|
516
|
+
* @property {Date} date
|
|
517
|
+
*/
|
|
518
|
+
this.$emit('input', val);
|
|
519
|
+
/**
|
|
520
|
+
* Date change event
|
|
521
|
+
* @property {Date} date
|
|
522
|
+
*/
|
|
523
|
+
this.$emit('change', val);
|
|
524
|
+
},
|
|
525
|
+
},
|
|
526
|
+
};
|
|
527
|
+
</script>
|