Skip to content

Commit f487d11

Browse files
committed
feat: add disabledCalendarChanger (#628)
1 parent d09739f commit f487d11

File tree

6 files changed

+144
-15
lines changed

6 files changed

+144
-15
lines changed

src/calendar/calendar-panel.js

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ export default {
3333
defaultPanel: {
3434
type: String,
3535
},
36+
disabledCalendarChanger: {
37+
type: Function,
38+
default: () => false,
39+
},
3640
disabledDate: {
3741
type: Function,
3842
default: () => false,
@@ -185,19 +189,33 @@ export default {
185189
return classes.concat(this.getClasses(cellDate, this.innerValue, classes.join(' ')));
186190
},
187191
getMonthClasses(month) {
192+
const classes = [];
188193
if (this.type !== 'month') {
189-
return this.calendarMonth === month ? 'active' : '';
194+
if (this.calendarMonth === month) {
195+
classes.push('active');
196+
}
197+
const cellDate = this.getMonthCellDate(month);
198+
if (this.disabledCalendarChanger(cellDate, 'month')) {
199+
classes.push('disabled');
200+
}
201+
return classes;
190202
}
191-
const classes = [];
192203
const cellDate = this.getMonthCellDate(month);
193204
classes.push(this.getStateClass(cellDate));
194205
return classes.concat(this.getClasses(cellDate, this.innerValue, classes.join(' ')));
195206
},
196207
getYearClasses(year) {
208+
const classes = [];
197209
if (this.type !== 'year') {
198-
return this.calendarYear === year ? 'active' : '';
210+
if (this.calendarYear === year) {
211+
classes.push('active');
212+
}
213+
const cellDate = this.getYearCellDate(year);
214+
if (this.disabledCalendarChanger(cellDate, 'year')) {
215+
classes.push('disabled');
216+
}
217+
return classes;
199218
}
200-
const classes = [];
201219
const cellDate = this.getYearCellDate(year);
202220
classes.push(this.getStateClass(cellDate));
203221
return classes.concat(this.getClasses(cellDate, this.innerValue, classes.join(' ')));
@@ -227,6 +245,7 @@ export default {
227245
if (panel === 'year') {
228246
return (
229247
<TableYear
248+
disabledCalendarChanger={this.disabledCalendarChanger}
230249
calendar={innerCalendar}
231250
getCellClasses={this.getYearClasses}
232251
getYearPanel={this.getYearPanel}
@@ -238,6 +257,7 @@ export default {
238257
if (panel === 'month') {
239258
return (
240259
<TableMonth
260+
disabledCalendarChanger={this.disabledCalendarChanger}
241261
calendar={innerCalendar}
242262
getCellClasses={this.getMonthClasses}
243263
onSelect={this.handleSelectMonth}
@@ -248,6 +268,7 @@ export default {
248268
}
249269
return (
250270
<TableDate
271+
disabledCalendarChanger={this.disabledCalendarChanger}
251272
class={{ [`${this.prefixClass}-calendar-week-mode`]: this.type === 'week' }}
252273
calendar={innerCalendar}
253274
getCellClasses={this.getDateClasses}

src/calendar/icon-button.vue

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
<template>
22
<button
33
type="button"
4-
:class="`${prefixClass}-btn ${prefixClass}-btn-text ${prefixClass}-btn-icon-${type}`"
4+
:disabled="disabled"
5+
:class="[
6+
`${prefixClass}-btn ${prefixClass}-btn-text ${prefixClass}-btn-icon-${type}`,
7+
{
8+
disabled: disabled,
9+
},
10+
]"
511
v-on="$listeners"
612
>
713
<i :class="`${prefixClass}-icon-${type}`"></i>
@@ -12,6 +18,7 @@
1218
export default {
1319
props: {
1420
type: String,
21+
disabled: Boolean,
1522
},
1623
inject: {
1724
prefixClass: {

src/calendar/table-date.vue

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,26 @@
11
<template>
22
<div :class="`${prefixClass}-calendar ${prefixClass}-calendar-panel-date`">
33
<div :class="`${prefixClass}-calendar-header`">
4-
<icon-button type="double-left" @click="handleIconDoubleLeftClick"></icon-button>
5-
<icon-button type="left" @click="handleIconLeftClick"></icon-button>
6-
<icon-button type="double-right" @click="handleIconDoubleRightClick"></icon-button>
7-
<icon-button type="right" @click="handleIconRightClick"></icon-button>
4+
<icon-button
5+
type="double-left"
6+
:disabled="isDisabledArrows('last-year')"
7+
@click="handleIconDoubleLeftClick"
8+
></icon-button>
9+
<icon-button
10+
type="left"
11+
:disabled="isDisabledArrows('last-month')"
12+
@click="handleIconLeftClick"
13+
></icon-button>
14+
<icon-button
15+
type="double-right"
16+
:disabled="isDisabledArrows('next-year')"
17+
@click="handleIconDoubleRightClick"
18+
></icon-button>
19+
<icon-button
20+
type="right"
21+
:disabled="isDisabledArrows('next-month')"
22+
@click="handleIconRightClick"
23+
></icon-button>
824
<span :class="`${prefixClass}-calendar-header-label`">
925
<button
1026
v-for="item in yearMonth"
@@ -87,6 +103,10 @@ export default {
87103
},
88104
},
89105
props: {
106+
disabledCalendarChanger: {
107+
type: Function,
108+
default: () => false,
109+
},
90110
calendar: {
91111
type: Date,
92112
default: () => new Date(),
@@ -141,6 +161,28 @@ export default {
141161
},
142162
},
143163
methods: {
164+
isDisabledArrows(type) {
165+
const date = new Date(this.calendar);
166+
switch (type) {
167+
case 'last-year':
168+
date.setFullYear(date.getFullYear() - 1, date.getMonth() + 1, 0);
169+
date.setHours(23, 59, 59, 999);
170+
break;
171+
case 'next-year':
172+
date.setFullYear(date.getFullYear() + 1);
173+
break;
174+
case 'last-month':
175+
date.setMonth(date.getMonth(), 0);
176+
date.setHours(23, 59, 59, 999);
177+
break;
178+
case 'next-month':
179+
date.setMonth(date.getMonth() + 1);
180+
break;
181+
default:
182+
break;
183+
}
184+
return this.disabledCalendarChanger(date, type);
185+
},
144186
handleIconLeftClick() {
145187
this.$emit(
146188
'changecalendar',

src/calendar/table-month.vue

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
<template>
22
<div :class="`${prefixClass}-calendar ${prefixClass}-calendar-panel-month`">
33
<div :class="`${prefixClass}-calendar-header`">
4-
<icon-button type="double-left" @click="handleIconDoubleLeftClick"></icon-button>
5-
<icon-button type="double-right" @click="handleIconDoubleRightClick"></icon-button>
4+
<icon-button
5+
type="double-left"
6+
:disabled="isDisabledArrows('last-year')"
7+
@click="handleIconDoubleLeftClick"
8+
></icon-button>
9+
<icon-button
10+
type="double-right"
11+
:disabled="isDisabledArrows('next-year')"
12+
@click="handleIconDoubleRightClick"
13+
></icon-button>
614
<span :class="`${prefixClass}-calendar-header-label`">
715
<button
816
type="button"
@@ -49,6 +57,10 @@ export default {
4957
},
5058
},
5159
props: {
60+
disabledCalendarChanger: {
61+
type: Function,
62+
default: () => false,
63+
},
5264
calendar: {
5365
type: Date,
5466
default: () => new Date(),
@@ -72,6 +84,21 @@ export default {
7284
},
7385
},
7486
methods: {
87+
isDisabledArrows(type) {
88+
const date = new Date(this.calendar);
89+
switch (type) {
90+
case 'last-year':
91+
date.setFullYear(date.getFullYear() - 1, 11, 31);
92+
date.setHours(23, 59, 59, 999);
93+
break;
94+
case 'next-year':
95+
date.setFullYear(date.getFullYear() + 1, 0, 1);
96+
break;
97+
default:
98+
break;
99+
}
100+
return this.disabledCalendarChanger(date, type);
101+
},
75102
handleIconDoubleLeftClick() {
76103
this.$emit(
77104
'changecalendar',
@@ -95,7 +122,7 @@ export default {
95122
target = target.parentNode;
96123
}
97124
const month = target.getAttribute('data-month');
98-
if (month) {
125+
if (month && !target.classList.contains('disabled')) {
99126
this.$emit('select', parseInt(month, 10));
100127
}
101128
},

src/calendar/table-year.vue

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
<template>
22
<div :class="`${prefixClass}-calendar ${prefixClass}-calendar-panel-year`">
33
<div :class="`${prefixClass}-calendar-header`">
4-
<icon-button type="double-left" @click="handleIconDoubleLeftClick"></icon-button>
5-
<icon-button type="double-right" @click="handleIconDoubleRightClick"></icon-button>
4+
<icon-button
5+
type="double-left"
6+
:disabled="isDisabledArrows('last-decade')"
7+
@click="handleIconDoubleLeftClick"
8+
></icon-button>
9+
<icon-button
10+
type="double-right"
11+
:disabled="isDisabledArrows('next-decade')"
12+
@click="handleIconDoubleRightClick"
13+
></icon-button>
614
<span :class="`${prefixClass}-calendar-header-label`">
715
<span>{{ firstYear }}</span>
816
<span :class="`${prefixClass}-calendar-decade-separator`"></span>
@@ -41,6 +49,10 @@ export default {
4149
},
4250
},
4351
props: {
52+
disabledCalendarChanger: {
53+
type: Function,
54+
default: () => false,
55+
},
4456
calendar: {
4557
type: Date,
4658
default: () => new Date(),
@@ -70,6 +82,21 @@ export default {
7082
},
7183
},
7284
methods: {
85+
isDisabledArrows(type) {
86+
const date = new Date(this.calendar);
87+
switch (type) {
88+
case 'last-decade':
89+
date.setFullYear(this.firstYear - 1, 11, 31);
90+
date.setHours(23, 59, 59, 999);
91+
break;
92+
case 'next-decade':
93+
date.setFullYear(this.lastYear + 1, 0, 1);
94+
break;
95+
default:
96+
break;
97+
}
98+
return this.disabledCalendarChanger(date, type);
99+
},
73100
getYears(calendar) {
74101
const firstYear = Math.floor(calendar.getFullYear() / 10) * 10;
75102
const years = [];
@@ -98,7 +125,7 @@ export default {
98125
target = target.parentNode;
99126
}
100127
const year = target.getAttribute('data-year');
101-
if (year) {
128+
if (year && !target.classList.contains('disabled')) {
102129
this.$emit('select', parseInt(year, 10));
103130
}
104131
},

src/style/btn.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@
1818
border-color: $primary-color;
1919
color: $primary-color;
2020
}
21+
&:disabled,
22+
&.disabled {
23+
color: $disabled-color;
24+
cursor: not-allowed;
25+
}
2126
}
2227

2328
.#{$namespace}-btn-text {

0 commit comments

Comments
 (0)