From eae38926cdc17e4343781da29a083cbaa3641a8a Mon Sep 17 00:00:00 2001 From: qa46hx Date: Thu, 7 May 2020 15:52:59 +0200 Subject: [PATCH] fix(calendar): enhance centralDate initialization Co-authored-by: Thijs Louisse --- .changeset/shaggy-wasps-doubt.md | 6 ++++ packages/calendar/src/LionCalendar.js | 15 +++++++++ packages/calendar/test/lion-calendar.test.js | 33 ++++++++++++++++++- .../src/LionInputDatepicker.js | 7 ++-- .../test-helpers/DatepickerInputObject.js | 23 +++++++------ .../test/lion-input-datepicker.test.js | 27 ++++++++++++--- 6 files changed, 91 insertions(+), 20 deletions(-) create mode 100644 .changeset/shaggy-wasps-doubt.md diff --git a/.changeset/shaggy-wasps-doubt.md b/.changeset/shaggy-wasps-doubt.md new file mode 100644 index 000000000..d1a3ea012 --- /dev/null +++ b/.changeset/shaggy-wasps-doubt.md @@ -0,0 +1,6 @@ +--- +'@lion/calendar': patch +'@lion/input-datepicker': patch +--- + +Calendar allows to reinitialize centralDate properly. Datepicker calls this functionality on opening the calendar. diff --git a/packages/calendar/src/LionCalendar.js b/packages/calendar/src/LionCalendar.js index cf47a9e4d..5d724d43d 100644 --- a/packages/calendar/src/LionCalendar.js +++ b/packages/calendar/src/LionCalendar.js @@ -324,6 +324,19 @@ export class LionCalendar extends LocalizeMixin(LitElement) { } } + /** + * This exposes an interface for datepickers that want to + * reinitialize when calendar is opened + */ + initCentralDate() { + if (this.selectedDate) { + this.focusSelectedDate(); + } else { + this.centralDate = /** @type {Date} */ (this.__initialCentralDate); + this.focusCentralDate(); + } + } + /** * @private */ @@ -334,6 +347,8 @@ export class LionCalendar extends LocalizeMixin(LitElement) { } else { this.__ensureValidCentralDate(); } + /** @type {Date} */ + this.__initialCentralDate = this.centralDate; } /** diff --git a/packages/calendar/test/lion-calendar.test.js b/packages/calendar/test/lion-calendar.test.js index fd322e7ee..300f604a9 100644 --- a/packages/calendar/test/lion-calendar.test.js +++ b/packages/calendar/test/lion-calendar.test.js @@ -20,7 +20,7 @@ describe('', () => { localizeTearDown(); }); - describe.skip('Structure', () => { + describe('Structure', () => { it('implements BEM structure', async () => { const el = await fixture(html``); @@ -209,6 +209,17 @@ describe('', () => { expect(elObj.selectedDayObj).to.be.undefined; }); + it('recalculates "centralDate" when "selectedDate" is reset', async () => { + const el = await fixture(html` + + `); + const elObj = new CalendarObject(el); + el.selectedDate = undefined; + await el.updateComplete; + expect(elObj.selectedDayObj).to.be.undefined; + expect(isSameDate(el.centralDate, new Date('2019/06/15'))).to.be.true; + }); + it('sends event "user-selected-date-changed" when user selects a date', async () => { const dateChangedSpy = sinon.spy(); const el = await fixture(html` @@ -289,6 +300,26 @@ describe('', () => { expect(elObj.getDayObj(7).isFocused).to.be.true; }); + it('has a initCentralDate() method for external contexts like datepickers', async () => { + const initialCentralDate = new Date('2014/07/05'); + const initialSelectedDate = new Date('2014/07/07'); + const el = await fixture(html``); + + expect(el.selectedDate).to.equal(initialSelectedDate); + expect(el.centralDate).to.equal(initialCentralDate); + + const newSelectedDate = new Date('2015/07/05'); + el.selectedDate = newSelectedDate; + el.initCentralDate(); + expect(el.centralDate).to.equal(newSelectedDate); + el.selectedDate = undefined; + el.initCentralDate(); + expect(el.centralDate).to.equal(initialCentralDate); + }); + describe('Enabled Dates', () => { it('disables all days before "minDate" property', async () => { const el = await fixture(html` diff --git a/packages/input-datepicker/src/LionInputDatepicker.js b/packages/input-datepicker/src/LionInputDatepicker.js index b7c4c6066..8c7bb02e0 100644 --- a/packages/input-datepicker/src/LionInputDatepicker.js +++ b/packages/input-datepicker/src/LionInputDatepicker.js @@ -352,14 +352,11 @@ export class LionInputDatepicker extends ScopedElementsMixin( /** * Lifecycle callback for subclassers + * @overridable */ _onCalendarOverlayOpened() { if (this._focusCentralDateOnCalendarOpen) { - if (this._calendarNode.selectedDate) { - this._calendarNode.focusSelectedDate(); - } else { - this._calendarNode.focusCentralDate(); - } + this._calendarNode.initCentralDate(); } } diff --git a/packages/input-datepicker/test-helpers/DatepickerInputObject.js b/packages/input-datepicker/test-helpers/DatepickerInputObject.js index 7e156e966..8316bb8b2 100644 --- a/packages/input-datepicker/test-helpers/DatepickerInputObject.js +++ b/packages/input-datepicker/test-helpers/DatepickerInputObject.js @@ -8,20 +8,23 @@ export class DatepickerInputObject { /** * Methods mimicing User Interaction + * @param {{click?:boolean}} [options] */ - - async openCalendar() { + async openCalendar({ click } = {}) { // Make sure the calendar is opened, not closed/toggled; this.overlayController.hide(); - this.invokerEl.click(); - const completePromises = []; - if (this.overlayEl) { - completePromises.push(this.overlayEl.updateComplete); + if (click) { + this.invokerEl.click(); + const completePromises = []; + if (this.overlayEl) { + completePromises.push(this.overlayEl.updateComplete); + } + if (this.calendarEl) { + completePromises.push(this.calendarEl.updateComplete); + } + return Promise.all(completePromises); } - if (this.calendarEl) { - completePromises.push(this.calendarEl.updateComplete); - } - return Promise.all(completePromises); + return this.el.__openCalendarOverlay(); } async closeCalendar() { diff --git a/packages/input-datepicker/test/lion-input-datepicker.test.js b/packages/input-datepicker/test/lion-input-datepicker.test.js index 20532bf28..a4bc26da2 100644 --- a/packages/input-datepicker/test/lion-input-datepicker.test.js +++ b/packages/input-datepicker/test/lion-input-datepicker.test.js @@ -151,10 +151,10 @@ describe('', () => { const el = await fixture(html``); const elObj = new DatepickerInputObject(el); expect(elObj.overlayController.isShown).to.equal(false); - await elObj.openCalendar(); + await elObj.openCalendar({ click: true }); expect(elObj.overlayController.isShown).to.equal(false); el.disabled = false; - await elObj.openCalendar(); + await elObj.openCalendar({ click: true }); expect(elObj.overlayController.isShown).to.equal(true); }); @@ -162,10 +162,10 @@ describe('', () => { const el = await fixture(html``); const elObj = new DatepickerInputObject(el); expect(elObj.overlayController.isShown).to.equal(false); - await elObj.openCalendar(); + await elObj.openCalendar({ click: true }); expect(elObj.overlayController.isShown).to.equal(false); el.readOnly = false; - await elObj.openCalendar(); + await elObj.openCalendar({ click: true }); expect(elObj.overlayController.isShown).to.equal(true); }); }); @@ -184,6 +184,25 @@ describe('', () => { expect(isSameDate(/** @type {Date} */ (el.modelValue), myOtherDate)).to.be.true; }); + it('restores centralDate when modelValue is cleared', async () => { + const myDate = new Date('2019/06/15'); + const el = await fixture(html` `); + const elObj = new DatepickerInputObject(el); + const initialCentralDate = elObj.calendarEl.centralDate; + el.modelValue = myDate; + + await elObj.openCalendar(); + expect(elObj.calendarEl.selectedDate).to.equal(myDate); + expect(elObj.calendarEl.centralDate).to.equal(myDate); + + el.modelValue = undefined; + expect(elObj.calendarEl.centralDate).to.equal(myDate); + await elObj.closeCalendar(); + await elObj.openCalendar(); + + expect(elObj.calendarEl.centralDate).to.equal(initialCentralDate); + }); + it('closes the calendar overlay on "user-selected-date-changed"', async () => { const el = await fixture(html``); const elObj = new DatepickerInputObject(el);