@wangxinowo/vue-datepicker-next 1.0.3 → 1.0.6

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.
@@ -364,6 +364,76 @@ const RangeCalendar = {
364
364
  return hoverValue;
365
365
  },
366
366
 
367
+ // 年份 hover 处理(类似于日期 hover 逻辑)
368
+ onYearHover(value) {
369
+ let hoverValue = [];
370
+ const { sSelectedValue, firstSelectedValue, type } = this;
371
+
372
+ // 比较年份
373
+ const compareYear = (v1, v2) => {
374
+ return v1.year() - v2.year();
375
+ };
376
+
377
+ if (type === 'start' && sSelectedValue[1]) {
378
+ // 选择开始年份时:如果 hover 值小于结束值,显示范围预览
379
+ hoverValue =
380
+ compareYear(value, sSelectedValue[1]) < 0 ? [value, sSelectedValue[1]] : [value];
381
+ } else if (type === 'end' && sSelectedValue[0]) {
382
+ // 选择结束年份时:如果 hover 值大于开始值,显示范围预览
383
+ hoverValue = compareYear(value, sSelectedValue[0]) > 0 ? [sSelectedValue[0], value] : [];
384
+ } else {
385
+ // both 模式
386
+ if (!firstSelectedValue) {
387
+ if (this.sHoverValue.length) {
388
+ this.setState({ sHoverValue: [] });
389
+ }
390
+ return hoverValue;
391
+ }
392
+ hoverValue =
393
+ compareYear(value, firstSelectedValue) < 0
394
+ ? [value, firstSelectedValue]
395
+ : [firstSelectedValue, value];
396
+ }
397
+ this.fireHoverValueChange(hoverValue);
398
+ return hoverValue;
399
+ },
400
+
401
+ // 月份 hover 处理(类似于日期 hover 逻辑)
402
+ onMonthHover(value) {
403
+ let hoverValue = [];
404
+ const { sSelectedValue, firstSelectedValue, type } = this;
405
+
406
+ // 比较年月
407
+ const compareMonth = (v1, v2) => {
408
+ const yearDiff = v1.year() - v2.year();
409
+ if (yearDiff !== 0) return yearDiff;
410
+ return v1.month() - v2.month();
411
+ };
412
+
413
+ if (type === 'start' && sSelectedValue[1]) {
414
+ // 选择开始月份时:如果 hover 值小于结束值,显示范围预览
415
+ hoverValue =
416
+ compareMonth(value, sSelectedValue[1]) < 0 ? [value, sSelectedValue[1]] : [value];
417
+ } else if (type === 'end' && sSelectedValue[0]) {
418
+ // 选择结束月份时:如果 hover 值大于开始值,显示范围预览
419
+ hoverValue = compareMonth(value, sSelectedValue[0]) > 0 ? [sSelectedValue[0], value] : [];
420
+ } else {
421
+ // both 模式
422
+ if (!firstSelectedValue) {
423
+ if (this.sHoverValue.length) {
424
+ this.setState({ sHoverValue: [] });
425
+ }
426
+ return hoverValue;
427
+ }
428
+ hoverValue =
429
+ compareMonth(value, firstSelectedValue) < 0
430
+ ? [value, firstSelectedValue]
431
+ : [firstSelectedValue, value];
432
+ }
433
+ this.fireHoverValueChange(hoverValue);
434
+ return hoverValue;
435
+ },
436
+
367
437
  onToday() {
368
438
  const startValue = getTodayTime(this.sValue[0]);
369
439
  const endValue = startValue.clone().add(1, 'months');
@@ -921,6 +991,8 @@ const RangeCalendar = {
921
991
  inputSelect: this.onStartInputSelect,
922
992
  valueChange: this.onStartValueChange,
923
993
  panelChange: this.onStartPanelChange,
994
+ yearHover: this.onYearHover,
995
+ monthHover: this.onMonthHover,
924
996
  },
925
997
  });
926
998
  const rightPartProps = mergeProps(baseProps, newProps, {
@@ -946,6 +1018,8 @@ const RangeCalendar = {
946
1018
  inputSelect: this.onEndInputSelect,
947
1019
  valueChange: this.onEndValueChange,
948
1020
  panelChange: this.onEndPanelChange,
1021
+ yearHover: this.onYearHover,
1022
+ monthHover: this.onMonthHover,
949
1023
  },
950
1024
  });
951
1025
  let TodayButtonNode = null;
