diff --git a/packages/calendar/__tests__/calendar.spec.ts b/packages/calendar/__tests__/calendar.spec.ts new file mode 100644 index 0000000000..35aed45dcf --- /dev/null +++ b/packages/calendar/__tests__/calendar.spec.ts @@ -0,0 +1,89 @@ +import { mount } from '@vue/test-utils' +import { nextTick } from 'vue' +import Calendar from '../src/index.vue' + +const _mount = (template: string, data?, otherObj?) => mount({ + components: { + 'el-calendar': Calendar, + }, + template, + data, + ...otherObj, +}) + +describe('Calendar.vue', () => { + it('create', async() => { + const wrapper = _mount(` + + `, () => ({ value: new Date('2019-04-01') })) + const titleEl = wrapper.find('.el-calendar__title') + expect(/2019.*April/.test((titleEl.element as HTMLElement).innerHTML)).toBeTruthy() + expect(wrapper.element.querySelectorAll('thead th').length).toBe(7) + const rows = wrapper.element.querySelectorAll('.el-calendar-table__row') + expect(rows.length).toBe(6); + (rows[5].firstElementChild as HTMLElement).click() + + await nextTick() + expect(/2019.*May/.test((titleEl.element as HTMLElement).innerHTML)).toBeTruthy() + const vm = wrapper.vm as any + const date = vm.value + expect(date.getFullYear()).toBe(2019) + expect(date.getMonth()).toBe(4) + expect((wrapper.find('.is-selected span').element as HTMLElement).innerHTML).toBe('5') + }) + + it('range', () => { + const wrapper = _mount(` + + `) + const titleEl = wrapper.find('.el-calendar__title') + expect(/2019.*March/.test((titleEl.element as HTMLElement).innerHTML)).toBeTruthy() + const rows = wrapper.element.querySelectorAll('.el-calendar-table__row') + expect(rows.length).toBe(4) + expect(wrapper.element.querySelector('.el-calendar__button-group')).toBeNull() + }) + + it('range tow monthes', async() => { + const wrapper = _mount(` + + `) + const titleEl = wrapper.find('.el-calendar__title') + expect(/2019.*April/.test((titleEl.element as HTMLElement).innerHTML)).toBeTruthy() + const dateTables = wrapper.element.querySelectorAll('.el-calendar-table.is-range') + expect(dateTables.length).toBe(2) + const rows = wrapper.element.querySelectorAll('.el-calendar-table__row') + expect(rows.length).toBe(5) + const cell = rows[rows.length - 1].firstElementChild; + (cell as HTMLElement).click() + + await nextTick() + + expect(/2019.*May/.test((titleEl.element as HTMLElement).innerHTML)).toBeTruthy() + expect(cell.classList.contains('is-selected')).toBeTruthy() + }) + + it('firstDayOfWeek', async () => { + // default en locale, weekStart 0 Sunday + const wrapper = _mount(` + + `, () => ({ value: new Date('2019-04-01') })) + const head = wrapper.element.querySelector('.el-calendar-table thead') + expect((head.firstElementChild as HTMLElement).innerHTML).toBe('Sun') + expect((head.lastElementChild as HTMLElement).innerHTML).toBe('Sat') + const firstRow = wrapper.element.querySelector('.el-calendar-table__row') + expect((firstRow.firstElementChild as HTMLElement).innerHTML).toContain('31') + expect((firstRow.lastElementChild as HTMLElement).innerHTML).toContain('6') + }) + + it('firstDayOfWeek in range mode', async () => { + const wrapper = _mount(` + + `, () => ({ value: new Date('2019-03-04') })) + const head = wrapper.element.querySelector('.el-calendar-table thead') + expect((head.firstElementChild as HTMLElement).innerHTML).toBe('Sun') + expect((head.lastElementChild as HTMLElement).innerHTML).toBe('Sat') + const firstRow = wrapper.element.querySelector('.el-calendar-table__row') + expect((firstRow.firstElementChild as HTMLElement).innerHTML).toContain('3') + expect((firstRow.lastElementChild as HTMLElement).innerHTML).toContain('9') + }) +}) diff --git a/packages/calendar/index.ts b/packages/calendar/index.ts new file mode 100644 index 0000000000..f427b9b080 --- /dev/null +++ b/packages/calendar/index.ts @@ -0,0 +1,5 @@ +import { App } from 'vue' +import Calendar from './src/index.vue' +export default (app: App): void => { + app.component(Calendar.name, Calendar) +} diff --git a/packages/calendar/package.json b/packages/calendar/package.json new file mode 100644 index 0000000000..c54d9494e9 --- /dev/null +++ b/packages/calendar/package.json @@ -0,0 +1,12 @@ +{ + "name": "@element-plus/calendar", + "version": "0.0.0", + "main": "dist/index.js", + "license": "MIT", + "peerDependencies": { + "vue": "^3.0.0-rc.9" + }, + "devDependencies": { + "@vue/test-utils": "^2.0.0-beta.3" + } +} diff --git a/packages/calendar/src/date-table.vue b/packages/calendar/src/date-table.vue new file mode 100644 index 0000000000..dcd56af089 --- /dev/null +++ b/packages/calendar/src/date-table.vue @@ -0,0 +1,207 @@ + + + diff --git a/packages/calendar/src/index.vue b/packages/calendar/src/index.vue new file mode 100644 index 0000000000..79b64f405a --- /dev/null +++ b/packages/calendar/src/index.vue @@ -0,0 +1,222 @@ + + + diff --git a/packages/element-plus/index.ts b/packages/element-plus/index.ts index 8b5f958094..5e25ce1207 100644 --- a/packages/element-plus/index.ts +++ b/packages/element-plus/index.ts @@ -34,8 +34,10 @@ import ElSlider from '@element-plus/slider' import ElInput from '@element-plus/input' import ElTransfer from '@element-plus/transfer' import ElDialog from '@element-plus/dialog' +import ElCalendar from '@element-plus/calendar' import ElInfiniteScroll from '@element-plus/infinite-scroll' + export { ElAlert, ElAvatar, @@ -71,6 +73,7 @@ export { ElInput, ElTransfer, ElDialog, + ElCalendar, ElInfiniteScroll, } @@ -110,6 +113,7 @@ const install = (app: App): void => { ElInput(app) ElTransfer(app) ElDialog(app) + ElCalendar(app) ElInfiniteScroll(app) } diff --git a/website/components/header.vue b/website/components/header.vue index f95081f0e3..b77a0f06a9 100644 --- a/website/components/header.vue +++ b/website/components/header.vue @@ -93,18 +93,20 @@ {{ displayedLang }} - - + - {{ value }} - - + + {{ value }} + + + diff --git a/website/docs/en-US/calendar.md b/website/docs/en-US/calendar.md index 4516c59ee7..d5ceaf906e 100644 --- a/website/docs/en-US/calendar.md +++ b/website/docs/en-US/calendar.md @@ -26,12 +26,11 @@ Display date. :::demo Customize what is displayed in the calendar cell by setting `scoped-slot` named `dateCell`. In `scoped-slot` you can get the date (the date of the current cell), data (including the type, isSelected, day attribute). For details, please refer to the API documentation below. ```html - @@ -47,7 +46,7 @@ Display date. :::demo Set the `range` attribute to specify the display range of the calendar. Start time must be Monday, end time must be Sunday, and the time span cannot exceed two months. ```html - + ``` ::: diff --git a/website/docs/es/calendar.md b/website/docs/es/calendar.md index 717861461b..374bada392 100644 --- a/website/docs/es/calendar.md +++ b/website/docs/es/calendar.md @@ -27,12 +27,11 @@ Muestra fechas. ```html - @@ -48,7 +47,7 @@ Muestra fechas. :::demo Defina el atributo `range` para especificar el rango de visualización del calendario. El tiempo de inicio debe ser el lunes, el tiempo de finalización debe ser el domingo y el período no puede exceder los dos meses. ```html - + ``` ::: diff --git a/website/docs/fr-FR/calendar.md b/website/docs/fr-FR/calendar.md index a198b2be9d..a81a641c81 100644 --- a/website/docs/fr-FR/calendar.md +++ b/website/docs/fr-FR/calendar.md @@ -26,12 +26,11 @@ Affiche un calendrier. :::demo Personnalisez le contenu du calendrier en utilisant le `scoped-slot` appelé `dateCell`. Dans ce `scoped-slot` vous aurez accès au paramètres date (date de la cellule courante), data (incluant les attributs type, isSelected et day). Pour plus d'informations, référez-vous à la documentation ci-dessous. ```html - @@ -47,7 +46,7 @@ Affiche un calendrier. :::demo Utilisez l'attribut `range` pour afficher un intervalle particulier. Le début doit être un lundi et la fin un dimanche, l'intervalle ne pouvant excéder deux mois. ```html - + ``` ::: diff --git a/website/docs/zh-CN/calendar.md b/website/docs/zh-CN/calendar.md index 2dc53b5115..050a6e94cc 100644 --- a/website/docs/zh-CN/calendar.md +++ b/website/docs/zh-CN/calendar.md @@ -26,12 +26,11 @@ :::demo 通过设置名为 `dateCell` 的 `scoped-slot` 来自定义日历单元格中显示的内容。在 `scoped-slot` 可以获取到 date(当前单元格的日期), data(包括 type,isSelected,day 属性)。详情解释参考下方的 API 文档。 ```html - @@ -47,7 +46,7 @@ :::demo 设置 `range` 属性指定日历的显示范围。开始时间必须是周起始日,结束时间必须是周结束日,且时间跨度不能超过两个月。 ```html - + ``` ::: diff --git a/website/entry.js b/website/entry.js index b30ccd868f..b2cb1c66d1 100644 --- a/website/entry.js +++ b/website/entry.js @@ -12,6 +12,9 @@ import './demo-styles/index.scss' import './assets/styles/common.css' import './assets/styles/fonts/style.css' import icon from './icon.json' +import dayjs from 'dayjs' +import 'dayjs/locale/zh-cn' +dayjs.locale('zh-cn') // todo: locale based on Doc site lang import App from './app.vue' import ElementPlus from 'element-plus'