diff --git a/packages/elements/src/datetime-picker/__demo__/index.html b/packages/elements/src/datetime-picker/__demo__/index.html index fd7f057ce..ad97b12c8 100644 --- a/packages/elements/src/datetime-picker/__demo__/index.html +++ b/packages/elements/src/datetime-picker/__demo__/index.html @@ -155,6 +155,7 @@ Input Trigger Disabled Input Disabled Popup Disabled + Prevent Close On Select

@@ -190,7 +191,8 @@ weekendsOnly: dateTimePicker.weekendsOnly, inputTriggerDisabled: dateTimePicker.inputTriggerDisabled, inputDisabled: dateTimePicker.inputDisabled, - popupDisabled: dateTimePicker.popupDisabled + popupDisabled: dateTimePicker.popupDisabled, + preventCloseOnSelect: dateTimePicker.preventCloseOnSelect }; consoleEl.value = JSON.stringify(data, undefined, 4); @@ -380,6 +382,12 @@ dateTimePicker.popupDisabled = value || undefined; }); + document + .getElementById('preventCloseOnSelect') + .addEventListener('checked-changed', ({ detail: { value } }) => { + dateTimePicker.preventCloseOnSelect = value || undefined; + }); + const eventLog = []; const onEvent = (event) => { eventLog.unshift(`${event.type}: ${JSON.stringify(event.detail)}`); diff --git a/packages/elements/src/datetime-picker/__test__/datetime-picker.navigation.test.js b/packages/elements/src/datetime-picker/__test__/datetime-picker.navigation.test.js index e7b7b0c1e..ce808973f 100644 --- a/packages/elements/src/datetime-picker/__test__/datetime-picker.navigation.test.js +++ b/packages/elements/src/datetime-picker/__test__/datetime-picker.navigation.test.js @@ -2,7 +2,7 @@ import '@refinitiv-ui/elements/datetime-picker'; import '@refinitiv-ui/halo-theme/light/ef-datetime-picker.js'; -import { elementUpdated, expect, fixture, oneEvent } from '@refinitiv-ui/test-helpers'; +import { elementUpdated, expect, fixture, nextFrame, oneEvent } from '@refinitiv-ui/test-helpers'; import { fireKeydownEvent } from './utils.js'; @@ -95,5 +95,75 @@ describe('datetime-picker/Navigation', function () { await elementUpdated(el); expect(el.opened).to.be.equal(false, 'Setting disabled should close calendar'); }); + it('Should not close calendar when preventCloseOnSelect is true in single mode', async function () { + const el = await fixture( + '' + ); + await elementUpdated(el); + + const calendarEl = el.calendarEl; + const cell = calendarEl.shadowRoot.querySelector('div[tabindex]'); // Select a date cell + cell.click(); + await elementUpdated(el); + + expect(el.opened).to.be.equal(true, 'Calendar should remain open when preventCloseOnSelect is true'); + }); + it('Should not close calendar when preventCloseOnSelect is true in range mode', async function () { + const el = await fixture( + '' + ); + el.views = ['2020-04', '2020-05']; + await elementUpdated(el); + await nextFrame(); + await nextFrame(); + + const calendarFromEl = el.calendarFromEl; + const fromCell = calendarFromEl.shadowRoot.querySelector('div[tabindex]'); // Select a date in the "from" calendar + fromCell.click(); + await elementUpdated(el); + await nextFrame(); + + const calendarToEl = el.calendarToEl; + const toCell = calendarToEl.shadowRoot.querySelector('div[tabindex]'); // Select a date in the "to" calendar + toCell.click(); + await elementUpdated(el); + await nextFrame(); + + expect(el.opened).to.be.equal( + true, + 'Calendar should remain open when preventCloseOnSelect is true in range mode' + ); + }); + it('Should not close calendar when preventCloseOnSelect is true with timepicker', async function () { + const el = await fixture( + '' + ); + await elementUpdated(el); + + const calendarEl = el.calendarEl; + const cell = calendarEl.shadowRoot.querySelector('div[tabindex]'); // Select a date cell + cell.click(); + await elementUpdated(el); + + const timepickerEl = el.timepickerEl; + timepickerEl.value = '12:30'; // Simulate time selection + await elementUpdated(el); + + expect(el.opened).to.be.equal( + true, + 'Calendar should remain open when preventCloseOnSelect is true with timepicker' + ); + }); + it('Should close calendar when preventCloseOnSelect is false', async function () { + const el = await fixture(''); + await elementUpdated(el); + + const calendarEl = el.calendarEl; + const cell = calendarEl.shadowRoot.querySelector('div[tabindex]'); // Select a date cell + cell.click(); + await elementUpdated(el); + + expect(el.opened).to.be.equal(false, 'Calendar should close when preventCloseOnSelect is false'); + }); }); }); diff --git a/packages/elements/src/datetime-picker/index.ts b/packages/elements/src/datetime-picker/index.ts index 09d52a923..7192664c6 100644 --- a/packages/elements/src/datetime-picker/index.ts +++ b/packages/elements/src/datetime-picker/index.ts @@ -342,6 +342,13 @@ export class DatetimePicker extends FormFieldElement implements MultiValue { @property({ type: Boolean, attribute: 'input-trigger-disabled' }) public inputTriggerDisabled = false; + /** + * Prevents the Picker from closing on date selection. + * Note that if timepicker is true, the picker will remain open regardless of this flag. + */ + @property({ type: Boolean, attribute: 'prevent-close-on-select' }) + public preventCloseOnSelect = false; + /** * Disable input part of the picker */ @@ -998,6 +1005,9 @@ export class DatetimePicker extends FormFieldElement implements MultiValue { // Close popup if there is no time picker const newValues = this.values; if (!this.timepicker && newValues[0] && (this.range ? newValues[1] : true)) { + if (this.preventCloseOnSelect) { + return; + } this.setOpened(false); /**