diff --git a/example/app.js b/example/app.js index 0951a2d..d866b7e 100644 --- a/example/app.js +++ b/example/app.js @@ -14,6 +14,7 @@ import HideSeconds from './demo/HideSeconds.vue'; import MinuteStep from './demo/MinuteStep.vue'; import FixedTimeList from './demo/FixedTimeList.vue'; import Disabled from './demo/Disabled.vue'; +import MinMax from './demo/MinMax.vue'; import docEn from './en.md'; import docZhCN from './zh-cn.md'; @@ -74,6 +75,11 @@ const components = [ component: ControlOpen, code: fs.readFileSync(`${__dirname}/demo/ControlOpen.vue`, 'utf8'), }, + { + id: 'MinMax', + component: MinMax, + code: fs.readFileSync(`${__dirname}/demo/MinMax.vue`, 'utf8'), + }, ]; function transformMd(text) { diff --git a/example/demo/MinMax.vue b/example/demo/MinMax.vue new file mode 100644 index 0000000..3dcab08 --- /dev/null +++ b/example/demo/MinMax.vue @@ -0,0 +1,46 @@ + + + diff --git a/example/en.md b/example/en.md index 1f64814..7014105 100644 --- a/example/en.md +++ b/example/en.md @@ -60,6 +60,13 @@ You can use the prop `open` to control the visible of popup. This example shows how to close the popup when the seconds is selected. + +### Min Max + +You can use the prop `min` & `max` to specify range. + +This example shows how to use min and max date to restrict specify dates. + ### Hide seconds selection & display AMPM selection diff --git a/example/zh-cn.md b/example/zh-cn.md index 6822ef5..f8d32f7 100644 --- a/example/zh-cn.md +++ b/example/zh-cn.md @@ -60,6 +60,12 @@ 下面的例子说明怎么关闭弹窗当选择秒的时候 + + +### Min Max + + + ### 隐藏秒和显示 am/pm diff --git a/src/calendar/calendar-panel.js b/src/calendar/calendar-panel.js index f9dec48..3a965a4 100644 --- a/src/calendar/calendar-panel.js +++ b/src/calendar/calendar-panel.js @@ -62,14 +62,27 @@ export default { type: Boolean, default: false, }, + min: { + type: Date, + }, + max: { + type: Date, + }, }, data() { const panels = ['date', 'month', 'year']; const index = Math.max(panels.indexOf(this.type), panels.indexOf(this.defaultPanel)); const panel = index !== -1 ? panels[index] : 'date'; + const minDate = (this.min && new Date(this.min)) || undefined; + const maxDate = (this.max && new Date(this.max)) || undefined; + if (minDate) minDate.setHours(0, 0, 0, 0); + if (maxDate) maxDate.setHours(23, 59, 59, 999); + return { panel, innerCalendar: new Date(), + minDate, + maxDate, }; }, computed: { @@ -186,7 +199,10 @@ export default { }, getMonthClasses(month) { if (this.type !== 'month') { - return this.calendarMonth === month ? 'active' : ''; + const classes = [this.calendarMonth === month ? 'active' : '']; + if (this.getIsMonthDisabled(month)) classes.push('disabled'); + + return classes; } const classes = []; const cellDate = this.getMonthCellDate(month); @@ -195,7 +211,10 @@ export default { }, getYearClasses(year) { if (this.type !== 'year') { - return this.calendarYear === year ? 'active' : ''; + const classes = [this.calendarYear === year ? 'active' : '']; + if (this.getIsYearDisabled(year)) classes.push('disabled'); + + return classes; } const classes = []; const cellDate = this.getYearCellDate(year); @@ -203,7 +222,7 @@ export default { return classes.concat(this.getClasses(cellDate, this.innerValue, classes.join(' '))); }, getStateClass(cellDate) { - if (this.isDisabled(cellDate)) { + if (this.getIsDateDisabled(cellDate) || this.isDisabled(cellDate)) { return 'disabled'; } if (this.innerValue.some(v => v.getTime() === cellDate.getTime())) { @@ -221,9 +240,34 @@ export default { }); return active ? `${this.prefixClass}-active-week` : ''; }, + getIsYearDisabled(year) { + return ( + (!!this.minDate && year < this.minDate.getFullYear()) || + (!!this.maxDate && year > this.maxDate.getFullYear()) + ); + }, + getIsMonthDisabled(month) { + const cellDate = this.getMonthCellDate(month); + + return ( + (!!this.minDate && + (this.minDate.getFullYear() > cellDate.getFullYear() || + (this.minDate.getFullYear() === cellDate.getFullYear() && + month < this.minDate.getMonth()))) || + (!!this.maxDate && + (this.maxDate.getFullYear() < cellDate.getFullYear() || + (this.maxDate.getFullYear() === cellDate.getFullYear() && + month > this.maxDate.getMonth()))) + ); + }, + getIsDateDisabled(cellDate) { + return ( + (!!this.minDate && this.minDate > cellDate) || (!!this.maxDate && this.maxDate < cellDate) + ); + }, }, render() { - const { panel, innerCalendar } = this; + const { panel, innerCalendar, minDate, maxDate } = this; if (panel === 'year') { return ( ); } @@ -243,6 +290,9 @@ export default { onSelect={this.handleSelectMonth} onChangepanel={this.handelPanelChange} onChangecalendar={this.handleCalendarChange} + getIsMonthDisabled={this.getIsMonthDisabled} + min={minDate && minDate.getFullYear()} + max={maxDate && maxDate.getFullYear()} /> ); } @@ -259,6 +309,9 @@ export default { onSelect={this.handleSelectDate} onChangepanel={this.handelPanelChange} onChangecalendar={this.handleCalendarChange} + getIsDateDisabled={this.getIsDateDisabled} + min={minDate} + max={maxDate} /> ); }, diff --git a/src/calendar/icon-button.vue b/src/calendar/icon-button.vue index 552bebf..7dd83ed 100644 --- a/src/calendar/icon-button.vue +++ b/src/calendar/icon-button.vue @@ -1,7 +1,13 @@