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

@@ -209,7 +210,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); @@ -399,6 +401,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 6b098a8e3..be7661928 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'; @@ -77,5 +77,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 2b8997593..4402d7764 100644 --- a/packages/elements/src/datetime-picker/index.ts +++ b/packages/elements/src/datetime-picker/index.ts @@ -343,6 +343,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 */ @@ -994,6 +1001,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); /**