feat(calendar): add year navigation

This commit is contained in:
qa46hx 2020-08-13 10:55:23 +02:00 committed by Thomas Allmer
parent 6729a9fb32
commit d5f8b461d3
23 changed files with 613 additions and 249 deletions

View file

@ -156,7 +156,7 @@ export class LionCalendar extends LocalizeMixin(LitElement) {
render() {
return html`
<div class="calendar" role="application">
${this.__renderHeader()} ${this.__renderData()}
${this.__renderNavigation()} ${this.__renderData()}
</div>
`;
}
@ -173,6 +173,14 @@ export class LionCalendar extends LocalizeMixin(LitElement) {
this.__modifyDate(-1, { dateType: 'centralDate', type: 'Month', mode: 'both' });
}
goToNextYear() {
this.__modifyDate(1, { dateType: 'centralDate', type: 'FullYear', mode: 'both' });
}
goToPreviousYear() {
this.__modifyDate(-1, { dateType: 'centralDate', type: 'FullYear', mode: 'both' });
}
async focusDate(date) {
this.centralDate = date;
await this.updateComplete;
@ -254,9 +262,7 @@ export class LionCalendar extends LocalizeMixin(LitElement) {
}
}
__renderHeader() {
const month = getMonthNames({ locale: this.__getLocale() })[this.centralDate.getMonth()];
const year = this.centralDate.getFullYear();
__renderMonthNavigation(month, year) {
const nextMonth =
this.centralDate.getMonth() === 11
? getMonthNames({ locale: this.__getLocale() })[0]
@ -265,22 +271,40 @@ export class LionCalendar extends LocalizeMixin(LitElement) {
this.centralDate.getMonth() === 0
? getMonthNames({ locale: this.__getLocale() })[11]
: getMonthNames({ locale: this.__getLocale() })[this.centralDate.getMonth() - 1];
const nextYear =
this.centralDate.getMonth() === 11
? this.centralDate.getFullYear() + 1
: this.centralDate.getFullYear();
const previousYear =
this.centralDate.getMonth() === 0
? this.centralDate.getFullYear() - 1
: this.centralDate.getFullYear();
const nextYear = this.centralDate.getMonth() === 11 ? year + 1 : year;
const previousYear = this.centralDate.getMonth() === 0 ? year - 1 : year;
return html`
<div class="calendar__navigation__month">
${this.__renderPreviousButton('Month', previousMonth, previousYear)}
<h2 class="calendar__navigation-heading" id="month" aria-atomic="true">
${month}
</h2>
${this.__renderNextButton('Month', nextMonth, nextYear)}
</div>
`;
}
__renderYearNavigation(month, year) {
const nextYear = year + 1;
const previousYear = year - 1;
return html`
<div class="calendar__header">
${this.__renderPreviousButton(previousMonth, previousYear)}
<h2 class="calendar__month-heading" id="month_and_year" aria-atomic="true">
${month} ${year}
<div class="calendar__navigation__year">
${this.__renderPreviousButton('FullYear', month, previousYear)}
<h2 class="calendar__navigation-heading" id="year" aria-atomic="true">
${year}
</h2>
${this.__renderNextButton(nextMonth, nextYear)}
${this.__renderNextButton('FullYear', month, nextYear)}
</div>
`;
}
__renderNavigation() {
const month = getMonthNames({ locale: this.__getLocale() })[this.centralDate.getMonth()];
const year = this.centralDate.getFullYear();
return html`
<div class="calendar__navigation">
${this.__renderYearNavigation(month, year)} ${this.__renderMonthNavigation(month, year)}
</div>
`;
}
@ -302,40 +326,96 @@ export class LionCalendar extends LocalizeMixin(LitElement) {
});
}
__renderPreviousButton(previousMonth, previousYear) {
const previousButtonTitle = `${this.msgLit(
'lion-calendar:previousMonth',
)}, ${previousMonth} ${previousYear}`;
__getPreviousDisabled(type, previousMonth, previousYear) {
let disabled;
let month = previousMonth;
if (this.minDate && type === 'Month') {
disabled = getLastDayPreviousMonth(this.centralDate) < this.minDate;
} else if (this.minDate) {
disabled = previousYear < this.minDate.getFullYear();
}
if (!disabled && this.minDate && type === 'FullYear') {
// change the month to the first available month
if (previousYear === this.minDate.getFullYear()) {
if (this.centralDate.getMonth() < this.minDate.getMonth()) {
month = getMonthNames({ locale: this.__getLocale() })[this.minDate.getMonth()];
}
}
}
return { disabled, month };
}
__getNextDisabled(type, nextMonth, nextYear) {
let disabled;
let month = nextMonth;
if (this.maxDate && type === 'Month') {
disabled = getFirstDayNextMonth(this.centralDate) > this.maxDate;
} else if (this.maxDate) {
disabled = nextYear > this.maxDate.getFullYear();
}
if (!disabled && this.maxDate && type === 'FullYear') {
// change the month to the first available month
if (nextYear === this.maxDate.getFullYear()) {
if (this.centralDate.getMonth() >= this.maxDate.getMonth()) {
month = getMonthNames({ locale: this.__getLocale() })[this.maxDate.getMonth()];
}
}
}
return { disabled, month };
}
__renderPreviousButton(type, previousMonth, previousYear) {
const { disabled, month } = this.__getPreviousDisabled(type, previousMonth, previousYear);
const previousButtonTitle = this.__getNavigationLabel('previous', type, month, previousYear);
function clickDateDelegation() {
if (type === 'FullYear') {
this.goToPreviousYear();
} else {
this.goToPreviousMonth();
}
}
return html`
<button
class="calendar__previous-month-button"
class="calendar__previous-button"
aria-label=${previousButtonTitle}
title=${previousButtonTitle}
@click=${this.goToPreviousMonth}
?disabled=${this.isPreviousMonthDisabled}
@click=${clickDateDelegation}
?disabled=${disabled}
>
&lt;
</button>
`;
}
__renderNextButton(nextMonth, nextYear) {
const nextButtonTitle = `${this.msgLit('lion-calendar:nextMonth')}, ${nextMonth} ${nextYear}`;
__renderNextButton(type, nextMonth, nextYear) {
const { disabled, month } = this.__getNextDisabled(type, nextMonth, nextYear);
const nextButtonTitle = this.__getNavigationLabel('next', type, month, nextYear);
function clickDateDelegation() {
if (type === 'FullYear') {
this.goToNextYear();
} else {
this.goToNextMonth();
}
}
return html`
<button
class="calendar__next-month-button"
class="calendar__next-button"
aria-label=${nextButtonTitle}
title=${nextButtonTitle}
@click=${this.goToNextMonth}
?disabled=${this.isNextMonthDisabled}
@click=${clickDateDelegation}
?disabled=${disabled}
>
&gt;
</button>
`;
}
__getNavigationLabel(mode, type, month, year) {
return `${this.msgLit(`lion-calendar:${mode}${type}`)}, ${month} ${year}`;
}
__coreDayPreprocessor(_day, { currentMonth = false } = {}) {
const day = createDay(new Date(_day.date), _day);
const today = normalizeDateTime(new Date());
@ -380,12 +460,6 @@ export class LionCalendar extends LocalizeMixin(LitElement) {
});
});
});
this.isNextMonthDisabled =
this.maxDate && getFirstDayNextMonth(this.centralDate) > this.maxDate;
this.isPreviousMonthDisabled =
this.minDate && getLastDayPreviousMonth(this.centralDate) < this.minDate;
return data;
}