@@ -37,6 +37,8 @@ const CalendarHeader = {
37
37
  mode: PropTypes.any,
38
38
  // 支持数组形式,用于范围选择器
39
39
  selectedValue: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
40
+ // hover 值,用于范围选择时的预览效果
41
+ hoverValue: PropTypes.array.def([]),
40
42
  monthCellRender: PropTypes.func,
41
43
  monthCellContentRender: PropTypes.func,
42
44
  renderFooter: PropTypes.func,
@@ -172,8 +174,12 @@ const CalendarHeader = {
172
174
  disabledMonth,
173
175
  renderFooter,
174
176
  selectedValue,
177
+ hoverValue,
175
178
  } = props;
176
179
 
180
+ const yearHover = getListeners(this).yearHover || noop;
181
+ const monthHover = getListeners(this).monthHover || noop;
182
+
177
183
  let panel = null;
178
184
  if (mode === 'month') {
179
185
  panel = (
@@ -181,9 +187,11 @@ const CalendarHeader = {
181
187
  locale={locale}
182
188
  value={value}
183
189
  selectedValue={selectedValue}
190
+ hoverValue={hoverValue}
184
191
  rootPrefixCls={prefixCls}
185
192
  onSelect={this.onMonthSelect}
186
193
  onYearPanelShow={() => this.showYearPanel('month')}
194
+ onMonthHover={monthHover}
187
195
  disabledDate={disabledMonth}
188
196
  cellRender={props.monthCellRender}
189
197
  contentRender={props.monthCellContentRender}
@@ -198,10 +206,12 @@ const CalendarHeader = {
198
206
  locale={locale}
199
207
  value={value}
200
208
  selectedValue={selectedValue}
209
+ hoverValue={hoverValue}
201
210
  rootPrefixCls={prefixCls}
202
211
  onSelect={this.onYearSelect}
203
212
  onValueChange={this.onYearValueChange}
204
213
  onDecadePanelShow={this.showDecadePanel}
214
+ onYearHover={yearHover}
205
215
  renderFooter={renderFooter}
206
216
  disabledDate={disabledMonth}
207
217
  />
@@ -17,6 +17,8 @@ const MonthPanel = {
17
17
  defaultValue: PropTypes.any,
18
18
  // 支持单个值或数组(范围选择)
19
19
  selectedValue: PropTypes.oneOfType([PropTypes.any, PropTypes.array]),
20
+ // hover 值,用于范围选择时的预览效果
21
+ hoverValue: PropTypes.array.def([]),
20
22
  cellRender: PropTypes.any,
21
23
  contentRender: PropTypes.any,
22
24
  locale: PropTypes.any,
@@ -69,9 +71,11 @@ const MonthPanel = {
69
71
  disabledDate,
70
72
  renderFooter,
71
73
  selectedValue,
74
+ hoverValue,
72
75
  } = this;
73
76
  const year = sValue.year();
74
77
  const prefixCls = `${rootPrefixCls}-month-panel`;
78
+ const monthHover = getListeners(this).monthHover || noop;
75
79
 
76
80
  const footer = renderFooter && renderFooter('month');
77
81
  return (
@@ -106,9 +110,11 @@ const MonthPanel = {
106
110
  <MonthTable
107
111
  disabledDate={disabledDate}
108
112
  onSelect={this.setAndSelectValue}
113
+ onMonthHover={monthHover}
109
114
  locale={locale}
110
115
  value={sValue}
111
116
  selectedValue={selectedValue}
117
+ hoverValue={hoverValue}
112
118
  cellRender={cellRender}
113
119
  contentRender={contentRender}
114
120
  prefixCls={prefixCls}
@@ -13,20 +13,20 @@ function isRangeMode(selectedValue) {
13
13
  }
14
14
 
15
15
  // 获取范围开始的年月
16
- function getRangeStart(selectedValue) {
17
- if (!isRangeMode(selectedValue) || !selectedValue[0]) return null;
16
+ function getRangeStart(value) {
17
+ if (!isRangeMode(value) || !value[0]) return null;
18
18
  return {
19
- year: selectedValue[0].year(),
20
- month: selectedValue[0].month(),
19
+ year: value[0].year(),
20
+ month: value[0].month(),
21
21
  };
22
22
  }
23
23
 
24
24
  // 获取范围结束的年月
25
- function getRangeEnd(selectedValue) {
26
- if (!isRangeMode(selectedValue) || !selectedValue[1]) return null;
25
+ function getRangeEnd(value) {
26
+ if (!isRangeMode(value) || !value[1]) return null;
27
27
  return {
28
- year: selectedValue[1].year(),
29
- month: selectedValue[1].month(),
28
+ year: value[1].year(),
29
+ month: value[1].month(),
30
30
  };
31
31
  }
32
32
 
@@ -45,6 +45,8 @@ const MonthTable = {
45
45
  value: PropTypes.object,
46
46
  // 支持单个值或数组(范围选择)
47
47
  selectedValue: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
48
+ // hover 值,用于范围选择时的预览效果
49
+ hoverValue: PropTypes.array.def([]),
48
50
  locale: PropTypes.any,
49
51
  contentRender: PropTypes.any,
50
52
  disabledDate: PropTypes.func,
@@ -98,15 +100,23 @@ const MonthTable = {
98
100
  render() {
99
101
  const props = this.$props;
100
102
  const value = this.sValue;
101
- const { selectedValue } = props;
103
+ const { selectedValue, hoverValue } = props;
102
104
  const today = getTodayTime(value);
103
105
  const months = this.months();
104
106
  const { prefixCls, locale, contentRender, cellRender, disabledDate } = props;
107
+ const monthHover = this.$listeners.monthHover || noop;
105
108
 
106
109
  // 判断是范围模式还是单值模式
107
110
  const rangeMode = isRangeMode(selectedValue);
108
- const rangeStart = getRangeStart(selectedValue);
109
- const rangeEnd = getRangeEnd(selectedValue);
111
+
112
+ // 使用 hoverValue 进行范围预览(如果存在的话)
113
+ const rangeValue = hoverValue && hoverValue.length ? hoverValue : selectedValue;
114
+ const rangeStart = getRangeStart(rangeValue);
115
+ const rangeEnd = getRangeEnd(rangeValue);
116
+
117
+ // 选中值(用于显示实际选中的起始和结束)
118
+ const selectedStart = getRangeStart(selectedValue);
119
+ const selectedEnd = getRangeEnd(selectedValue);
110
120
 
111
121
  // 单值模式:只有当 selectedValue 存在且与当前面板年份相同时,才显示选中状态
112
122
  const hasSelectedValue = !rangeMode && selectedValue && selectedValue.year() === value.year();
@@ -125,7 +135,18 @@ const MonthTable = {
125
135
  disabled = disabledDate(testValue);
126
136
  }
127
137
 
128
- // 判断当前月份是否在范围内
138
+ // 判断当前月份是否在选中范围内(使用实际选中值)
139
+ let isSelectedStart = false;
140
+ let isSelectedEnd = false;
141
+
142
+ if (rangeMode && selectedStart) {
143
+ isSelectedStart = selectedStart.year === currentYear && selectedStart.month === monthData.value;
144
+ }
145
+ if (rangeMode && selectedEnd) {
146
+ isSelectedEnd = selectedEnd.year === currentYear && selectedEnd.month === monthData.value;
147
+ }
148
+
149
+ // 判断当前月份是否在范围内(使用 rangeValue,可能是 hover 值)
129
150
  let isRangeStart = false;
130
151
  let isRangeEnd = false;
131
152
  let isInRange = false;
@@ -156,18 +177,34 @@ const MonthTable = {
156
177
  isInRange = compareWithStart > 0 && compareWithEnd < 0;
157
178
  }
158
179
 
180
+ // 判断是否为 hover 预览状态(有 hoverValue 时)
181
+ const isHoverRange = hoverValue && hoverValue.length > 0;
182
+
159
183
  const classNameMap = {
160
184
  [`${prefixCls}-cell`]: 1,
161
185
  [`${prefixCls}-cell-disabled`]: disabled,
162
186
  // 单值模式的选中状态
163
187
  [`${prefixCls}-selected-cell`]: monthData.value === selectedMonth,
164
- // 范围模式的选中状态
165
- [`${prefixCls}-selected-start-cell`]: isRangeStart,
166
- [`${prefixCls}-selected-end-cell`]: isRangeEnd,
188
+ // 范围模式的选中状态(实际选中)
189
+ [`${prefixCls}-selected-start-cell`]: isSelectedStart,
190
+ [`${prefixCls}-selected-end-cell`]: isSelectedEnd,
191
+ // 范围背景(包括 hover 预览)
167
192
  [`${rootPrefixCls}-in-range-cell`]: isInRange || isRangeStart || isRangeEnd,
193
+ // hover 预览状态(仅当有 hoverValue 时才添加 hover 样式类)
194
+ [`${rootPrefixCls}-in-hover-range-cell`]: isHoverRange && (isInRange || isRangeStart || isRangeEnd),
168
195
  [`${prefixCls}-current-cell`]:
169
196
  today.year() === value.year() && monthData.value === today.month(),
170
197
  };
198
+
199
+ // hover 处理函数
200
+ const hoverHandler = () => {
201
+ if (disabled) {
202
+ return;
203
+ }
204
+ const hoverTime = value.clone().month(monthData.value);
205
+ monthHover(hoverTime);
206
+ };
207
+
171
208
  let cellEl;
172
209
  if (cellRender) {
173
210
  const currentValue = value.clone();
@@ -189,6 +226,7 @@ const MonthTable = {
189
226
  role="gridcell"
190
227
  key={monthData.value}
191
228
  onClick={disabled ? noop : () => this.chooseMonth(monthData.value)}
229
+ onMouseenter={hoverHandler}
192
230
  title={monthData.title}
193
231
  class={classNameMap}
194
232
  >
@@ -70,6 +70,8 @@ const CalendarPart = {
70
70
  panelChange = noop,
71
71
  select = noop,
72
72
  dayHover = noop,
73
+ yearHover = noop,
74
+ monthHover = noop,
73
75
  } = getListeners(this);
74
76
  const shouldShowTimePicker = showTimePicker && timePicker;
75
77
  const disabledTimeConfig =
@@ -130,12 +132,16 @@ const CalendarPart = {
130
132
  disabledMonth,
131
133
  // 传递完整的 selectedValue 数组,让 YearPanel/MonthPanel 支持范围选中效果
132
134
  selectedValue: selectedValue,
135
+ // 传递 hoverValue,用于范围预览
136
+ hoverValue: hoverValue,
133
137
  // 保留 direction 信息,用于判断是左面板还是右面板
134
138
  direction,
135
139
  },
136
140
  on: {
137
141
  valueChange,
138
142
  panelChange,
143
+ yearHover,
144
+ monthHover,
139
145
  },
140
146
  };
141
147
  const tableProps = {
@@ -28,15 +28,15 @@ function isRangeMode(selectedValue) {
28
28
  }
29
29
 
30
30
  // 获取范围开始年份
31
- function getRangeStartYear(selectedValue) {
32
- if (!isRangeMode(selectedValue)) return null;
33
- return selectedValue[0] ? selectedValue[0].year() : null;
31
+ function getRangeStartYear(value) {
32
+ if (!isRangeMode(value)) return null;
33
+ return value[0] ? value[0].year() : null;
34
34
  }
35
35
 
36
36
  // 获取范围结束年份
37
- function getRangeEndYear(selectedValue) {
38
- if (!isRangeMode(selectedValue)) return null;
39
- return selectedValue[1] ? selectedValue[1].year() : null;
37
+ function getRangeEndYear(value) {
38
+ if (!isRangeMode(value)) return null;
39
+ return value[1] ? value[1].year() : null;
40
40
  }
41
41
 
42
42
  export default {
@@ -47,6 +47,8 @@ export default {
47
47
  defaultValue: PropTypes.object,
48
48
  // 支持单个值或数组(范围选择)
49
49
  selectedValue: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
50
+ // hover 值,用于范围选择时的预览效果
51
+ hoverValue: PropTypes.array.def([]),
50
52
  locale: PropTypes.object,
51
53
  renderFooter: PropTypes.func,
52
54
  disabledDate: PropTypes.func,
@@ -90,15 +92,23 @@ export default {
90
92
 
91
93
  render() {
92
94
  const { sValue: value, locale, renderFooter, $props } = this;
93
- const { selectedValue } = $props;
95
+ const { selectedValue, hoverValue } = $props;
94
96
  const decadePanelShow = getListeners(this).decadePanelShow || noop;
97
+ const yearHover = getListeners(this).yearHover || noop;
95
98
  const years = this.years();
96
99
  const currentYear = value.year();
97
100
 
98
101
  // 判断是范围模式还是单值模式
99
102
  const rangeMode = isRangeMode(selectedValue);
100
- const rangeStartYear = getRangeStartYear(selectedValue);
101
- const rangeEndYear = getRangeEndYear(selectedValue);
103
+
104
+ // 使用 hoverValue 进行范围预览(如果存在的话)
105
+ const rangeValue = hoverValue && hoverValue.length ? hoverValue : selectedValue;
106
+ const rangeStartYear = getRangeStartYear(rangeValue);
107
+ const rangeEndYear = getRangeEndYear(rangeValue);
108
+
109
+ // 选中值(用于显示实际选中的起始和结束)
110
+ const selectedStartYear = getRangeStartYear(selectedValue);
111
+ const selectedEndYear = getRangeEndYear(selectedValue);
102
112
 
103
113
  // 单值模式:只有当 selectedValue 存在时才显示选中状态
104
114
  const selectedYear = !rangeMode && selectedValue ? selectedValue.year() : null;
@@ -120,7 +130,11 @@ export default {
120
130
  // 判断年份是否在当前十年范围内(不是上一十年或下一十年的预览)
121
131
  const isInCurrentDecade = yearData.year >= startYear && yearData.year <= endYear;
122
132
 
123
- // 判断是否为范围起始/结束/中间,只在当前十年范围内应用
133
+ // 判断是否为选中的起始/结束(使用实际选中值,而非 hover 值)
134
+ const isSelectedStart = rangeMode && selectedStartYear !== null && yearData.year === selectedStartYear && isInCurrentDecade;
135
+ const isSelectedEnd = rangeMode && selectedEndYear !== null && yearData.year === selectedEndYear && isInCurrentDecade;
136
+
137
+ // 判断是否为范围起始/结束/中间(使用 rangeValue,可能是 hover 值)
124
138
  const isRangeStart = rangeMode && rangeStartYear !== null && yearData.year === rangeStartYear && isInCurrentDecade;
125
139
  const isRangeEnd = rangeMode && rangeEndYear !== null && yearData.year === rangeEndYear && isInCurrentDecade;
126
140
  const isInRange = rangeMode &&
@@ -130,15 +144,21 @@ export default {
130
144
  yearData.year < rangeEndYear &&
131
145
  isInCurrentDecade;
132
146
 
147
+ // 判断是否为 hover 预览状态(有 hoverValue 时)
148
+ const isHoverRange = hoverValue && hoverValue.length > 0;
149
+
133
150
  const classNameMap = {
134
151
  [`${prefixCls}-cell`]: 1,
135
152
  [`${prefixCls}-cell-disabled`]: disabled,
136
153
  // 单值模式的选中状态
137
154
  [`${prefixCls}-selected-cell`]: selectedYear !== null && yearData.year === selectedYear,
138
- // 范围模式的选中状态
139
- [`${prefixCls}-selected-start-cell`]: isRangeStart,
140
- [`${prefixCls}-selected-end-cell`]: isRangeEnd,
155
+ // 范围模式的选中状态(实际选中)
156
+ [`${prefixCls}-selected-start-cell`]: isSelectedStart,
157
+ [`${prefixCls}-selected-end-cell`]: isSelectedEnd,
158
+ // 范围背景(包括 hover 预览)
141
159
  [`${this.rootPrefixCls}-in-range-cell`]: isInRange || isRangeStart || isRangeEnd,
160
+ // hover 预览状态(仅当有 hoverValue 时才添加 hover 样式类)
161
+ [`${this.rootPrefixCls}-in-hover-range-cell`]: isHoverRange && (isInRange || isRangeStart || isRangeEnd),
142
162
  [`${prefixCls}-last-decade-cell`]: yearData.year < startYear,
143
163
  [`${prefixCls}-next-decade-cell`]: yearData.year > endYear,
144
164
  };
@@ -150,12 +170,23 @@ export default {
150
170
  } else {
151
171
  clickHandler = chooseYear.bind(this, yearData.year);
152
172
  }
173
+
174
+ // hover 处理函数
175
+ const hoverHandler = () => {
176
+ if (disabled || yearData.year < startYear || yearData.year > endYear) {
177
+ return;
178
+ }
179
+ const hoverTime = value.clone().year(yearData.year);
180
+ yearHover(hoverTime);
181
+ };
182
+
153
183
  return (
154
184
  <td
155
185
  role="gridcell"
156
186
  title={yearData.title}
157
187
  key={yearData.content}
158
188
  onClick={disabled ? noop : clickHandler}
189
+ onMouseenter={hoverHandler}
159
190
  class={classNameMap}
160
191
  >
161
192
  <a class={`${prefixCls}-year`}>{yearData.content}</a>
package/src/index.js CHANGED
@@ -4,6 +4,7 @@
4
4
  */
5
5
 
6
6
  import DatePicker from './components/date-picker';
7
+ import antDirective from './components/_util/antDirective';
7
8
  import './components/style/index.less';
8
9
  import './components/date-picker/style/index.less';
9
10
 
@@ -16,6 +17,9 @@ export { default as dayjsGenerateConfig } from './components/date-picker/generat
16
17
 
17
18
  // 安装函数
18
19
  const install = function(Vue) {
20
+ // 注册所有指令 (ant-ref, ant-input, ant-decorator, ant-portal)
21
+ Vue.use(antDirective);
22
+
19
23
  Vue.component(DatePicker.name, DatePicker);
20
24
  Vue.component('a-date-picker', DatePicker);
21
25
  Vue.component('a-range-picker', RangePicker);