bi-eleme 2.2.1 → 2.4.2

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.
Files changed (130) hide show
  1. package/lib/alert.js +4 -4
  2. package/lib/aside.js +4 -4
  3. package/lib/autocomplete.js +10 -10
  4. package/lib/avatar.js +4 -4
  5. package/lib/backtop.js +6 -6
  6. package/lib/badge.js +4 -4
  7. package/lib/breadcrumb-item.js +4 -4
  8. package/lib/breadcrumb.js +4 -4
  9. package/lib/button-group.js +4 -4
  10. package/lib/button.js +4 -4
  11. package/lib/calendar.js +15 -15
  12. package/lib/card.js +4 -4
  13. package/lib/carousel-item.js +4 -4
  14. package/lib/carousel.js +6 -6
  15. package/lib/cascader-panel.js +10 -10
  16. package/lib/cascader.js +12 -12
  17. package/lib/checkbox-button.js +4 -4
  18. package/lib/checkbox-group.js +4 -4
  19. package/lib/checkbox.js +4 -4
  20. package/lib/col.js +2 -2
  21. package/lib/collapse-item.js +6 -6
  22. package/lib/collapse.js +4 -4
  23. package/lib/color-picker.js +8 -8
  24. package/lib/container.js +4 -4
  25. package/lib/date-picker.js +65 -64
  26. package/lib/descriptions-item.js +2 -2
  27. package/lib/descriptions.js +2 -2
  28. package/lib/dialog.js +8 -8
  29. package/lib/divider.js +4 -4
  30. package/lib/drawer.js +6 -6
  31. package/lib/dropdown-item.js +4 -4
  32. package/lib/dropdown-menu.js +4 -4
  33. package/lib/dropdown.js +16 -16
  34. package/lib/element-ui.common.js +4772 -311
  35. package/lib/empty.js +4 -4
  36. package/lib/footer.js +4 -4
  37. package/lib/form-item.js +6 -6
  38. package/lib/form.js +11 -11
  39. package/lib/header.js +4 -4
  40. package/lib/icon.js +4 -4
  41. package/lib/image.js +8 -8
  42. package/lib/index.js +1 -1
  43. package/lib/infinite-scroll.js +2 -2
  44. package/lib/input-number.js +6 -6
  45. package/lib/input.js +6 -6
  46. package/lib/link.js +4 -4
  47. package/lib/loading.js +6 -6
  48. package/lib/main.js +4 -4
  49. package/lib/menu-item-group.js +4 -4
  50. package/lib/menu-item.js +6 -6
  51. package/lib/menu.js +6 -6
  52. package/lib/message-box.js +13 -13
  53. package/lib/message.js +8 -8
  54. package/lib/notification.js +8 -8
  55. package/lib/option-group.js +4 -4
  56. package/lib/option.js +4 -4
  57. package/lib/page-header.js +4 -4
  58. package/lib/pagination.js +4 -4
  59. package/lib/popconfirm.js +8 -8
  60. package/lib/popover.js +4 -4
  61. package/lib/progress.js +4 -4
  62. package/lib/radio-button.js +4 -4
  63. package/lib/radio-group.js +4 -4
  64. package/lib/radio.js +4 -4
  65. package/lib/rate.js +6 -6
  66. package/lib/result.js +4 -4
  67. package/lib/row.js +2 -2
  68. package/lib/scrollbar.js +2 -2
  69. package/lib/select.js +16 -16
  70. package/lib/skeleton-item.js +4 -4
  71. package/lib/skeleton.js +4 -4
  72. package/lib/slider.js +8 -8
  73. package/lib/spinner.js +4 -4
  74. package/lib/step.js +4 -4
  75. package/lib/steps.js +6 -6
  76. package/lib/submenu.js +6 -6
  77. package/lib/super-date.js +4832 -0
  78. package/lib/switch.js +6 -6
  79. package/lib/tab-pane.js +4 -4
  80. package/lib/table-column.js +2 -2
  81. package/lib/table.js +20 -18
  82. package/lib/tabs.js +4 -4
  83. package/lib/tag.js +4 -4
  84. package/lib/theme-chalk/index.css +1 -1
  85. package/lib/theme-chalk/super-date.css +1 -0
  86. package/lib/time-picker.js +59 -59
  87. package/lib/time-select.js +16 -16
  88. package/lib/timeline-item.js +4 -4
  89. package/lib/timeline.js +4 -4
  90. package/lib/tooltip.js +2 -2
  91. package/lib/transfer.js +8 -8
  92. package/lib/tree.js +6 -6
  93. package/lib/upload.js +15 -15
  94. package/lib/utils/date-util.js +5 -2
  95. package/lib/utils/date.js +67 -9
  96. package/package.json +1 -1
  97. package/packages/super-date/index.js +8 -0
  98. package/packages/super-date/src/basic/date-table.vue +448 -0
  99. package/packages/super-date/src/basic/month-table.vue +278 -0
  100. package/packages/super-date/src/basic/time-spinner.vue +340 -0
  101. package/packages/super-date/src/basic/year-table.vue +144 -0
  102. package/packages/super-date/src/panel/date-range.vue +1000 -0
  103. package/packages/super-date/src/panel/date.vue +649 -0
  104. package/packages/super-date/src/panel/month-range.vue +289 -0
  105. package/packages/super-date/src/panel/time-range.vue +250 -0
  106. package/packages/super-date/src/panel/time-select.vue +195 -0
  107. package/packages/super-date/src/panel/time.vue +211 -0
  108. package/packages/super-date/src/picker/date-picker.js +29 -0
  109. package/packages/super-date/src/picker/time-picker.js +39 -0
  110. package/packages/super-date/src/picker/time-select.js +21 -0
  111. package/packages/super-date/src/picker.vue +955 -0
  112. package/packages/theme-chalk/lib/index.css +1 -1
  113. package/packages/theme-chalk/lib/super-date.css +1 -0
  114. package/packages/theme-chalk/src/index.scss +1 -0
  115. package/packages/theme-chalk/src/super-date/date-picker.scss +106 -0
  116. package/packages/theme-chalk/src/super-date/date-range-picker.scss +138 -0
  117. package/packages/theme-chalk/src/super-date/date-table.scss +154 -0
  118. package/packages/theme-chalk/src/super-date/month-table.scss +96 -0
  119. package/packages/theme-chalk/src/super-date/picker-panel.scss +130 -0
  120. package/packages/theme-chalk/src/super-date/picker.scss +204 -0
  121. package/packages/theme-chalk/src/super-date/time-picker.scss +94 -0
  122. package/packages/theme-chalk/src/super-date/time-range-picker.scss +32 -0
  123. package/packages/theme-chalk/src/super-date/time-spinner.scss +111 -0
  124. package/packages/theme-chalk/src/super-date/year-table.scss +66 -0
  125. package/packages/theme-chalk/src/super-date.scss +12 -0
  126. package/src/index.js +4 -1
  127. package/src/utils/date-util.js +3 -0
  128. package/src/utils/date.js +291 -195
  129. package/types/element-ui.d.ts +9 -5
  130. package/types/super-date.d.ts +124 -0
