diff --git a/src/calendar/README.md b/src/calendar/README.md index 3df673156..7756a9b31 100644 --- a/src/calendar/README.md +++ b/src/calendar/README.md @@ -200,6 +200,14 @@ When selecting a date range, you can use the `max-range` prop to specify the max ``` +### Custom First Day Of Week + +Use `first-day-of-week` to custom the start day of week + +```html + +``` + ### Tiled display Set `poppable` to `false`, the calendar will be displayed directly on the page instead of appearing as a popup @@ -235,6 +243,7 @@ Set `poppable` to `false`, the calendar will be displayed directly on the page i | show-confirm | Whether to show confirm button | _boolean_ | `true` | | confirm-text | Confirm button text | _string_ | `Confirm` | | confirm-disabled-text | Confirm button text when disabled | _string_ | `Confirm` | +| first-day-of-week | Set the start day of week | _0-6_ | `0` | ### Poppable Props diff --git a/src/calendar/README.zh-CN.md b/src/calendar/README.zh-CN.md index 6b7e6c2f9..f4aa46748 100644 --- a/src/calendar/README.zh-CN.md +++ b/src/calendar/README.zh-CN.md @@ -202,6 +202,14 @@ export default { ``` +### 自定义周起始日 + +通过`first-day-of-week`属性设置一周从哪天开始 + +```html + +``` + ### 平铺展示 将`poppable`设置为`false`,日历会直接展示在页面内,而不是以弹层的形式出现 @@ -237,6 +245,7 @@ export default { | show-confirm | 是否展示确认按钮 | _boolean_ | `true` | | confirm-text | 确认按钮的文字 | _string_ | `确定` | | confirm-disabled-text | 确认按钮处于禁用状态时的文字 | _string_ | `确定` | +| first-day-of-week | 设置周起始日 | _0-6_ | `0` | ### Poppable Props diff --git a/src/calendar/components/Header.js b/src/calendar/components/Header.js index f0ac16a95..814583b29 100644 --- a/src/calendar/components/Header.js +++ b/src/calendar/components/Header.js @@ -9,6 +9,7 @@ export default createComponent({ subtitle: String, showTitle: Boolean, showSubtitle: Boolean, + firstDayOfWeek: Number, }, methods: { @@ -28,9 +29,16 @@ export default createComponent({ genWeekDays() { const weekdays = t('weekdays'); + const { firstDayOfWeek } = this; + + const renderWeekDays = [ + ...weekdays.slice(firstDayOfWeek, 7), + ...weekdays.slice(0, firstDayOfWeek), + ]; + return (
- {weekdays.map((item) => ( + {renderWeekDays.map((item) => ( {item} ))}
diff --git a/src/calendar/components/Month.js b/src/calendar/components/Month.js index 50280034f..ef58563c8 100644 --- a/src/calendar/components/Month.js +++ b/src/calendar/components/Month.js @@ -27,6 +27,7 @@ export default createComponent({ allowSameDay: Boolean, showSubtitle: Boolean, showMonthTitle: Boolean, + firstDayOfWeek: Number, }, data() { @@ -41,7 +42,15 @@ export default createComponent({ }, offset() { - return this.date.getDay(); + const { firstDayOfWeek } = this; + + const realDay = this.date.getDay(); + + if (!firstDayOfWeek) { + return realDay; + } + + return (realDay + 7 - this.firstDayOfWeek) % 7; }, totalDay() { diff --git a/src/calendar/demo/index.vue b/src/calendar/demo/index.vue index 19f4ab4d0..5b2c7a767 100644 --- a/src/calendar/demo/index.vue +++ b/src/calendar/demo/index.vue @@ -81,6 +81,12 @@ :value="formatRange(date.maxRange)" @click="show('range', 'maxRange')" /> + + @@ -108,6 +114,7 @@ :show-confirm="showConfirm" :confirm-text="confirmText" :confirm-disabled-text="confirmDisabledText" + :first-day-of-week="firstDayOfWeek" @confirm="onConfirm" /> @@ -139,6 +146,7 @@ export default { customPosition: '自定义弹出位置', customCalendar: '自定义日历', confirmDisabledText: '请选择结束时间', + firstDayOfWeek: '自定义周起始日', tiledDisplay: '平铺展示', }, 'en-US': { @@ -161,6 +169,7 @@ export default { customDayText: 'Custom Day Text', customPosition: 'Custom Position', customCalendar: 'Custom Calendar', + firstDayOfWeek: 'Custom First Day Of Week', confirmDisabledText: 'Select End Time', tiledDisplay: 'Tiled display', }, @@ -195,6 +204,7 @@ export default { tiledMaxDate: new Date(2012, 2, 20), confirmText: undefined, confirmDisabledText: undefined, + firstDayOfWeek: 0, }; }, @@ -210,6 +220,7 @@ export default { this.showConfirm = true; this.confirmText = undefined; this.confirmDisabledText = undefined; + this.firstDayOfWeek = 0; }, show(type, id) { @@ -246,6 +257,9 @@ export default { case 'maxRange': this.maxRange = 3; break; + case 'firstDayOfWeek': + this.firstDayOfWeek = 1; + break; } }, diff --git a/src/calendar/index.js b/src/calendar/index.js index e05b3a13a..591e64a2c 100644 --- a/src/calendar/index.js +++ b/src/calendar/index.js @@ -35,6 +35,13 @@ export default createComponent({ allowSameDay: Boolean, closeOnPopstate: Boolean, confirmDisabledText: String, + firstDayOfWeek: { + type: [Number, String], + default: 0, + validator: (val) => { + return val >= 0 && val <= 6; + }, + }, type: { type: String, default: 'single', @@ -137,6 +144,10 @@ export default createComponent({ return !currentDate; }, + + dayOffset() { + return this.firstDayOfWeek ? this.firstDayOfWeek % 7 : 0; + }, }, watch: { @@ -379,6 +390,7 @@ export default createComponent({ showSubtitle={this.showSubtitle} allowSameDay={this.allowSameDay} showMonthTitle={showMonthTitle} + firstDayOfWeek={this.dayOffset} onClick={this.onClickDay} /> ); @@ -432,6 +444,7 @@ export default createComponent({ scopedSlots={{ title: () => this.slots('title'), }} + firstDayOfWeek={this.dayOffset} />
{this.months.map(this.genMonth)} diff --git a/src/calendar/test/__snapshots__/demo.spec.js.snap b/src/calendar/test/__snapshots__/demo.spec.js.snap index 33cd782f9..2e5ac8a76 100644 --- a/src/calendar/test/__snapshots__/demo.spec.js.snap +++ b/src/calendar/test/__snapshots__/demo.spec.js.snap @@ -51,6 +51,10 @@ exports[`renders demo correctly 1`] = `
日期区间最大范围
+
+
自定义周起始日
+ +
diff --git a/src/calendar/test/prop.spec.js b/src/calendar/test/prop.spec.js index 726e7dfef..0ec7da118 100644 --- a/src/calendar/test/prop.spec.js +++ b/src/calendar/test/prop.spec.js @@ -191,3 +191,24 @@ test('month-show event', async () => { expect(wrapper.emitted('month-show')).toBeTruthy(); }); + +test.only('first day of week', async () => { + const wrapper = mount(Calendar, { + propsData: { + poppable: false, + defaultDate: new Date(2020, 7, 1), + maxDate: new Date(2020, 7, 30), + firstDayOfWeek: 2, + }, + }); + + await later(); + + expect(wrapper.find('.van-calendar__weekdays').text()[0]).toEqual('二'); + + const day = wrapper.find( + '.van-calendar__month:first-of-type .van-calendar__day' + ); + expect(day.text()).toEqual('1'); + expect(day.attributes('style')).toContain(`margin-left: ${100 / 7}%`); +});