View file

@ -13,19 +13,21 @@ export const calendarStyle = css`
display: block;
}
.calendar__header {
display: flex;
justify-content: space-between;
border-bottom: 1px solid #adadad;
.calendar__navigation {
padding: 0 8px;
}
.calendar__month-heading {
.calendar__navigation__month,
.calendar__navigation__year {
display: flex;
}
.calendar__navigation-heading {
margin: 0.5em 0;
}
.calendar__previous-month-button,
.calendar__next-month-button {
.calendar__previous-button,
.calendar__next-button {
background-color: #fff;
border: 0;
padding: 0;

View file

@ -14,7 +14,7 @@ export function dataTemplate(
data-wrap-cols
aria-readonly="true"
class="calendar__grid"
aria-labelledby="month_and_year"
aria-labelledby="month year"
>
<thead>
<tr role="row">

View file

@ -14,14 +14,43 @@ const defaultMonthLabels = [
'November',
'December',
];
const firstWeekDays = [1, 2, 3, 4, 5, 6, 7];
const lastDaysOfYear = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
export function dayTemplate(day, { weekdays, monthsLabels = defaultMonthLabels } = {}) {
const dayNumber = day.date.getDate();
const monthName = monthsLabels[day.date.getMonth()];
const year = day.date.getFullYear();
const weekdayName = weekdays[day.weekOrder];
const firstDay = dayNumber === 1;
const endOfFirstWeek = day.weekOrder === 6 && firstWeekDays.includes(dayNumber);
const startOfFirstFullWeek = day.startOfWeek && firstWeekDays.includes(dayNumber);
if (year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0)) {
lastDaysOfYear[1] = 29;
}
const lastDayNumber = lastDaysOfYear[day.date.getMonth()];
const lastWeekDays = [];
for (let i = lastDayNumber; i >= lastDayNumber - 7; i -= 1) {
lastWeekDays.push(i);
}
const endOfLastFullWeek = day.weekOrder === 6 && lastWeekDays.includes(dayNumber);
const startOfLastWeek = day.startOfWeek && lastWeekDays.includes(dayNumber);
const lastDay = lastDayNumber === dayNumber;
return html`
<td role="gridcell" class="calendar__day-cell">
<td
role="gridcell"
class="calendar__day-cell"
?current-month=${day.currentMonth}
?first-day=${firstDay}
?end-of-first-week=${endOfFirstWeek}
?start-of-first-full-week=${startOfFirstFullWeek}
?end-of-last-full-week=${endOfLastFullWeek}
?start-of-last-week=${startOfLastWeek}
?last-day=${lastDay}
>
<button
.date=${day.date}
class="calendar__day-button"
@ -38,7 +67,9 @@ export function dayTemplate(day, { weekdays, monthsLabels = defaultMonthLabels }
?current-month=${day.currentMonth}
?next-month=${day.nextMonth}
>
${day.date.getDate()}
<span class="calendar__day-button__text">
${day.date.getDate()}
</span>
</button>
</td>
`;

View file

@ -18,19 +18,31 @@ export class CalendarObject {
}
get headerEl() {
return this.el.shadowRoot.querySelector('.calendar__header');
return this.el.shadowRoot.querySelector('.calendar__navigation');
}
get yearHeadingEl() {
return this.el.shadowRoot.querySelector('#year');
}
get monthHeadingEl() {
return this.el.shadowRoot.querySelector('.calendar__month-heading');
return this.el.shadowRoot.querySelector('#month');
}
get nextYearButtonEl() {
return this.el.shadowRoot.querySelectorAll('.calendar__next-button')[0];
}
get previousYearButtonEl() {
return this.el.shadowRoot.querySelectorAll('.calendar__previous-button')[0];
}
get nextMonthButtonEl() {
return this.el.shadowRoot.querySelector('.calendar__next-month-button');
return this.el.shadowRoot.querySelectorAll('.calendar__next-button')[1];
}
get previousMonthButtonEl() {
return this.el.shadowRoot.querySelector('.calendar__previous-month-button');
return this.el.shadowRoot.querySelectorAll('.calendar__previous-button')[1];
}
get gridEl() {
@ -117,15 +129,11 @@ export class CalendarObject {
/**
* States
*/
get activeMonthAndYear() {
get activeMonth() {
return this.monthHeadingEl.textContent.trim();
}
get activeMonth() {
return this.activeMonthAndYear.split(' ')[0];
}
get activeYear() {
return this.activeMonthAndYear.split(' ')[1];
return this.yearHeadingEl.textContent.trim();
}
}

View file

@ -18,10 +18,10 @@ describe('<lion-calendar>', () => {
const el = await fixture(html`<lion-calendar></lion-calendar>`);
expect(el.shadowRoot.querySelector('.calendar')).to.exist;
expect(el.shadowRoot.querySelector('.calendar__header')).to.exist;
expect(el.shadowRoot.querySelector('.calendar__previous-month-button')).to.exist;
expect(el.shadowRoot.querySelector('.calendar__next-month-button')).to.exist;
expect(el.shadowRoot.querySelector('.calendar__month-heading')).to.exist;
expect(el.shadowRoot.querySelector('.calendar__navigation')).to.exist;
expect(el.shadowRoot.querySelector('.calendar__previous-button')).to.exist;
expect(el.shadowRoot.querySelector('.calendar__next-button')).to.exist;
expect(el.shadowRoot.querySelector('.calendar__navigation-heading')).to.exist;
expect(el.shadowRoot.querySelector('.calendar__grid')).to.exist;
});
@ -30,25 +30,52 @@ describe('<lion-calendar>', () => {
const el = await fixture(html`<lion-calendar></lion-calendar>`);
expect(el.shadowRoot.querySelector('.calendar__month-heading')).dom.to.equal(`
expect(el.shadowRoot.querySelector('#year')).dom.to.equal(`
<h2
id="month_and_year"
class="calendar__month-heading"
id="year"
class="calendar__navigation-heading"
aria-atomic="true"
>
December 2000
2000
</h2>
`);
expect(el.shadowRoot.querySelector('#month')).dom.to.equal(`
<h2
id="month"
class="calendar__navigation-heading"
aria-atomic="true"
>
December
</h2>
`);
clock.restore();
});
it('has previous year button', async () => {
const el = await fixture(
html`<lion-calendar .centralDate=${new Date('2019/11/20')}></lion-calendar>`,
);
expect(el.shadowRoot.querySelectorAll('.calendar__previous-button')[0]).dom.to.equal(`
<button class="calendar__previous-button" aria-label="Previous year, November 2018" title="Previous year, November 2018">&lt;</button>
`);
});
it('has next year button', async () => {
const el = await fixture(
html`<lion-calendar .centralDate=${new Date('2019/11/20')}></lion-calendar>`,
);
expect(el.shadowRoot.querySelectorAll('.calendar__next-button')[0]).dom.to.equal(`
<button class="calendar__next-button" aria-label="Next year, November 2020" title="Next year, November 2020">&gt;</button>
`);
});
it('has previous month button', async () => {
const el = await fixture(
html`<lion-calendar .centralDate=${new Date('2019/11/20')}></lion-calendar>`,
);
expect(el.shadowRoot.querySelector('.calendar__previous-month-button')).dom.to.equal(`
<button class="calendar__previous-month-button" aria-label="Previous month, October 2019" title="Previous month, October 2019">&lt;</button>
expect(el.shadowRoot.querySelectorAll('.calendar__previous-button')[1]).dom.to.equal(`
<button class="calendar__previous-button" aria-label="Previous month, October 2019" title="Previous month, October 2019">&lt;</button>
`);
});
@ -56,8 +83,8 @@ describe('<lion-calendar>', () => {
const el = await fixture(
html`<lion-calendar .centralDate=${new Date('2019/11/20')}></lion-calendar>`,
);
expect(el.shadowRoot.querySelector('.calendar__next-month-button')).dom.to.equal(`
<button class="calendar__next-month-button" aria-label="Next month, December 2019" title="Next month, December 2019">&gt;</button>
expect(el.shadowRoot.querySelectorAll('.calendar__next-button')[1]).dom.to.equal(`
<button class="calendar__next-button" aria-label="Next month, December 2019" title="Next month, December 2019">&gt;</button>
`);
});
});
@ -69,7 +96,8 @@ describe('<lion-calendar>', () => {
<lion-calendar .centralDate="${new Date('2014/05/15')}"></lion-calendar>
`),
);
expect(elObj.activeMonthAndYear).to.equal('May 2014');
expect(elObj.activeMonth).to.equal('May');
expect(elObj.activeYear).to.equal('2014');
});
it('sets "centralDate" to today by default', async () => {
@ -78,7 +106,8 @@ describe('<lion-calendar>', () => {
const el = await fixture(html`<lion-calendar></lion-calendar>`);
const elObj = new CalendarObject(el);
expect(isSameDate(el.centralDate, new Date())).to.be.true;
expect(elObj.activeMonthAndYear).to.equal('March 2013');
expect(elObj.activeMonth).to.equal('March');
expect(elObj.activeYear).to.equal('2013');
clock.restore();
});
@ -125,7 +154,8 @@ describe('<lion-calendar>', () => {
></lion-calendar>
`),
);
expect(elObj.activeMonthAndYear).to.equal('June 2018');
expect(elObj.activeMonth).to.equal('June');
expect(elObj.activeYear).to.equal('2018');
});
it('changes "centralDate" from default to "selectedDate" on first render if no other custom "centralDate" is provided', async () => {
@ -136,8 +166,8 @@ describe('<lion-calendar>', () => {
`);
const elObj = new CalendarObject(el);
expect(isSameDate(el.centralDate, new Date('2016/10/20'))).to.be.true;
expect(elObj.activeMonthAndYear).to.equal('October 2016');
expect(elObj.activeMonth).to.equal('October');
expect(elObj.activeYear).to.equal('2016');
clock.restore();
});
@ -318,7 +348,8 @@ describe('<lion-calendar>', () => {
`);
const elObj = new CalendarObject(el);
expect(isSameDate(el.centralDate, new Date('2001/01/08'))).to.be.true;
expect(elObj.activeMonthAndYear).to.equal('January 2001');
expect(elObj.activeMonth).to.equal('January');
expect(elObj.activeYear).to.equal('2001');
clock.restore();
});
@ -377,14 +408,15 @@ describe('<lion-calendar>', () => {
});
});
describe('Calendar header (month navigation)', () => {
describe('Calendar navigation', () => {
describe('Title', () => {
it('contains secondary title displaying the current month and year in focus', async () => {
const el = await fixture(
html`<lion-calendar .selectedDate="${new Date('2000/12/12')}"></lion-calendar>`,
);
const elObj = new CalendarObject(el);
expect(elObj.activeMonthAndYear).to.equal('December 2000');
expect(elObj.activeMonth).to.equal('December');
expect(elObj.activeYear).to.equal('2000');
});
it('updates the secondary title when the displayed month/year changes', async () => {
@ -394,7 +426,8 @@ describe('<lion-calendar>', () => {
const elObj = new CalendarObject(el);
el.centralDate = new Date('1999/10/12');
await el.updateComplete;
expect(elObj.activeMonthAndYear).to.equal('October 1999');
expect(elObj.activeMonth).to.equal('October');
expect(elObj.activeYear).to.equal('1999');
});
describe('Accessibility', () => {
@ -406,130 +439,235 @@ describe('<lion-calendar>', () => {
});
describe('Navigation', () => {
it('has a button for navigation to previous month', async () => {
const el = await fixture(
html`<lion-calendar .selectedDate="${new Date('2001/01/01')}"></lion-calendar>`,
);
const elObj = new CalendarObject(el);
expect(elObj.previousMonthButtonEl).not.to.equal(null);
expect(elObj.activeMonthAndYear).to.equal('January 2001');
describe('Year', () => {
it('has a button for navigation to previous year', async () => {
const el = await fixture(
html`<lion-calendar .selectedDate="${new Date('2001/01/01')}"></lion-calendar>`,
);
const elObj = new CalendarObject(el);
expect(elObj.previousYearButtonEl).not.to.equal(null);
expect(elObj.activeMonth).to.equal('January');
expect(elObj.activeYear).to.equal('2001');
elObj.previousMonthButtonEl.click();
await el.updateComplete;
expect(elObj.activeMonthAndYear).to.equal('December 2000');
elObj.previousYearButtonEl.click();
await el.updateComplete;
expect(elObj.activeMonth).to.equal('January');
expect(elObj.activeYear).to.equal('2000');
elObj.previousMonthButtonEl.click();
await el.updateComplete;
expect(elObj.activeMonthAndYear).to.equal('November 2000');
elObj.previousYearButtonEl.click();
await el.updateComplete;
expect(elObj.activeMonth).to.equal('January');
expect(elObj.activeYear).to.equal('1999');
});
it('has a button for navigation to next year', async () => {
const el = await fixture(
html`<lion-calendar .selectedDate="${new Date('2000/12/12')}"></lion-calendar>`,
);
const elObj = new CalendarObject(el);
expect(elObj.nextYearButtonEl).not.to.equal(null);
expect(elObj.activeMonth).to.equal('December');
expect(elObj.activeYear).to.equal('2000');
elObj.nextYearButtonEl.click();
await el.updateComplete;
expect(elObj.activeMonth).to.equal('December');
expect(elObj.activeYear).to.equal('2001');
elObj.nextYearButtonEl.click();
await el.updateComplete;
expect(elObj.activeMonth).to.equal('December');
expect(elObj.activeYear).to.equal('2002');
});
it('disables previousYearButton and nextYearButton based on disabled days accordingly', async () => {
const el = await fixture(html`
<lion-calendar .selectedDate="${new Date('2000/06/12')}"></lion-calendar>
`);
const elObj = new CalendarObject(el);
expect(elObj.activeMonth).to.equal('June');
expect(elObj.activeYear).to.equal('2000');
expect(elObj.previousYearButtonEl.hasAttribute('disabled')).to.equal(false);
expect(elObj.nextYearButtonEl.hasAttribute('disabled')).to.equal(false);
el.minDate = new Date('2000/01/01');
el.maxDate = new Date('2000/12/31');
await el.updateComplete;
expect(elObj.previousYearButtonEl.hasAttribute('disabled')).to.equal(true);
expect(elObj.nextYearButtonEl.hasAttribute('disabled')).to.equal(true);
elObj.previousYearButtonEl.click();
await el.updateComplete;
expect(elObj.activeMonth).to.equal('June');
expect(elObj.activeYear).to.equal('2000');
el.minDate = new Date('1999/12/31');
el.maxDate = new Date('2001/01/01');
await el.updateComplete;
expect(elObj.previousYearButtonEl.hasAttribute('disabled')).to.equal(false);
expect(elObj.nextYearButtonEl.hasAttribute('disabled')).to.equal(false);
});
it('sets label to correct month previousYearButton and nextYearButton based on disabled days accordingly', async () => {
const el = await fixture(html`
<lion-calendar .selectedDate="${new Date('2000/06/12')}"></lion-calendar>
`);
const elObj = new CalendarObject(el);
el.minDate = new Date('1999/07/12');
el.maxDate = new Date('2001/05/12');
await el.updateComplete;
expect(elObj.previousYearButtonEl.hasAttribute('disabled')).to.equal(false);
expect(elObj.previousYearButtonEl.ariaLabel).to.equal('Previous year, July 1999');
expect(elObj.nextYearButtonEl.hasAttribute('disabled')).to.equal(false);
expect(elObj.nextYearButtonEl.ariaLabel).to.equal('Next year, May 2001');
});
});
it('has a button for navigation to next month', async () => {
const el = await fixture(
html`<lion-calendar .selectedDate="${new Date('2000/12/12')}"></lion-calendar>`,
);
const elObj = new CalendarObject(el);
expect(elObj.nextMonthButtonEl).not.to.equal(null);
expect(elObj.activeMonthAndYear).to.equal('December 2000');
describe('Month', () => {
it('has a button for navigation to previous month', async () => {
const el = await fixture(
html`<lion-calendar .selectedDate="${new Date('2001/01/01')}"></lion-calendar>`,
);
const elObj = new CalendarObject(el);
expect(elObj.previousMonthButtonEl).not.to.equal(null);
expect(elObj.activeMonth).to.equal('January');
expect(elObj.activeYear).to.equal('2001');
elObj.nextMonthButtonEl.click();
await el.updateComplete;
expect(elObj.activeMonthAndYear).to.equal('January 2001');
elObj.previousMonthButtonEl.click();
await el.updateComplete;
expect(elObj.activeMonth).to.equal('December');
expect(elObj.activeYear).to.equal('2000');
elObj.nextMonthButtonEl.click();
await el.updateComplete;
expect(elObj.activeMonthAndYear).to.equal('February 2001');
});
elObj.previousMonthButtonEl.click();
await el.updateComplete;
expect(elObj.activeMonth).to.equal('November');
expect(elObj.activeYear).to.equal('2000');
});
it('disables previousMonthButton and nextMonthButton based on disabled days accordingly', async () => {
const el = await fixture(html`
<lion-calendar .selectedDate="${new Date('2000/12/12')}"></lion-calendar>
`);
const elObj = new CalendarObject(el);
expect(elObj.activeMonthAndYear).to.equal('December 2000');
expect(elObj.previousMonthButtonEl.hasAttribute('disabled')).to.equal(false);
expect(elObj.nextMonthButtonEl.hasAttribute('disabled')).to.equal(false);
it('has a button for navigation to next month', async () => {
const el = await fixture(
html`<lion-calendar .selectedDate="${new Date('2000/12/12')}"></lion-calendar>`,
);
const elObj = new CalendarObject(el);
expect(elObj.nextMonthButtonEl).not.to.equal(null);
expect(elObj.activeMonth).to.equal('December');
expect(elObj.activeYear).to.equal('2000');
el.minDate = new Date('2000/12/01');
el.maxDate = new Date('2000/12/31');
await el.updateComplete;
elObj.nextMonthButtonEl.click();
await el.updateComplete;
expect(elObj.activeMonth).to.equal('January');
expect(elObj.activeYear).to.equal('2001');
expect(elObj.previousMonthButtonEl.hasAttribute('disabled')).to.equal(true);
expect(elObj.nextMonthButtonEl.hasAttribute('disabled')).to.equal(true);
elObj.nextMonthButtonEl.click();
await el.updateComplete;
expect(elObj.activeMonth).to.equal('February');
expect(elObj.activeYear).to.equal('2001');
});
elObj.previousMonthButtonEl.click();
await el.updateComplete;
expect(elObj.activeMonthAndYear).to.equal('December 2000');
it('disables previousMonthButton and nextMonthButton based on disabled days accordingly', async () => {
const el = await fixture(html`
<lion-calendar .selectedDate="${new Date('2000/12/12')}"></lion-calendar>
`);
const elObj = new CalendarObject(el);
expect(elObj.activeMonth).to.equal('December');
expect(elObj.activeYear).to.equal('2000');
expect(elObj.previousMonthButtonEl.hasAttribute('disabled')).to.equal(false);
expect(elObj.nextMonthButtonEl.hasAttribute('disabled')).to.equal(false);
elObj.previousMonthButtonEl.click();
await el.updateComplete;
expect(elObj.activeMonthAndYear).to.equal('December 2000');
});
el.minDate = new Date('2000/12/01');
el.maxDate = new Date('2000/12/31');
await el.updateComplete;
it('handles switch to previous month when dates are disabled', async () => {
const clock = sinon.useFakeTimers({ now: new Date('2000/12/15').getTime() });
expect(elObj.previousMonthButtonEl.hasAttribute('disabled')).to.equal(true);
expect(elObj.nextMonthButtonEl.hasAttribute('disabled')).to.equal(true);
const el = await fixture(html`<lion-calendar></lion-calendar>`);
const elObj = new CalendarObject(el);
expect(elObj.activeMonthAndYear).to.equal('December 2000');
elObj.previousMonthButtonEl.click();
await el.updateComplete;
expect(elObj.activeMonth).to.equal('December');
expect(elObj.activeYear).to.equal('2000');
el.minDate = new Date('2000/11/20');
await el.updateComplete;
elObj.previousMonthButtonEl.click();
await el.updateComplete;
expect(elObj.activeMonth).to.equal('December');
expect(elObj.activeYear).to.equal('2000');
});
expect(elObj.previousMonthButtonEl.hasAttribute('disabled')).to.equal(false);
expect(isSameDate(el.centralDate, new Date('2000/12/15'))).to.be.true;
it('handles switch to previous month when dates are disabled', async () => {
const clock = sinon.useFakeTimers({ now: new Date('2000/12/15').getTime() });
elObj.previousMonthButtonEl.click();
await el.updateComplete;
expect(elObj.activeMonthAndYear).to.equal('November 2000');
expect(isSameDate(el.centralDate, new Date('2000/11/20'))).to.be.true;
const el = await fixture(html`<lion-calendar></lion-calendar>`);
const elObj = new CalendarObject(el);
expect(elObj.activeMonth).to.equal('December');
expect(elObj.activeYear).to.equal('2000');
clock.restore();
});
el.minDate = new Date('2000/11/20');
await el.updateComplete;
it('handles switch to next month when dates are disabled', async () => {
const clock = sinon.useFakeTimers({ now: new Date('2000/12/15').getTime() });
expect(elObj.previousMonthButtonEl.hasAttribute('disabled')).to.equal(false);
expect(isSameDate(el.centralDate, new Date('2000/12/15'))).to.be.true;
const el = await fixture(html`<lion-calendar></lion-calendar>`);
const elObj = new CalendarObject(el);
expect(elObj.activeMonthAndYear).to.equal('December 2000');
elObj.previousMonthButtonEl.click();
await el.updateComplete;
expect(elObj.activeMonth).to.equal('November');
expect(elObj.activeYear).to.equal('2000');
expect(isSameDate(el.centralDate, new Date('2000/11/20'))).to.be.true;
el.maxDate = new Date('2001/01/10');
await el.updateComplete;
clock.restore();
});
expect(elObj.nextMonthButtonEl.hasAttribute('disabled')).to.equal(false);
expect(isSameDate(el.centralDate, new Date('2000/12/15'))).to.be.true;
it('handles switch to next month when dates are disabled', async () => {
const clock = sinon.useFakeTimers({ now: new Date('2000/12/15').getTime() });
elObj.nextMonthButtonEl.click();
await el.updateComplete;
expect(elObj.activeMonthAndYear).to.equal('January 2001');
expect(isSameDate(el.centralDate, new Date('2001/01/10'))).to.be.true;
const el = await fixture(html`<lion-calendar></lion-calendar>`);
const elObj = new CalendarObject(el);
expect(elObj.activeMonth).to.equal('December');
expect(elObj.activeYear).to.equal('2000');
clock.restore();
});
el.maxDate = new Date('2001/01/10');
await el.updateComplete;
it('supports navigating from larger months to smaller ones (day counts)', async () => {
// given
const inputDate = new Date('2019/08/31');
const element = await fixture(html`
<lion-calendar .centralDate="${inputDate}"> </lion-calendar>
`);
// when
const remote = new CalendarObject(element);
remote.nextMonthButtonEl.click();
await element.updateComplete;
// then
expect(remote.activeMonthAndYear).to.equal('September 2019');
expect(remote.centralDayObj.el).dom.to.equal(`
<button
class="calendar__day-button"
tabindex="0"
aria-label="30 September 2019 Monday"
aria-pressed="false"
past=""
current-month="">
30
</button>
`);
expect(elObj.nextMonthButtonEl.hasAttribute('disabled')).to.equal(false);
expect(isSameDate(el.centralDate, new Date('2000/12/15'))).to.be.true;
elObj.nextMonthButtonEl.click();
await el.updateComplete;
expect(elObj.activeMonth).to.equal('January');
expect(elObj.activeYear).to.equal('2001');
expect(isSameDate(el.centralDate, new Date('2001/01/10'))).to.be.true;
clock.restore();
});
it('supports navigating from larger months to smaller ones (day counts)', async () => {
// given
const inputDate = new Date('2019/08/31');
const element = await fixture(html`
<lion-calendar .centralDate="${inputDate}"> </lion-calendar>
`);
// when
const remote = new CalendarObject(element);
remote.nextMonthButtonEl.click();
await element.updateComplete;
// then
expect(remote.activeMonth).to.equal('September');
expect(remote.activeYear).to.equal('2019');
expect(remote.centralDayObj.el).dom.to.equal(`
<button
class="calendar__day-button"
tabindex="0"
aria-label="30 September 2019 Monday"
aria-pressed="false"
past=""
current-month="">
<span class="calendar__day-button__text">
30
</span>
</button>
`);
});
});
describe('Accessibility', () => {
@ -538,6 +676,7 @@ describe('<lion-calendar>', () => {
<lion-calendar .selectedDate="${new Date('2000/12/12')}"></lion-calendar>
`);
const elObj = new CalendarObject(el);
// month
expect(elObj.previousMonthButtonEl.getAttribute('title')).to.equal(
'Previous month, November 2000',
);
@ -550,6 +689,18 @@ describe('<lion-calendar>', () => {
expect(elObj.nextMonthButtonEl.getAttribute('aria-label')).to.equal(
'Next month, January 2001',
);
// year
expect(elObj.previousYearButtonEl.getAttribute('title')).to.equal(
'Previous year, December 1999',
);
expect(elObj.previousYearButtonEl.getAttribute('aria-label')).to.equal(
'Previous year, December 1999',
);
expect(elObj.nextYearButtonEl.getAttribute('title')).to.equal('Next year, December 2001');
expect(elObj.nextYearButtonEl.getAttribute('aria-label')).to.equal(
'Next year, December 2001',
);
});
});
});
@ -670,17 +821,20 @@ describe('<lion-calendar>', () => {
<lion-calendar .selectedDate="${new Date('2001/01/02')}"></lion-calendar>
`);
const elObj = new CalendarObject(el);
expect(elObj.activeMonthAndYear).to.equal('January 2001');
expect(elObj.activeMonth).to.equal('January');
expect(elObj.activeYear).to.equal('2001');
el.__contentWrapperElement.dispatchEvent(new KeyboardEvent('keydown', { key: 'PageUp' }));
await el.updateComplete;
expect(elObj.activeMonthAndYear).to.equal('December 2000');
expect(elObj.activeMonth).to.equal('December');
expect(elObj.activeYear).to.equal('2000');
el.__contentWrapperElement.dispatchEvent(
new KeyboardEvent('keydown', { key: 'PageDown' }),
);
await el.updateComplete;
expect(elObj.activeMonthAndYear).to.equal('January 2001');
expect(elObj.activeMonth).to.equal('January');
expect(elObj.activeYear).to.equal('2001');
});
it('navigates through years with [alt + pageup] [alt + pagedown] keys', async () => {
@ -688,19 +842,22 @@ describe('<lion-calendar>', () => {
<lion-calendar .selectedDate="${new Date('2001/01/02')}"></lion-calendar>
`);
const elObj = new CalendarObject(el);
expect(elObj.activeMonthAndYear).to.equal('January 2001');
expect(elObj.activeMonth).to.equal('January');
expect(elObj.activeYear).to.equal('2001');
el.__contentWrapperElement.dispatchEvent(
new KeyboardEvent('keydown', { key: 'PageDown', altKey: true }),
);
await el.updateComplete;
expect(elObj.activeMonthAndYear).to.equal('January 2002');
expect(elObj.activeMonth).to.equal('January');
expect(elObj.activeYear).to.equal('2002');
el.__contentWrapperElement.dispatchEvent(
new KeyboardEvent('keydown', { key: 'PageUp', altKey: true }),
);
await el.updateComplete;
expect(elObj.activeMonthAndYear).to.equal('January 2001');
expect(elObj.activeMonth).to.equal('January');
expect(elObj.activeYear).to.equal('2001');
});
describe('Arrow keys', () => {
@ -809,13 +966,15 @@ describe('<lion-calendar>', () => {
<lion-calendar .selectedDate="${new Date('2000/12/31')}"></lion-calendar>
`);
const elObj = new CalendarObject(el);
expect(elObj.activeMonthAndYear).to.equal('December 2000');
expect(elObj.activeMonth).to.equal('December');
expect(elObj.activeYear).to.equal('2000');
el.__contentWrapperElement.dispatchEvent(
new KeyboardEvent('keydown', { key: 'ArrowRight' }),
);
await el.updateComplete;
expect(elObj.activeMonthAndYear).to.equal('January 2001');
expect(elObj.activeMonth).to.equal('January');
expect(elObj.activeYear).to.equal('2001');
expect(elObj.focusedDayObj.monthday).to.equal(1);
});
@ -824,13 +983,15 @@ describe('<lion-calendar>', () => {
<lion-calendar .selectedDate="${new Date('2001/01/01')}"></lion-calendar>
`);
const elObj = new CalendarObject(el);
expect(elObj.activeMonthAndYear).to.equal('January 2001');
expect(elObj.activeMonth).to.equal('January');
expect(elObj.activeYear).to.equal('2001');
el.__contentWrapperElement.dispatchEvent(
new KeyboardEvent('keydown', { key: 'ArrowLeft' }),
);
await el.updateComplete;
expect(elObj.activeMonthAndYear).to.equal('December 2000');
expect(elObj.activeMonth).to.equal('December');
expect(elObj.activeYear).to.equal('2000');
expect(elObj.focusedDayObj.monthday).to.equal(31);
});
@ -839,13 +1000,15 @@ describe('<lion-calendar>', () => {
<lion-calendar .selectedDate="${new Date('2000/12/30')}"></lion-calendar>
`);
const elObj = new CalendarObject(el);
expect(elObj.activeMonthAndYear).to.equal('December 2000');
expect(elObj.activeMonth).to.equal('December');
expect(elObj.activeYear).to.equal('2000');
el.__contentWrapperElement.dispatchEvent(
new KeyboardEvent('keydown', { key: 'ArrowDown' }),
);
await el.updateComplete;
expect(elObj.activeMonthAndYear).to.equal('January 2001');
expect(elObj.activeMonth).to.equal('January');
expect(elObj.activeYear).to.equal('2001');
expect(elObj.focusedDayObj.monthday).to.equal(6);
});
@ -854,13 +1017,15 @@ describe('<lion-calendar>', () => {
<lion-calendar .selectedDate="${new Date('2001/01/02')}"></lion-calendar>
`);
const elObj = new CalendarObject(el);
expect(elObj.activeMonthAndYear).to.equal('January 2001');
expect(elObj.activeMonth).to.equal('January');
expect(elObj.activeYear).to.equal('2001');
el.__contentWrapperElement.dispatchEvent(
new KeyboardEvent('keydown', { key: 'ArrowUp' }),
);
await el.updateComplete;
expect(elObj.activeMonthAndYear).to.equal('December 2000');
expect(elObj.activeMonth).to.equal('December');
expect(elObj.activeYear).to.equal('2000');
expect(elObj.focusedDayObj.monthday).to.equal(26);
});
});

View file

@ -1,17 +1,14 @@
/* eslint-disable no-unused-expressions */
import { expect, fixture } from '@open-wc/testing';
import { createDay } from '../../src/utils/createDay.js';
import { dayTemplate } from '../../src/utils/dayTemplate.js';
const weekdays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
describe('dayTemplate', () => {
it('renders day cell', async () => {
const day = createDay(new Date('2019/04/19'), { weekOrder: 5 });
const el = await fixture(
dayTemplate(day, {
weekdays: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
}),
);
const el = await fixture(dayTemplate(day, { weekdays }));
expect(el).dom.to.equal(`
<td role="gridcell" class="calendar__day-cell">
<button
@ -20,9 +17,66 @@ describe('dayTemplate', () => {
aria-pressed="false"
tabindex="-1"
>
19
<span class="calendar__day-button__text">19</span>
</button>
</td>
`);
});
it('sets the first-day attribute', async () => {
let day = createDay(new Date('2019/04/01'));
const el1 = await fixture(dayTemplate(day, { weekdays }));
expect(el1.hasAttribute('first-day')).to.be.true;
day = createDay(new Date('2019/04/02'));
const el2 = await fixture(dayTemplate(day, { weekdays }));
expect(el2.hasAttribute('first-day')).to.be.false;
});
it('sets the end-of-first-week attribute', async () => {
let day = createDay(new Date('2019/04/06'), { weekOrder: 6 });
const el1 = await fixture(dayTemplate(day, { weekdays }));
expect(el1.hasAttribute('end-of-first-week')).to.be.true;
day = createDay(new Date('2019/04/13'), { weekOrder: 6 });
const el2 = await fixture(dayTemplate(day, { weekdays }));
expect(el2.hasAttribute('end-of-first-week')).to.be.false;
});
it('sets the start-of-first-full-week attribute', async () => {
let day = createDay(new Date('2019/04/07'), { startOfWeek: true });
const el1 = await fixture(dayTemplate(day, { weekdays }));
expect(el1.hasAttribute('start-of-first-full-week')).to.be.true;
day = createDay(new Date('2019/04/14'), { startOfWeek: true });
const el2 = await fixture(dayTemplate(day, { weekdays }));
expect(el2.hasAttribute('start-of-first-full-week')).to.be.false;
});
it('sets the end-of-last-full-week attribute', async () => {
let day = createDay(new Date('2019/04/27'), { weekOrder: 6 });
const el1 = await fixture(dayTemplate(day, { weekdays }));
expect(el1.hasAttribute('end-of-last-full-week')).to.be.true;
day = createDay(new Date('2019/04/20'), { weekOrder: 6 });
const el2 = await fixture(dayTemplate(day, { weekdays }));
expect(el2.hasAttribute('end-of-last-full-week')).to.be.false;
});
it('sets the start-of-last-week attribute', async () => {
let day = createDay(new Date('2019/04/28'), { startOfWeek: true });
const el1 = await fixture(dayTemplate(day, { weekdays }));
expect(el1.hasAttribute('start-of-last-week')).to.be.true;
day = createDay(new Date('2019/04/21'), { startOfWeek: true });
const el2 = await fixture(dayTemplate(day, { weekdays }));
expect(el2.hasAttribute('start-of-last-week')).to.be.false;
});
it('sets the last-day attribute', async () => {
let day = createDay(new Date('2019/04/30'), { startOfWeek: true });
const el1 = await fixture(dayTemplate(day, { weekdays }));
expect(el1.hasAttribute('last-day')).to.be.true;
day = createDay(new Date('2019/03/30'), { startOfWeek: true });
const el2 = await fixture(dayTemplate(day, { weekdays }));
expect(el2.hasAttribute('last-day')).to.be.false;
day = createDay(new Date('2019/02/28'), { startOfWeek: true });
const el3 = await fixture(dayTemplate(day, { weekdays }));
expect(el3.hasAttribute('last-day')).to.be.true;
});
});

View file

@ -3,7 +3,7 @@ const html = strings => strings[0];
export default html`
<div id="js-content-wrapper">
<table
aria-labelledby="month_and_year"
aria-labelledby="month year"
aria-readonly="true"
class="calendar__grid"
data-wrap-cols=""
@ -51,14 +51,14 @@ export default html`
</thead>
<tbody>
<tr role="row">
<td class="calendar__day-cell" role="gridcell">
<td class="calendar__day-cell" role="gridcell" start-of-last-week>
<button
aria-label="25 November 2018 Sunday"
aria-pressed="false"
class="calendar__day-button"
tabindex="-1"
>
25
<span class="calendar__day-button__text">25</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
@ -68,7 +68,7 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
26
<span class="calendar__day-button__text">26</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
@ -78,7 +78,7 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
27
<span class="calendar__day-button__text">27</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
@ -88,7 +88,7 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
28
<span class="calendar__day-button__text">28</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
@ -98,39 +98,39 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
29
<span class="calendar__day-button__text">29</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
<td class="calendar__day-cell" role="gridcell" last-day>
<button
aria-label="30 November 2018 Friday"
aria-pressed="false"
class="calendar__day-button"
tabindex="-1"
>
30
<span class="calendar__day-button__text">30</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
<td class="calendar__day-cell" role="gridcell" end-of-first-week first-day>
<button
aria-label="1 December 2018 Saturday"
aria-pressed="false"
class="calendar__day-button"
tabindex="-1"
>
1
<span class="calendar__day-button__text">1</span>
</button>
</td>
</tr>
<tr role="row">
<td class="calendar__day-cell" role="gridcell">
<td class="calendar__day-cell" role="gridcell" start-of-first-full-week>
<button
aria-label="2 December 2018 Sunday"
aria-pressed="false"
class="calendar__day-button"
tabindex="-1"
>
2
<span class="calendar__day-button__text">2</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
@ -140,7 +140,7 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
3
<span class="calendar__day-button__text">3</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
@ -150,7 +150,7 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
4
<span class="calendar__day-button__text">4</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
@ -160,7 +160,7 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
5
<span class="calendar__day-button__text">5</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
@ -170,7 +170,7 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
6
<span class="calendar__day-button__text">6</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
@ -180,7 +180,7 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
7
<span class="calendar__day-button__text">7</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
@ -190,7 +190,7 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
8
<span class="calendar__day-button__text">8</span>
</button>
</td>
</tr>
@ -202,7 +202,7 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
9
<span class="calendar__day-button__text">9</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
@ -212,7 +212,7 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
10
<span class="calendar__day-button__text">10</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
@ -222,7 +222,7 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
11
<span class="calendar__day-button__text">11</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
@ -232,7 +232,7 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
12
<span class="calendar__day-button__text">12</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
@ -242,7 +242,7 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
13
<span class="calendar__day-button__text">13</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
@ -252,7 +252,7 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
14
<span class="calendar__day-button__text">14</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
@ -262,7 +262,7 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
15
<span class="calendar__day-button__text">15</span>
</button>
</td>
</tr>
@ -274,7 +274,7 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
16
<span class="calendar__day-button__text">16</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
@ -284,7 +284,7 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
17
<span class="calendar__day-button__text">17</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
@ -294,7 +294,7 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
18
<span class="calendar__day-button__text">18</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
@ -304,7 +304,7 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
19
<span class="calendar__day-button__text">19</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
@ -314,7 +314,7 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
20
<span class="calendar__day-button__text">20</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
@ -324,7 +324,7 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
21
<span class="calendar__day-button__text">21</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
@ -334,7 +334,7 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
22
<span class="calendar__day-button__text">22</span>
</button>
</td>
</tr>
@ -346,7 +346,7 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
23
<span class="calendar__day-button__text">23</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
@ -356,7 +356,7 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
24
<span class="calendar__day-button__text">24</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
@ -366,7 +366,7 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
25
<span class="calendar__day-button__text">25</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
@ -376,7 +376,7 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
26
<span class="calendar__day-button__text">26</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
@ -386,7 +386,7 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
27
<span class="calendar__day-button__text">27</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
@ -396,49 +396,49 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
28
<span class="calendar__day-button__text">28</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
<td class="calendar__day-cell" role="gridcell" end-of-last-full-week>
<button
aria-label="29 December 2018 Saturday"
aria-pressed="false"
class="calendar__day-button"
tabindex="-1"
>
29
<span class="calendar__day-button__text">29</span>
</button>
</td>
</tr>
<tr role="row">
<td class="calendar__day-cell" role="gridcell">
<td class="calendar__day-cell" role="gridcell" start-of-last-week>
<button
aria-label="30 December 2018 Sunday"
aria-pressed="false"
class="calendar__day-button"
tabindex="-1"
>
30
<span class="calendar__day-button__text">30</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
<td class="calendar__day-cell" last-day role="gridcell">
<button
aria-label="31 December 2018 Monday"
aria-pressed="false"
class="calendar__day-button"
tabindex="-1"
>
31
<span class="calendar__day-button__text">31</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
<td class="calendar__day-cell" role="gridcell" first-day>
<button
aria-label="1 January 2019 Tuesday"
aria-pressed="false"
class="calendar__day-button"
tabindex="-1"
>
1
<span class="calendar__day-button__text">1</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
@ -448,7 +448,7 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
2
<span class="calendar__day-button__text">2</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
@ -458,7 +458,7 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
3
<span class="calendar__day-button__text">3</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
@ -468,17 +468,17 @@ export default html`
class="calendar__day-button"
tabindex="-1"
>
4
<span class="calendar__day-button__text">4</span>
</button>
</td>
<td class="calendar__day-cell" role="gridcell">
<td class="calendar__day-cell" role="gridcell" end-of-first-week>
<button
aria-label="5 January 2019 Saturday"
aria-pressed="false"
class="calendar__day-button"
tabindex="-1"
>
5
<span class="calendar__day-button__text">5</span>
</button>
</td>
</tr>

View file

@ -1,4 +1,6 @@
export default {
nextMonth: 'Следващ месец',
previousMonth: 'Предишен месец',
nextFullYear: 'Следващ година',
previousFullYear: 'Предишен година',
};

View file

@ -1,4 +1,6 @@
export default {
nextMonth: 'Příští měsíc',
previousMonth: 'Předchozí měsíc',
nextFullYear: 'Příští rok',
previousFullYear: 'Předchozí rok',
};

View file

@ -1,4 +1,6 @@
export default {
nextMonth: 'Nächster Monat',
previousMonth: 'Vorheriger Monat',
nextFullYear: 'Nächster Jahr',
previousFullYear: 'Vorheriger Jahr',
};

View file

@ -1,4 +1,6 @@
export default {
nextMonth: 'Next month',
previousMonth: 'Previous month',
nextFullYear: 'Next year',
previousFullYear: 'Previous year',
};

View file

@ -1,4 +1,6 @@
export default {
nextMonth: 'Mes siguiente',
previousMonth: 'Mes anterior',
nextFullYear: 'Año siguiente',
previousFullYear: 'Año anterior',
};

View file

@ -1,4 +1,6 @@
export default {
nextMonth: 'Mois prochain',
previousMonth: 'Mois précédent',
nextFullYear: 'An prochain',
previousFullYear: 'An précédent',
};

View file

@ -1,4 +1,6 @@
export default {
nextMonth: 'Következő hónap',
previousMonth: 'Előző hónap',
nextFullYear: 'Következő év',
previousFullYear: 'Előző év',
};

View file

@ -1,4 +1,6 @@
export default {
nextMonth: 'Mese successivo',
previousMonth: 'Mese precedente',
nextFullYear: 'Anno successivo',
previousFullYear: 'Anno precedente',
};

View file

@ -1,4 +1,6 @@
export default {
nextMonth: 'Volgende maand',
previousMonth: 'Vorige maand',
nextFullMonth: 'Volgend jaar',
previousFullMonth: 'Vorig jaar',
};

View file

@ -1,4 +1,6 @@
export default {
nextMonth: 'Następny miesiąc',
previousMonth: 'Poprzedni miesiąc',
nextFullYear: 'Następny rok',
previousFullYear: 'Poprzedni rok',
};

View file

@ -1,4 +1,6 @@
export default {
nextMonth: 'Luna viitoare',
previousMonth: 'Luna anterioară',
nextFullYear: 'An viitoare',
previousFullYear: 'An anterioară',
};

View file

@ -1,4 +1,6 @@
export default {
nextMonth: 'Следующий месяц',
previousMonth: 'Предыдущий месяц',
nextFullMonth: 'Следующий год',
previousFullMonth: 'Предыдущий год',
};

View file

@ -1,4 +1,6 @@
export default {
nextMonth: 'Nasledujúci mesiac',
previousMonth: 'Predchádzajúci mesiac',
nextFullYear: 'Nasledujúci rok',
previousFullYear: 'Predchádzajúci rok',
};

View file

@ -1,4 +1,6 @@
export default {
nextMonth: 'Наступний місяць',
previousMonth: 'Попередній місяць',
nextFullYear: 'Наступний року',
previousFullYear: 'Попередній року',
};

View file

@ -1,4 +1,6 @@
export default {
nextMonth: '下一个月',
previousMonth: '前一个月',
nextFullYear: '明一年',
previousFullYear: '前一年',
};