package/lib/upload.js CHANGED
@@ -82,12 +82,12 @@ module.exports =
82
82
  /******/
83
83
  /******/
84
84
  /******/ // Load entry module and return exports
85
- /******/ return __webpack_require__(__webpack_require__.s = 58);
85
+ /******/ return __webpack_require__(__webpack_require__.s = 60);
86
86
  /******/ })
87
87
  /************************************************************************/
88
88
  /******/ ({
89
89
 
90
- /***/ 0:
90
+ /***/ 1:
91
91
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
92
92
 
93
93
  "use strict";
@@ -192,14 +192,14 @@ function normalizeComponent(
192
192
 
193
193
  /***/ }),
194
194
 
195
- /***/ 11:
195
+ /***/ 12:
196
196
  /***/ (function(module, exports) {
197
197
 
198
198
  module.exports = require("bi-eleme/lib/mixins/migrating");
199
199
 
200
200
  /***/ }),
201
201
 
202
- /***/ 26:
202
+ /***/ 27:
203
203
  /***/ (function(module, exports) {
204
204
 
205
205
  module.exports = require("babel-helper-vue-jsx-merge-props");
@@ -213,7 +213,14 @@ module.exports = require("bi-eleme/lib/progress");
213
213
 
214
214
  /***/ }),
215
215
 
216
- /***/ 58:
216
+ /***/ 6:
217
+ /***/ (function(module, exports) {
218
+
219
+ module.exports = require("bi-eleme/lib/mixins/locale");
220
+
221
+ /***/ }),
222
+
223
+ /***/ 60:
217
224
  /***/ (function(module, __webpack_exports__, __webpack_require__) {
218
225
 
219
226
  "use strict";
@@ -515,7 +522,7 @@ var progress_default = /*#__PURE__*/__webpack_require__.n(progress_);
515
522
  // CONCATENATED MODULE: ./packages/upload/src/upload-list.vue?vue&type=script&lang=js
516
523
  /* harmony default export */ var src_upload_listvue_type_script_lang_js = (upload_listvue_type_script_lang_js);
517
524
  // EXTERNAL MODULE: ./node_modules/.store/vue-loader@15.11.1/node_modules/vue-loader/lib/runtime/componentNormalizer.js
518
- var componentNormalizer = __webpack_require__(0);
525
+ var componentNormalizer = __webpack_require__(1);
519
526
 
520
527
  // CONCATENATED MODULE: ./packages/upload/src/upload-list.vue
521
528
 
@@ -538,7 +545,7 @@ var component = Object(componentNormalizer["a" /* default */])(
538
545
 
539
546
  /* harmony default export */ var upload_list = (component.exports);
540
547
  // EXTERNAL MODULE: external "babel-helper-vue-jsx-merge-props"
541
- var external_babel_helper_vue_jsx_merge_props_ = __webpack_require__(26);
548
+ var external_babel_helper_vue_jsx_merge_props_ = __webpack_require__(27);
542
549
  var external_babel_helper_vue_jsx_merge_props_default = /*#__PURE__*/__webpack_require__.n(external_babel_helper_vue_jsx_merge_props_);
543
550
 
544
551
  // CONCATENATED MODULE: ./packages/upload/src/ajax.js
@@ -1014,7 +1021,7 @@ var upload_component = Object(componentNormalizer["a" /* default */])(
1014
1021
 
1015
1022
  /* harmony default export */ var src_upload = (upload_component.exports);
1016
1023
  // EXTERNAL MODULE: external "bi-eleme/lib/mixins/migrating"
1017
- var migrating_ = __webpack_require__(11);
1024
+ var migrating_ = __webpack_require__(12);
1018
1025
  var migrating_default = /*#__PURE__*/__webpack_require__.n(migrating_);
1019
1026
 
1020
1027
  // CONCATENATED MODULE: ./node_modules/.store/babel-loader@7.1.5/node_modules/babel-loader/lib!./node_modules/.store/vue-loader@15.11.1/node_modules/vue-loader/lib??vue-loader-options!./packages/upload/src/index.vue?vue&type=script&lang=js
@@ -1388,13 +1395,6 @@ src.install = function (Vue) {
1388
1395
 
1389
1396
  /* harmony default export */ var packages_upload = __webpack_exports__["default"] = (src);
1390
1397
 
1391
- /***/ }),
1392
-
1393
- /***/ 6:
1394
- /***/ (function(module, exports) {
1395
-
1396
- module.exports = require("bi-eleme/lib/mixins/locale");
1397
-
1398
1398
  /***/ })
1399
1399
 
1400
1400
  /******/ });
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  exports.__esModule = true;
4
- exports.validateRangeInOneMonth = exports.extractTimeFormat = exports.extractDateFormat = exports.nextYear = exports.prevYear = exports.nextMonth = exports.prevMonth = exports.changeYearMonthAndClampDate = exports.timeWithinRange = exports.limitTimeRange = exports.clearMilliseconds = exports.getTimestampInTimezone = exports.clearTime = exports.modifyWithTimeString = exports.modifyTime = exports.modifyDate = exports.range = exports.getRangeMinutes = exports.getMonthDays = exports.getPrevMonthLastDays = exports.getRangeHours = exports.getWeekNumber = exports.getStartDateOfMonth = exports.nextDate = exports.prevDate = exports.getFirstDayOfMonth = exports.getDayCountOfYear = exports.getDayCountOfMonth = exports.parseDate = exports.formatDate = exports.isDateObject = exports.isDate = exports.toDate = exports.getI18nSettings = undefined;
4
+ exports.setDaysDiff = exports.getDaysDiff = exports.validateRangeInOneMonth = exports.extractTimeFormat = exports.extractDateFormat = exports.nextYear = exports.prevYear = exports.nextMonth = exports.prevMonth = exports.changeYearMonthAndClampDate = exports.timeWithinRange = exports.limitTimeRange = exports.clearMilliseconds = exports.getTimestampInTimezone = exports.clearTime = exports.modifyWithTimeString = exports.modifyTime = exports.modifyDate = exports.range = exports.getRangeMinutes = exports.getMonthDays = exports.getPrevMonthLastDays = exports.getRangeHours = exports.getWeekNumber = exports.getStartDateOfMonth = exports.nextDate = exports.prevDate = exports.getFirstDayOfMonth = exports.getDayCountOfYear = exports.getDayCountOfMonth = exports.parseDate = exports.formatDate = exports.isDateObject = exports.isDate = exports.toDate = exports.getI18nSettings = undefined;
5
5
 
6
6
  var _date = require('bi-eleme/lib/utils/date');
7
7
 
@@ -314,4 +314,7 @@ var extractTimeFormat = exports.extractTimeFormat = function extractTimeFormat(f
314
314
 
315
315
  var validateRangeInOneMonth = exports.validateRangeInOneMonth = function validateRangeInOneMonth(start, end) {
316
316
  return start.getMonth() === end.getMonth() && start.getFullYear() === end.getFullYear();
317
- };
317
+ };
318
+
319
+ var getDaysDiff = exports.getDaysDiff = _date2.default.getDaysDiff;
320
+ var setDaysDiff = exports.setDaysDiff = _date2.default.setDaysDiff;
package/lib/utils/date.js CHANGED
@@ -27,7 +27,7 @@
27
27
 
28
28
  /*eslint-disable*/
29
29
  // 把 YYYY-MM-DD 改成了 yyyy-MM-dd
30
- (function (main) {
30
+ ;(function (main) {
31
31
  'use strict';
32
32
 
33
33
  /**
@@ -251,15 +251,14 @@
251
251
  shortTime: 'HH:mm',
252
252
  mediumTime: 'HH:mm:ss',
253
253
  longTime: 'HH:mm:ss.SSS'
254
- };
255
254
 
256
- /***
257
- * Format a date
258
- * @method format
259
- * @param {Date|number} dateObj
260
- * @param {string} mask Format of the date, i.e. 'mm-dd-yy' or 'shortDate'
261
- */
262
- fecha.format = function (dateObj, mask, i18nSettings) {
255
+ /***
256
+ * Format a date
257
+ * @method format
258
+ * @param {Date|number} dateObj
259
+ * @param {string} mask Format of the date, i.e. 'mm-dd-yy' or 'shortDate'
260
+ */
261
+ };fecha.format = function (dateObj, mask, i18nSettings) {
263
262
  var i18n = i18nSettings || fecha.i18n;
264
263
 
265
264
  if (typeof dateObj === 'number') {
@@ -356,6 +355,65 @@
356
355
  return date;
357
356
  };
358
357
 
358
+ /**
359
+ * Calculate days difference between two dates
360
+ * @param {Date|string} date1 First date
361
+ * @param {Date|string} date2 Second date (optional, defaults to current date)
362
+ * @returns {number} Days difference
363
+ */
364
+ fecha.getDaysDiff = function (date1, date2) {
365
+ // Convert to Date objects if strings
366
+ if (typeof date1 === 'string') {
367
+ date1 = fecha.parse(date1, 'yyyy-MM-dd');
368
+ }
369
+ if (!date2) {
370
+ date2 = new Date();
371
+ } else if (typeof date2 === 'string') {
372
+ date2 = fecha.parse(date2, 'yyyy-MM-dd');
373
+ }
374
+
375
+ // Validate dates
376
+ if (!date1 || !date2 || isNaN(date1.getTime()) || isNaN(date2.getTime())) {
377
+ throw new Error('Invalid date in fecha.getDaysDiff');
378
+ }
379
+
380
+ // Reset time to midnight to ensure accurate day calculation
381
+ date1 = new Date(date1.getFullYear(), date1.getMonth(), date1.getDate());
382
+ date2 = new Date(date2.getFullYear(), date2.getMonth(), date2.getDate());
383
+
384
+ // Calculate difference in days
385
+ var timeDiff = date2.getTime() - date1.getTime();
386
+ return Math.round(timeDiff / (1000 * 60 * 60 * 24));
387
+ };
388
+
389
+ /**
390
+ * Calculate the date that is a specified number of days before the given date
391
+ * @param {Date|string} date The reference date
392
+ * @param {number} diff Number of days to subtract (must be positive)
393
+ * @returns {Date} The resulting date
394
+ */
395
+ fecha.setDaysDiff = function (date, diff) {
396
+ // Validate diff parameter
397
+ if (typeof diff !== 'number' || diff < 0) {
398
+ throw new Error('diff parameter must be a positive number in fecha.setDaysDiff');
399
+ }
400
+
401
+ // Convert to Date object if string
402
+ if (typeof date === 'string') {
403
+ date = fecha.parse(date, 'yyyy-MM-dd');
404
+ }
405
+
406
+ // Validate date
407
+ if (!date || isNaN(date.getTime())) {
408
+ throw new Error('Invalid date in fecha.setDaysDiff');
409
+ }
410
+
411
+ // Reset time to midnight to ensure accurate day calculation
412
+ var result = new Date(date.getFullYear(), date.getMonth(), date.getDate());
413
+ result.setDate(result.getDate() - diff);
414
+ return result;
415
+ };
416
+
359
417
  /* istanbul ignore next */
360
418
  if (typeof module !== 'undefined' && module.exports) {
361
419
  module.exports = fecha;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bi-eleme",
3
- "version": "2.2.1",
3
+ "version": "2.4.2",
4
4
  "description": "A Component Library for Vue.js.from element-ui@2.15.10",
5
5
  "main": "lib/element-ui.common.js",
6
6
  "files": [
@@ -0,0 +1,8 @@
1
+ import DatePicker from './src/picker/date-picker';
2
+
3
+ /* istanbul ignore next */
4
+ DatePicker.install = function install(Vue) {
5
+ Vue.component(DatePicker.name, DatePicker);
6
+ };
7
+
8
+ export default DatePicker;
@@ -0,0 +1,448 @@
1
+ <template>
2
+ <table
3
+ cellspacing="0"
4
+ cellpadding="0"
5
+ class="el-date-table"
6
+ @click="handleClick"
7
+ @mousemove="handleMouseMove"
8
+ :class="{ 'is-week-mode': selectionMode === 'week' }"
9
+ >
10
+ <tbody>
11
+ <tr>
12
+ <th v-if="showWeekNumber">{{ t('el.datepicker.week') }}</th>
13
+ <th
14
+ v-for="(week, key) in WEEKS"
15
+ :key="key"
16
+ >{{ t('el.datepicker.weeks.' + week) }}</th>
17
+ </tr>
18
+ <tr
19
+ class="el-date-table__row"
20
+ v-for="(row, key) in rows"
21
+ :class="{ current: isWeekActive(row[1]) }"
22
+ :key="key"
23
+ >
24
+ <td
25
+ v-for="(cell, key) in row"
26
+ :class="getCellClasses(cell)"
27
+ :key="key"
28
+ >
29
+ <div>
30
+ <span>
31
+ {{ cell.text }}
32
+ </span>
33
+ </div>
34
+ </td>
35
+ </tr>
36
+ </tbody>
37
+ </table>
38
+ </template>
39
+
40
+ <script>
41
+ import { getFirstDayOfMonth, getDayCountOfMonth, getWeekNumber, getStartDateOfMonth, prevDate, nextDate, isDate, clearTime as _clearTime, getTimestampInTimezone } from 'bi-eleme/src/utils/date-util'
42
+ import Locale from 'bi-eleme/src/mixins/locale'
43
+ import { arrayFindIndex, arrayFind, coerceTruthyValueToArray } from 'bi-eleme/src/utils/util'
44
+
45
+ const WEEKS = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']
46
+ const getDateTimestamp = function (time, utc = 8) {
47
+ if (typeof time === 'number' || typeof time === 'string') {
48
+ return _clearTime(getTimestampInTimezone(new Date(time), utc)).getTime()
49
+ } else if (time instanceof Date) {
50
+ return _clearTime(getTimestampInTimezone(time, utc)).getTime()
51
+ } else {
52
+ return NaN
53
+ }
54
+ }
55
+
56
+ // remove the first element that satisfies `pred` from arr
57
+ // return a new array if modification occurs
58
+ // return the original array otherwise
59
+ const removeFromArray = function (arr, pred) {
60
+ const idx = typeof pred === 'function' ? arrayFindIndex(arr, pred) : arr.indexOf(pred)
61
+ return idx >= 0 ? [...arr.slice(0, idx), ...arr.slice(idx + 1)] : arr
62
+ }
63
+
64
+ export default {
65
+ mixins: [Locale],
66
+
67
+ props: {
68
+ firstDayOfWeek: {
69
+ default: 7,
70
+ type: Number,
71
+ validator: (val) => val >= 1 && val <= 7
72
+ },
73
+
74
+ utc: {
75
+ default: 8,
76
+ type: Number
77
+ },
78
+
79
+ value: {},
80
+
81
+ defaultValue: {
82
+ validator(val) {
83
+ // either: null, valid Date object, Array of valid Date objects
84
+ return val === null || isDate(val) || (Array.isArray(val) && val.every(isDate))
85
+ }
86
+ },
87
+
88
+ date: {},
89
+
90
+ selectionMode: {
91
+ default: 'day'
92
+ },
93
+
94
+ showWeekNumber: {
95
+ type: Boolean,
96
+ default: false
97
+ },
98
+
99
+ disabledDate: {},
100
+
101
+ cellClassName: {},
102
+
103
+ minDate: {},
104
+
105
+ maxDate: {},
106
+
107
+ rangeState: {
108
+ default() {
109
+ return {
110
+ endDate: null,
111
+ selecting: false
112
+ }
113
+ }
114
+ }
115
+ },
116
+
117
+ computed: {
118
+ offsetDay() {
119
+ const week = this.firstDayOfWeek
120
+ // 周日为界限,左右偏移的天数,3217654 例如周一就是 -1,目的是调整前两行日期的位置
121
+ return week > 3 ? 7 - week : -week
122
+ },
123
+
124
+ WEEKS() {
125
+ const week = this.firstDayOfWeek
126
+ return WEEKS.concat(WEEKS).slice(week, week + 7)
127
+ },
128
+
129
+ year() {
130
+ return this.date.getFullYear()
131
+ },
132
+
133
+ month() {
134
+ return this.date.getMonth()
135
+ },
136
+
137
+ startDate() {
138
+ return getStartDateOfMonth(this.year, this.month)
139
+ },
140
+
141
+ rows() {
142
+ // TODO: refactory rows / getCellClasses
143
+ const date = new Date(this.year, this.month, 1)
144
+ let day = getFirstDayOfMonth(date) // day of first day
145
+ const dateCountOfMonth = getDayCountOfMonth(date.getFullYear(), date.getMonth())
146
+ const dateCountOfLastMonth = getDayCountOfMonth(date.getFullYear(), date.getMonth() === 0 ? 11 : date.getMonth() - 1)
147
+
148
+ day = day === 0 ? 7 : day
149
+
150
+ const offset = this.offsetDay
151
+ const rows = this.tableRows
152
+ let count = 1
153
+
154
+ const startDate = this.startDate
155
+ const disabledDate = this.disabledDate
156
+ const cellClassName = this.cellClassName
157
+ const selectedDate = this.selectionMode === 'dates' ? coerceTruthyValueToArray(this.value) : []
158
+ const now = getDateTimestamp(new Date(), this.utc)
159
+
160
+ for (let i = 0; i < 6; i++) {
161
+ const row = rows[i]
162
+
163
+ if (this.showWeekNumber) {
164
+ if (!row[0]) {
165
+ row[0] = { type: 'week', text: getWeekNumber(nextDate(startDate, i * 7 + 1)) }
166
+ }
167
+ }
168
+
169
+ for (let j = 0; j < 7; j++) {
170
+ let cell = row[this.showWeekNumber ? j + 1 : j]
171
+ if (!cell) {
172
+ cell = { row: i, column: j, type: 'normal', inRange: false, start: false, end: false }
173
+ }
174
+
175
+ cell.type = 'normal'
176
+
177
+ const index = i * 7 + j
178
+ const time = nextDate(startDate, index - offset).getTime()
179
+ cell.inRange = time >= getDateTimestamp(this.minDate) && time <= getDateTimestamp(this.maxDate)
180
+ cell.start = this.minDate && time === getDateTimestamp(this.minDate)
181
+ cell.end = this.maxDate && time === getDateTimestamp(this.maxDate)
182
+ const isToday = time === now
183
+
184
+ if (isToday) {
185
+ cell.type = 'today'
186
+ }
187
+
188
+ if (i >= 0 && i <= 1) {
189
+ const numberOfDaysFromPreviousMonth = day + offset < 0 ? 7 + day + offset : day + offset
190
+
191
+ if (j + i * 7 >= numberOfDaysFromPreviousMonth) {
192
+ cell.text = count++
193
+ } else {
194
+ cell.text = dateCountOfLastMonth - (numberOfDaysFromPreviousMonth - (j % 7)) + 1 + i * 7
195
+ cell.type = 'prev-month'
196
+ }
197
+ } else {
198
+ if (count <= dateCountOfMonth) {
199
+ cell.text = count++
200
+ } else {
201
+ cell.text = count++ - dateCountOfMonth
202
+ cell.type = 'next-month'
203
+ }
204
+ }
205
+
206
+ let cellDate = new Date(time)
207
+ cell.disabled = typeof disabledDate === 'function' && disabledDate(cellDate)
208
+ cell.selected = arrayFind(selectedDate, (date) => date.getTime() === cellDate.getTime())
209
+ cell.customClass = typeof cellClassName === 'function' && cellClassName(cellDate)
210
+ this.$set(row, this.showWeekNumber ? j + 1 : j, cell)
211
+ }
212
+
213
+ if (this.selectionMode === 'week') {
214
+ const start = this.showWeekNumber ? 1 : 0
215
+ const end = this.showWeekNumber ? 7 : 6
216
+ const isWeekActive = this.isWeekActive(row[start + 1])
217
+
218
+ row[start].inRange = isWeekActive
219
+ row[start].start = isWeekActive
220
+ row[end].inRange = isWeekActive
221
+ row[end].end = isWeekActive
222
+ }
223
+ }
224
+
225
+ return rows
226
+ }
227
+ },
228
+
229
+ watch: {
230
+ 'rangeState.endDate'(newVal) {
231
+ this.markRange(this.minDate, newVal)
232
+ },
233
+
234
+ minDate(newVal, oldVal) {
235
+ if (getDateTimestamp(newVal) !== getDateTimestamp(oldVal)) {
236
+ this.markRange(this.minDate, this.maxDate)
237
+ }
238
+ },
239
+
240
+ maxDate(newVal, oldVal) {
241
+ if (getDateTimestamp(newVal) !== getDateTimestamp(oldVal)) {
242
+ this.markRange(this.minDate, this.maxDate)
243
+ }
244
+ }
245
+ },
246
+
247
+ data() {
248
+ return {
249
+ tableRows: [[], [], [], [], [], []],
250
+ lastRow: null,
251
+ lastColumn: null
252
+ }
253
+ },
254
+
255
+ methods: {
256
+ cellMatchesDate(cell, date) {
257
+ const value = new Date(date)
258
+ return this.year === value.getFullYear() && this.month === value.getMonth() && Number(cell.text) === value.getDate()
259
+ },
260
+
261
+ getCellClasses(cell) {
262
+ const selectionMode = this.selectionMode
263
+ const defaultValue = this.defaultValue ? (Array.isArray(this.defaultValue) ? this.defaultValue : [this.defaultValue]) : []
264
+
265
+ let classes = []
266
+ if ((cell.type === 'normal' || cell.type === 'today') && !cell.disabled) {
267
+ classes.push('available')
268
+ if (cell.type === 'today') {
269
+ classes.push('today')
270
+ }
271
+ } else {
272
+ classes.push(cell.type)
273
+ }
274
+
275
+ if (cell.type === 'normal' && defaultValue.some((date) => this.cellMatchesDate(cell, date))) {
276
+ classes.push('default')
277
+ }
278
+
279
+ if (selectionMode === 'day' && (cell.type === 'normal' || cell.type === 'today') && this.cellMatchesDate(cell, this.value)) {
280
+ classes.push('current')
281
+ }
282
+
283
+ if (cell.inRange && (cell.type === 'normal' || cell.type === 'today' || this.selectionMode === 'week')) {
284
+ classes.push('in-range')
285
+
286
+ if (cell.start) {
287
+ classes.push('start-date')
288
+ }
289
+
290
+ if (cell.end) {
291
+ classes.push('end-date')
292
+ }
293
+ }
294
+
295
+ if (cell.disabled) {
296
+ classes.push('disabled')
297
+ }
298
+
299
+ if (cell.selected) {
300
+ classes.push('selected')
301
+ }
302
+
303
+ if (cell.customClass) {
304
+ classes.push(cell.customClass)
305
+ }
306
+
307
+ return classes.join(' ')
308
+ },
309
+
310
+ getDateOfCell(row, column) {
311
+ const offsetFromStart = row * 7 + (column - (this.showWeekNumber ? 1 : 0)) - this.offsetDay
312
+ return nextDate(this.startDate, offsetFromStart)
313
+ },
314
+
315
+ isWeekActive(cell) {
316
+ if (this.selectionMode !== 'week') return false
317
+ const newDate = new Date(this.year, this.month, 1)
318
+ const year = newDate.getFullYear()
319
+ const month = newDate.getMonth()
320
+
321
+ if (cell.type === 'prev-month') {
322
+ newDate.setMonth(month === 0 ? 11 : month - 1)
323
+ newDate.setFullYear(month === 0 ? year - 1 : year)
324
+ }
325
+
326
+ if (cell.type === 'next-month') {
327
+ newDate.setMonth(month === 11 ? 0 : month + 1)
328
+ newDate.setFullYear(month === 11 ? year + 1 : year)
329
+ }
330
+
331
+ newDate.setDate(parseInt(cell.text, 10))
332
+
333
+ if (isDate(this.value)) {
334
+ const dayOffset = ((this.value.getDay() - this.firstDayOfWeek + 7) % 7) - 1
335
+ const weekDate = prevDate(this.value, dayOffset)
336
+ return weekDate.getTime() === newDate.getTime()
337
+ }
338
+ return false
339
+ },
340
+
341
+ markRange(minDate, maxDate) {
342
+ minDate = getDateTimestamp(minDate)
343
+ maxDate = getDateTimestamp(maxDate) || minDate
344
+ ;[minDate, maxDate] = [Math.min(minDate, maxDate), Math.max(minDate, maxDate)]
345
+
346
+ const startDate = this.startDate
347
+ const rows = this.rows
348
+ for (let i = 0, k = rows.length; i < k; i++) {
349
+ const row = rows[i]
350
+ for (let j = 0, l = row.length; j < l; j++) {
351
+ if (this.showWeekNumber && j === 0) continue
352
+
353
+ const cell = row[j]
354
+ const index = i * 7 + j + (this.showWeekNumber ? -1 : 0)
355
+ const time = nextDate(startDate, index - this.offsetDay).getTime()
356
+
357
+ cell.inRange = minDate && time >= minDate && time <= maxDate
358
+ cell.start = minDate && time === minDate
359
+ cell.end = maxDate && time === maxDate
360
+ }
361
+ }
362
+ },
363
+
364
+ handleMouseMove(event) {
365
+ if (!this.rangeState.selecting) return
366
+
367
+ let target = event.target
368
+ if (target.tagName === 'SPAN') {
369
+ target = target.parentNode.parentNode
370
+ }
371
+ if (target.tagName === 'DIV') {
372
+ target = target.parentNode
373
+ }
374
+ if (target.tagName !== 'TD') return
375
+
376
+ const row = target.parentNode.rowIndex - 1
377
+ const column = target.cellIndex
378
+
379
+ // can not select disabled date
380
+ if (this.rows[row][column].disabled) return
381
+
382
+ // only update rangeState when mouse moves to a new cell
383
+ // this avoids frequent Date object creation and improves performance
384
+ if (row !== this.lastRow || column !== this.lastColumn) {
385
+ this.lastRow = row
386
+ this.lastColumn = column
387
+ this.$emit('changerange', {
388
+ minDate: this.minDate,
389
+ maxDate: this.maxDate,
390
+ rangeState: {
391
+ selecting: true,
392
+ endDate: this.getDateOfCell(row, column)
393
+ }
394
+ })
395
+ }
396
+ },
397
+
398
+ handleClick(event) {
399
+ let target = event.target
400
+ if (target.tagName === 'SPAN') {
401
+ target = target.parentNode.parentNode
402
+ }
403
+ if (target.tagName === 'DIV') {
404
+ target = target.parentNode
405
+ }
406
+
407
+ if (target.tagName !== 'TD') return
408
+
409
+ const row = target.parentNode.rowIndex - 1
410
+ const column = this.selectionMode === 'week' ? 1 : target.cellIndex
411
+ const cell = this.rows[row][column]
412
+
413
+ if (cell.disabled || cell.type === 'week') return
414
+
415
+ const newDate = this.getDateOfCell(row, column)
416
+
417
+ if (this.selectionMode === 'range') {
418
+ if (!this.rangeState.selecting) {
419
+ this.$emit('pick', { minDate: newDate, maxDate: null })
420
+ this.rangeState.selecting = true
421
+ } else {
422
+ if (newDate >= this.minDate) {
423
+ this.$emit('pick', { minDate: this.minDate, maxDate: newDate })
424
+ } else {
425
+ this.$emit('pick', { minDate: newDate, maxDate: this.minDate })
426
+ }
427
+ this.rangeState.selecting = false
428
+ }
429
+ } else if (this.selectionMode === 'day') {
430
+ this.$emit('pick', newDate)
431
+ } else if (this.selectionMode === 'week') {
432
+ const weekNumber = getWeekNumber(newDate)
433
+ const value = newDate.getFullYear() + 'w' + weekNumber
434
+ this.$emit('pick', {
435
+ year: newDate.getFullYear(),
436
+ week: weekNumber,
437
+ value: value,
438
+ date: newDate
439
+ })
440
+ } else if (this.selectionMode === 'dates') {
441
+ const value = this.value || []
442
+ const newValue = cell.selected ? removeFromArray(value, (date) => date.getTime() === newDate.getTime()) : [...value, newDate]
443
+ this.$emit('pick', newValue)
444
+ }
445
+ }
446
+ }
447
+ }
448
+ </script>