From 4f4bf5b4133d9138e594a9bc388e476d5f17b8e1 Mon Sep 17 00:00:00 2001 From: Mizga Ionut-Alexandru Date: Mon, 25 Nov 2024 16:30:32 +0200 Subject: [PATCH 01/16] fix: update segment digits overflow --- .../src/segments/EditableSegment.ts | 20 ++++------------ .../test/date-time-picker.test.ts | 23 ++++++++++--------- 2 files changed, 17 insertions(+), 26 deletions(-) diff --git a/packages/date-time-picker/src/segments/EditableSegment.ts b/packages/date-time-picker/src/segments/EditableSegment.ts index 3ecd7122b5..184bc3ad1c 100644 --- a/packages/date-time-picker/src/segments/EditableSegment.ts +++ b/packages/date-time-picker/src/segments/EditableSegment.ts @@ -62,26 +62,16 @@ export abstract class EditableSegment { const typedValue = numberParser.parse(eventData); if (isNaN(typedValue)) return; - let newValue: number | undefined = numberParser.parse( + const newValue: number | undefined = numberParser.parse( `${this.value ?? ''}${typedValue}` ); - if (String(newValue).length > String(this.maxValue).length) - newValue = numberParser.parse(String(newValue).slice(1)); - - const { minValue, maxValue } = this.inputValidationLimits; - - if (newValue < minValue) { - newValue = !this.isInputValueCompliant(typedValue) - ? this.value - : typedValue; - } else if (newValue > maxValue) { - newValue = !this.isInputValueCompliant(typedValue) - ? this.value - : typedValue; + if (this.isInputValueCompliant(newValue)) { + this.value = newValue; + return; } - this.value = newValue; + if (this.isInputValueCompliant(typedValue)) this.value = typedValue; } private isInputValueCompliant(value: number): boolean { diff --git a/packages/date-time-picker/test/date-time-picker.test.ts b/packages/date-time-picker/test/date-time-picker.test.ts index 88be449543..59d6c53f36 100644 --- a/packages/date-time-picker/test/date-time-picker.test.ts +++ b/packages/date-time-picker/test/date-time-picker.test.ts @@ -157,7 +157,9 @@ describe('DateTimePicker', () => { }); it('should update the value as CalendarDate when it is the most specific date value', async () => { - element = await fixtureElement({ props: { value: valueDate } }); + element = await fixtureElement({ + props: { value: valueDate.set({ year: 2222 }) }, + }); editableSegments = getEditableSegments(element); const year = editableSegments.getByType(SegmentTypes.Year); @@ -195,7 +197,9 @@ describe('DateTimePicker', () => { }); it('should update the value as CalendarDateTime when it is the most specific date value', async () => { - element = await fixtureElement({ props: { value: valueDateTime } }); + element = await fixtureElement({ + props: { value: valueDateTime.set({ year: 2222 }) }, + }); editableSegments = getEditableSegments(element); const year = editableSegments.getByType(SegmentTypes.Year); @@ -237,7 +241,9 @@ describe('DateTimePicker', () => { }); it('should update the value as ZonedDateTime when it is the most specific date value', async () => { - element = await fixtureElement({ props: { value: valueZoned } }); + element = await fixtureElement({ + props: { value: valueZoned.set({ year: 2222 }) }, + }); editableSegments = getEditableSegments(element); const year = editableSegments.getByType(SegmentTypes.Year); @@ -1995,7 +2001,7 @@ describe('DateTimePicker', () => { await sendKeys({ type: '0' }); expect(segment.innerText).to.equal('2030'); await sendKeys({ type: '5' }); - expect(segment.innerText).to.equal('305'); + expect(segment.innerText).to.equal('5'); expectPlaceholders(editableSegments, [segment]); expect(element.value).to.be.undefined; @@ -2247,7 +2253,7 @@ describe('DateTimePicker', () => { expect(segment.innerText).to.equal('12'); await sendKeys({ type: '3' }); await elementUpdated(element); - expect(segment.innerText).to.equal('23'); + expect(segment.innerText).to.equal('03'); await sendKeys({ type: '5' }); await elementUpdated(element); expect(segment.innerText).to.equal('05'); @@ -2663,7 +2669,7 @@ describe('DateTimePicker', () => { element = await fixtureElement({ props: { precision: Precisions.Second, - value: new CalendarDateTime(1010, 10, 15, 13, 10, 10), + value: new CalendarDateTime(1010, 10, 15, 12, 10, 10), }, }); element.addEventListener('input', inputSpy); @@ -2900,7 +2906,6 @@ describe('DateTimePicker', () => { }); element.addEventListener('input', inputSpy); editableSegments = getEditableSegments(element); - const yearSegment = editableSegments.getByType(SegmentTypes.Year); const monthSegment = editableSegments.getByType(SegmentTypes.Month); const hourSegment = editableSegments.getByType(SegmentTypes.Hour); const secondSegment = editableSegments.getByType( @@ -2910,10 +2915,6 @@ describe('DateTimePicker', () => { SegmentTypes.DayPeriod ); - yearSegment.focus(); - await sendKeys({ type: '222' }); - await elementUpdated(element); - monthSegment.focus(); await sendKeys({ type: '5' }); await elementUpdated(element); From 24fa31ce5c5f3bb05fa832b262b45f2d5332950a Mon Sep 17 00:00:00 2001 From: Mizga Ionut-Alexandru Date: Tue, 26 Nov 2024 09:40:48 +0200 Subject: [PATCH 02/16] style: uncomment webkit prefix --- packages/date-time-picker/src/date-time-picker.css | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/date-time-picker/src/date-time-picker.css b/packages/date-time-picker/src/date-time-picker.css index ccafa535a5..76217ce693 100644 --- a/packages/date-time-picker/src/date-time-picker.css +++ b/packages/date-time-picker/src/date-time-picker.css @@ -131,7 +131,10 @@ sp-popover .popover-content { white-space: pre; user-select: none; - /* -webkit-user-select: none; */ + /* Currently Safari needs this to work as intended. + * The literal segments should not be selectable. + */ + -webkit-user-select: none; /* stylelint-disable-line */ } .is-placeholder, From 47fc924581581dd69023451da889bbbfdbc0598e Mon Sep 17 00:00:00 2001 From: Mizga Ionut-Alexandru Date: Tue, 26 Nov 2024 09:46:01 +0200 Subject: [PATCH 03/16] refactor(calendar): extract updateCurrentDate method --- packages/calendar/src/Calendar.ts | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/packages/calendar/src/Calendar.ts b/packages/calendar/src/Calendar.ts index 2ea80d7ab1..1487de1612 100644 --- a/packages/calendar/src/Calendar.ts +++ b/packages/calendar/src/Calendar.ts @@ -191,16 +191,7 @@ export class Calendar extends SpectrumElement { if (changesDates) { this.convertToCalendarDates(); this.checkDatePropsCompliance(changesMin || changesMax); - if (this.value) this.currentDate = this.value as CalendarDate; - else { - const isTodayNonCompliant = this.isNonCompliantDate(this.today); - - if (isTodayNonCompliant) { - if (this.min) this.currentDate = this.min as CalendarDate; - else if (this.max) - this.currentDate = this.max as CalendarDate; - } else this.currentDate = this.today; - } + this.updateCurrentDate(); } const previousDate = changedProperties.get('currentDate'); @@ -264,6 +255,20 @@ export class Calendar extends SpectrumElement { } } + private updateCurrentDate(): void { + if (this.value) { + this.currentDate = this.value as CalendarDate; + return; + } + + const isTodayNonCompliant = this.isNonCompliantDate(this.today); + + if (isTodayNonCompliant) { + if (this.min) this.currentDate = this.min as CalendarDate; + else if (this.max) this.currentDate = this.max as CalendarDate; + } else this.currentDate = this.today; + } + /** * Whether the date is non-compliant with the min and max constraints */ From 5925b6175d9510b917241195a7aab6981a248373 Mon Sep 17 00:00:00 2001 From: Mizga Ionut-Alexandru Date: Tue, 26 Nov 2024 16:31:31 +0200 Subject: [PATCH 04/16] test(date-time-picker): added focus tests --- .../test/date-time-picker.test.ts | 182 ++++++++++++++++-- packages/date-time-picker/test/helpers.ts | 8 + 2 files changed, 172 insertions(+), 18 deletions(-) diff --git a/packages/date-time-picker/test/date-time-picker.test.ts b/packages/date-time-picker/test/date-time-picker.test.ts index 59d6c53f36..e6519305b3 100644 --- a/packages/date-time-picker/test/date-time-picker.test.ts +++ b/packages/date-time-picker/test/date-time-picker.test.ts @@ -45,6 +45,7 @@ import { expectSameDates, fixtureElement, getEditableSegments, + getElementCenter, openCalendar, sendKeyMultipleTimes, } from './helpers.js'; @@ -613,14 +614,10 @@ describe('DateTimePicker', () => { 'sp-picker-button' ) as PickerButton; - const rect = calendarButton.getBoundingClientRect(); - const centerX = Math.round(rect.left + rect.width / 2); - const centerY = Math.round(rect.top + rect.height / 2); - const opened = oneEvent(element, 'sp-opened'); await sendMouse({ type: 'click', - position: [centerX, centerY], + position: getElementCenter(calendarButton), }); await opened; @@ -903,17 +900,168 @@ describe('DateTimePicker', () => { }); describe('Focus', () => { - it('should focus segments by clicking on them'); - it( - "should change segment focus to right by using the 'Right Arrow' key" - ); - it("should change segment focus to left by using the 'Left Arrow' key"); - it( - 'should change segment focus to left by using the Backspace/Delete key on a placeholder' - ); - // TODO: one TAB press should focus the calendar button, not the next segment - it("should focus the calendar button by using the 'Tab' key"); - it('should focus the calendar button after the Calendar closes'); + it('should focus segments by clicking on them', async () => { + const yearSegment = editableSegments.getByType(SegmentTypes.Year); + + await sendMouse({ + type: 'click', + position: getElementCenter(yearSegment), + }); + await sendKeys({ press: 'ArrowUp' }); + + expect(document.activeElement === element).to.be.true; + expect(element.shadowRoot.activeElement === yearSegment).to.be.true; + expect(yearSegment.innerText).to.equal(`${fixedYear}`); + + const daySegment = editableSegments.getByType(SegmentTypes.Day); + + await sendMouse({ + type: 'click', + position: getElementCenter(daySegment), + }); + await sendKeys({ press: 'ArrowUp' }); + + expect(document.activeElement === element).to.be.true; + expect(element.shadowRoot.activeElement === daySegment).to.be.true; + expect(daySegment.innerText).to.equal('01'); + }); + + it('should focus the first editable segment when the focus method is called', async () => { + element.focus(); + + expect(document.activeElement === element).to.be.true; + expect( + element.shadowRoot.activeElement === + element.firstEditableSegment + ).to.be.true; + }); + + it("should change segment focus to right by using the 'Right Arrow' key", async () => { + element = await fixtureElement({ + props: { precision: Precisions.Second }, + }); + editableSegments = getEditableSegments(element); + const dayPeriodSegment = editableSegments.getByType( + SegmentTypes.DayPeriod + ); + + element.focus(); + await sendKeyMultipleTimes( + 'ArrowRight', + editableSegments.length - 1 + ); + + expect(element.shadowRoot.activeElement === dayPeriodSegment).to.be + .true; + + await sendKeys({ press: 'ArrowRight' }); + + expect(element.shadowRoot.activeElement === dayPeriodSegment).to.be + .true; + }); + + it("should change segment focus to left by using the 'Left Arrow' key", async () => { + element = await fixtureElement({ + props: { precision: Precisions.Second }, + }); + editableSegments = getEditableSegments(element); + const dayPeriodSegment = editableSegments.getByType( + SegmentTypes.DayPeriod + ); + + await sendMouse({ + type: 'click', + position: getElementCenter(dayPeriodSegment), + }); + + expect(document.activeElement === element).to.be.true; + expect(element.shadowRoot.activeElement === dayPeriodSegment).to.be + .true; + + await sendKeyMultipleTimes( + 'ArrowLeft', + editableSegments.length - 1 + ); + + expect( + element.shadowRoot.activeElement === + element.firstEditableSegment + ).to.be.true; + + await sendKeys({ press: 'ArrowLeft' }); + + expect( + element.shadowRoot.activeElement === + element.firstEditableSegment + ).to.be.true; + }); + + it('should change segment focus to left by using the Backspace/Delete key on a placeholder', async () => { + element = await fixtureElement({ + props: { + precision: Precisions.Hour, + }, + }); + + editableSegments = getEditableSegments(element); + expectPlaceholders(editableSegments); + + const dayPeriod = editableSegments.getByType( + SegmentTypes.DayPeriod + ); + await sendMouse({ + type: 'click', + position: getElementCenter(dayPeriod), + }); + + expect(document.activeElement === element).to.be.true; + expect(element.shadowRoot.activeElement === dayPeriod).to.be.true; + + await sendKeys({ press: 'Backspace' }); + + const hourSegment = editableSegments.getByType(SegmentTypes.Hour); + expect(element.shadowRoot.activeElement === hourSegment).to.be.true; + + await sendKeys({ press: 'Backspace' }); + + const yearSegment = editableSegments.getByType(SegmentTypes.Year); + expect(element.shadowRoot.activeElement === yearSegment).to.be.true; + + await sendKeys({ press: 'Delete' }); + + const daySegment = editableSegments.getByType(SegmentTypes.Day); + expect(element.shadowRoot.activeElement === daySegment).to.be.true; + + await sendKeys({ press: 'Delete' }); + + const monthSegment = editableSegments.getByType(SegmentTypes.Month); + expect(element.shadowRoot.activeElement === monthSegment).to.be + .true; + + await sendKeys({ press: 'Delete' }); + expect(element.shadowRoot.activeElement === monthSegment).to.be + .true; + }); + + it("should change focus up to the calendar button by using the 'Tab' key", async () => { + element.focus(); + const dayPeriodSegment = editableSegments.getByType( + SegmentTypes.DayPeriod + ); + const calendarButton = element.shadowRoot!.querySelector( + 'sp-picker-button' + ) as PickerButton; + + await sendKeyMultipleTimes('Tab', editableSegments.length - 1); + + expect(element.shadowRoot.activeElement === dayPeriodSegment).to.be + .true; + + await sendKeys({ press: 'Tab' }); + + expect(element.shadowRoot.activeElement === calendarButton).to.be + .true; + }); }); describe('ArrowUp key', () => { @@ -2857,7 +3005,6 @@ describe('DateTimePicker', () => { inputSpy.resetHistory(); await sendKeys({ press: 'Delete' }); - await sendKeys({ press: 'Delete' }); await elementUpdated(element); expect(inputSpy.callCount).to.equal(0); @@ -2890,7 +3037,6 @@ describe('DateTimePicker', () => { inputSpy.resetHistory(); await sendKeys({ press: 'Delete' }); - await sendKeys({ press: 'Delete' }); await elementUpdated(element); expect(inputSpy.callCount).to.equal(0); diff --git a/packages/date-time-picker/test/helpers.ts b/packages/date-time-picker/test/helpers.ts index 1f05fdb2de..242fd5b1f5 100644 --- a/packages/date-time-picker/test/helpers.ts +++ b/packages/date-time-picker/test/helpers.ts @@ -136,3 +136,11 @@ export async function openCalendar(element: DateTimePicker): Promise { await sendKeys({ press: 'Enter' }); await opened; } + +export function getElementCenter(element: HTMLElement): [number, number] { + const rect = element.getBoundingClientRect(); + return [ + Math.round(rect.left + rect.width / 2), + Math.round(rect.top + rect.height / 2), + ]; +} From 61a92ccc5f0cfb7ca07ad1ee0ed2af40c6449080 Mon Sep 17 00:00:00 2001 From: Mizga Ionut-Alexandru Date: Tue, 26 Nov 2024 16:32:58 +0200 Subject: [PATCH 05/16] fix(date-time-picker): focus trap on calendar open --- packages/date-time-picker/src/DateTimePicker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/date-time-picker/src/DateTimePicker.ts b/packages/date-time-picker/src/DateTimePicker.ts index bbd75374ce..3c4c57b123 100644 --- a/packages/date-time-picker/src/DateTimePicker.ts +++ b/packages/date-time-picker/src/DateTimePicker.ts @@ -421,9 +421,9 @@ export class DateTimePicker extends ManageHelpText( (this.isCalendarOpen = false)} > From 18dd5d240e4f5888a2721340befa6726f9b8cfe7 Mon Sep 17 00:00:00 2001 From: Mizga Ionut-Alexandru Date: Tue, 26 Nov 2024 16:33:42 +0200 Subject: [PATCH 06/16] feat(date-time-picker): change segments focus on empty delete --- .../date-time-picker/src/DateTimePicker.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/date-time-picker/src/DateTimePicker.ts b/packages/date-time-picker/src/DateTimePicker.ts index 3c4c57b123..ac336ca28a 100644 --- a/packages/date-time-picker/src/DateTimePicker.ts +++ b/packages/date-time-picker/src/DateTimePicker.ts @@ -560,8 +560,10 @@ export class DateTimePicker extends ManageHelpText( } private handleKeydown(event: KeyboardEvent): void { - const segmentType = (event.target as HTMLElement).dataset - .type as EditableSegmentType; + const segmentElement = event.target as HTMLElement; + if (!segmentElement) return; + const segmentType = segmentElement.dataset.type as EditableSegmentType; + if (!segmentType) return; switch (event.code) { case 'ArrowUp': { @@ -573,15 +575,11 @@ export class DateTimePicker extends ManageHelpText( break; } case 'ArrowRight': { - const segment = event.target; - if (!segment) return; - this.focusSegment(segment as HTMLElement, 'next'); + this.focusSegment(segmentElement, 'next'); break; } case 'ArrowLeft': { - const segment = event.target; - if (!segment) return; - this.focusSegment(segment as HTMLElement, 'previous'); + this.focusSegment(segmentElement, 'previous'); break; } case 'Enter': @@ -592,7 +590,9 @@ export class DateTimePicker extends ManageHelpText( case 'Backspace': case 'Delete': { event.preventDefault(); - this.clearSegmentContent(segmentType); + if (this.segments.getByType(segmentType)?.value === undefined) + this.focusSegment(segmentElement, 'previous'); + else this.clearSegmentContent(segmentType); break; } } From 99ccde1bb23b08b472af1baf4ab563833fe87372 Mon Sep 17 00:00:00 2001 From: Mizga Ionut-Alexandru Date: Tue, 26 Nov 2024 17:08:21 +0200 Subject: [PATCH 07/16] test(date-time-picker): created expectFocused helper --- .../test/date-time-picker.test.ts | 91 +++++++----- packages/date-time-picker/test/helpers.ts | 129 ++++++++++++------ 2 files changed, 143 insertions(+), 77 deletions(-) diff --git a/packages/date-time-picker/test/date-time-picker.test.ts b/packages/date-time-picker/test/date-time-picker.test.ts index e6519305b3..48e5281f1c 100644 --- a/packages/date-time-picker/test/date-time-picker.test.ts +++ b/packages/date-time-picker/test/date-time-picker.test.ts @@ -40,6 +40,7 @@ import { testForLitDevWarnings } from '../../../test/testing-helpers.js'; import { dispatchCalendarChange, type EditableSegments, + expectFocused, expectPlaceholder, expectPlaceholders, expectSameDates, @@ -909,8 +910,8 @@ describe('DateTimePicker', () => { }); await sendKeys({ press: 'ArrowUp' }); - expect(document.activeElement === element).to.be.true; - expect(element.shadowRoot.activeElement === yearSegment).to.be.true; + expectFocused(document, element, 'element not focused'); + expectFocused(element.shadowRoot, yearSegment, 'year not focused'); expect(yearSegment.innerText).to.equal(`${fixedYear}`); const daySegment = editableSegments.getByType(SegmentTypes.Day); @@ -921,19 +922,16 @@ describe('DateTimePicker', () => { }); await sendKeys({ press: 'ArrowUp' }); - expect(document.activeElement === element).to.be.true; - expect(element.shadowRoot.activeElement === daySegment).to.be.true; + expectFocused(document, element, 'element not focused'); + expectFocused(element.shadowRoot, daySegment, 'day not focused'); expect(daySegment.innerText).to.equal('01'); }); it('should focus the first editable segment when the focus method is called', async () => { element.focus(); - expect(document.activeElement === element).to.be.true; - expect( - element.shadowRoot.activeElement === - element.firstEditableSegment - ).to.be.true; + expectFocused(document, element, 'element not focused'); + expectFocused(element.shadowRoot, element.firstEditableSegment); }); it("should change segment focus to right by using the 'Right Arrow' key", async () => { @@ -951,13 +949,15 @@ describe('DateTimePicker', () => { editableSegments.length - 1 ); - expect(element.shadowRoot.activeElement === dayPeriodSegment).to.be - .true; + expectFocused(element.shadowRoot, dayPeriodSegment); await sendKeys({ press: 'ArrowRight' }); - expect(element.shadowRoot.activeElement === dayPeriodSegment).to.be - .true; + expectFocused( + element.shadowRoot, + dayPeriodSegment, + 'dayPeriod no longer focused' + ); }); it("should change segment focus to left by using the 'Left Arrow' key", async () => { @@ -974,26 +974,27 @@ describe('DateTimePicker', () => { position: getElementCenter(dayPeriodSegment), }); - expect(document.activeElement === element).to.be.true; - expect(element.shadowRoot.activeElement === dayPeriodSegment).to.be - .true; + expectFocused(document, element, 'element not focused'); + expectFocused( + element.shadowRoot, + dayPeriodSegment, + 'dayPeriod not focused' + ); await sendKeyMultipleTimes( 'ArrowLeft', editableSegments.length - 1 ); - expect( - element.shadowRoot.activeElement === - element.firstEditableSegment - ).to.be.true; + expectFocused(element.shadowRoot, element.firstEditableSegment); await sendKeys({ press: 'ArrowLeft' }); - expect( - element.shadowRoot.activeElement === - element.firstEditableSegment - ).to.be.true; + expectFocused( + element.shadowRoot, + element.firstEditableSegment, + 'firstEditableSegment no longer focused' + ); }); it('should change segment focus to left by using the Backspace/Delete key on a placeholder', async () => { @@ -1014,33 +1015,43 @@ describe('DateTimePicker', () => { position: getElementCenter(dayPeriod), }); - expect(document.activeElement === element).to.be.true; - expect(element.shadowRoot.activeElement === dayPeriod).to.be.true; + expectFocused(document, element, 'element not focused'); + expectFocused( + element.shadowRoot, + dayPeriod, + 'dayPeriod not focused' + ); await sendKeys({ press: 'Backspace' }); const hourSegment = editableSegments.getByType(SegmentTypes.Hour); - expect(element.shadowRoot.activeElement === hourSegment).to.be.true; + expectFocused(element.shadowRoot, hourSegment, 'hour not focused'); await sendKeys({ press: 'Backspace' }); const yearSegment = editableSegments.getByType(SegmentTypes.Year); - expect(element.shadowRoot.activeElement === yearSegment).to.be.true; + expectFocused(element.shadowRoot, yearSegment, 'year not focused'); await sendKeys({ press: 'Delete' }); const daySegment = editableSegments.getByType(SegmentTypes.Day); - expect(element.shadowRoot.activeElement === daySegment).to.be.true; + expectFocused(element.shadowRoot, daySegment, 'day not focused'); await sendKeys({ press: 'Delete' }); const monthSegment = editableSegments.getByType(SegmentTypes.Month); - expect(element.shadowRoot.activeElement === monthSegment).to.be - .true; + expectFocused( + element.shadowRoot, + monthSegment, + 'month not focused' + ); await sendKeys({ press: 'Delete' }); - expect(element.shadowRoot.activeElement === monthSegment).to.be - .true; + expectFocused( + element.shadowRoot, + monthSegment, + 'month not focused' + ); }); it("should change focus up to the calendar button by using the 'Tab' key", async () => { @@ -1054,13 +1065,19 @@ describe('DateTimePicker', () => { await sendKeyMultipleTimes('Tab', editableSegments.length - 1); - expect(element.shadowRoot.activeElement === dayPeriodSegment).to.be - .true; + expectFocused( + element.shadowRoot, + dayPeriodSegment, + 'dayPeriod not focused' + ); await sendKeys({ press: 'Tab' }); - expect(element.shadowRoot.activeElement === calendarButton).to.be - .true; + expectFocused( + element.shadowRoot, + calendarButton, + 'calendarButton not focused' + ); }); }); diff --git a/packages/date-time-picker/test/helpers.ts b/packages/date-time-picker/test/helpers.ts index 242fd5b1f5..eda7794c3e 100644 --- a/packages/date-time-picker/test/helpers.ts +++ b/packages/date-time-picker/test/helpers.ts @@ -56,6 +56,11 @@ export async function fixtureElement({ return el; } +/** + * Returns an array of all editable segments in the DateTimePicker + * with a `getByType` method to find a segment by type. + * @param element - The DateTimePicker to get the segments from + */ export function getEditableSegments(element: DateTimePicker): EditableSegments { const elements = Array.from( element.shadowRoot.querySelectorAll('.editable-segment') @@ -71,29 +76,11 @@ export function getEditableSegments(element: DateTimePicker): EditableSegments { return elements as EditableSegments; } -export function expectPlaceholders( - editableSegments: EditableSegments, - exceptions: HTMLElement[] = [] -): void { - for (const segment of editableSegments.filter( - (segment) => !exceptions.includes(segment) - )) - expectPlaceholder(segment); -} - -export function expectPlaceholder(segment: HTMLElement): void { - expect(isPlaceholderSegment(segment)).to.be.true; -} - -function isPlaceholderSegment(segment: HTMLElement): boolean { - const type = segment.dataset.type as EditableSegmentType; - const placeholder = SegmentPlaceholders[type]; - - if (segment.innerText !== placeholder) return false; - - return true; -} - +/** + * Returns a promise that resolves when the key has been sent for the given number of times. + * @param key - The key to send + * @param times - The number of times to send the key + */ export function sendKeyMultipleTimes( key: string, times: number @@ -103,14 +90,22 @@ export function sendKeyMultipleTimes( ); } -export function expectSameDates( - a: DateValue, - b: DateValue, - message?: string -): void { - expect(isSameDay(a, b), message).to.be.true; +export async function openCalendar(element: DateTimePicker): Promise { + const calendarButton = element.shadowRoot!.querySelector( + 'sp-picker-button' + ) as HTMLElement; + + const opened = oneEvent(element, 'sp-opened'); + calendarButton.focus(); + await sendKeys({ press: 'Enter' }); + await opened; } +/** + * Simulates a date selection in the Calendar by dispatching a change event with the given date. + * @param element - The DateTimePicker with the Calendar to dispatch the event on + * @param date - The date to set the Calendar to + */ export async function dispatchCalendarChange( element: DateTimePicker, date: DateValue @@ -126,17 +121,11 @@ export async function dispatchCalendarChange( await elementUpdated(element); } -export async function openCalendar(element: DateTimePicker): Promise { - const calendarButton = element.shadowRoot!.querySelector( - 'sp-picker-button' - ) as HTMLElement; - - const opened = oneEvent(element, 'sp-opened'); - calendarButton.focus(); - await sendKeys({ press: 'Enter' }); - await opened; -} - +/** + * Returns the x and y coordinates of the center of the given element, rounded to the nearest integer. + * @param element - The element to get the center of + * @returns - The x and y coordinates of the center of the element + */ export function getElementCenter(element: HTMLElement): [number, number] { const rect = element.getBoundingClientRect(); return [ @@ -144,3 +133,63 @@ export function getElementCenter(element: HTMLElement): [number, number] { Math.round(rect.top + rect.height / 2), ]; } + +/** + * Asserts that the given editable segments have only placeholders. + * @param editableSegments - The segments to check + * @param exceptions - Segments that are allowed to have content + */ +export function expectPlaceholders( + editableSegments: EditableSegments, + exceptions: HTMLElement[] = [] +): void { + for (const segment of editableSegments.filter( + (segment) => !exceptions.includes(segment) + )) + expectPlaceholder(segment); +} + +/** + * Asserts that the given segment is a placeholder and does not have a value. + * @param segment - The segment to check + */ +export function expectPlaceholder(segment: HTMLElement): void { + expect(isPlaceholderSegment(segment)).to.be.true; +} + +function isPlaceholderSegment(segment: HTMLElement): boolean { + const type = segment.dataset.type as EditableSegmentType; + const placeholder = SegmentPlaceholders[type]; + + if (segment.innerText !== placeholder) return false; + + return true; +} + +/** + * Asserts that the given date values are the same day. + * @param a - The first date value + * @param b - The second date value + * @param message - The message to display if the assertion fails + */ +export function expectSameDates( + a: DateValue, + b: DateValue, + message?: string +): void { + expect(isSameDay(a, b), message).to.be.true; +} + +/** + * Asserts that the given element is focused. + * @param rootEl - The document or shadow root to check the active element of + * @param focusedEl - The element that should be focused + * @param message - The message to display if the assertion fails + */ +export function expectFocused( + rootEl: Document | ShadowRoot, + focusedEl: HTMLElement, + message?: string +): void { + expect(rootEl.activeElement === focusedEl, message).to.be.true; +} From ed7fb302138e1248d66e1b36e7afa66f6f5fccd2 Mon Sep 17 00:00:00 2001 From: Mizga Ionut-Alexandru Date: Tue, 26 Nov 2024 17:36:11 +0200 Subject: [PATCH 08/16] test(date-time-picker): added disabled tests --- .../test/date-time-picker.test.ts | 60 +++++++++++++++---- packages/date-time-picker/test/helpers.ts | 11 ++++ 2 files changed, 60 insertions(+), 11 deletions(-) diff --git a/packages/date-time-picker/test/date-time-picker.test.ts b/packages/date-time-picker/test/date-time-picker.test.ts index 48e5281f1c..d51b8c2f13 100644 --- a/packages/date-time-picker/test/date-time-picker.test.ts +++ b/packages/date-time-picker/test/date-time-picker.test.ts @@ -47,6 +47,7 @@ import { fixtureElement, getEditableSegments, getElementCenter, + isCalendarOpen, openCalendar, sendKeyMultipleTimes, } from './helpers.js'; @@ -588,7 +589,7 @@ describe('DateTimePicker', () => { describe('Calendar', () => { it('should have the calendar closed by default', () => { - expect(element['isCalendarOpen']).to.be.false; + expect(isCalendarOpen(element)).to.be.false; }); it('should open and close the calendar using the keyboard', async () => { @@ -601,13 +602,13 @@ describe('DateTimePicker', () => { await sendKeys({ press: 'Enter' }); await opened; - expect(element['isCalendarOpen']).to.be.true; + expect(isCalendarOpen(element)).to.be.true; const closed = oneEvent(element, 'sp-closed'); await sendKeys({ press: 'Escape' }); await closed; - expect(element['isCalendarOpen']).to.be.false; + expect(isCalendarOpen(element)).to.be.false; }); it('should open and close the calendar using the pointer', async () => { @@ -622,7 +623,7 @@ describe('DateTimePicker', () => { }); await opened; - expect(element['isCalendarOpen']).to.be.true; + expect(isCalendarOpen(element)).to.be.true; const closed = oneEvent(element, 'sp-closed'); await sendMouse({ @@ -631,7 +632,7 @@ describe('DateTimePicker', () => { }); await closed; - expect(element['isCalendarOpen']).to.be.false; + expect(isCalendarOpen(element)).to.be.false; }); it('should pass the value and min/max constraints to the calendar', async () => { @@ -663,7 +664,7 @@ describe('DateTimePicker', () => { describe('change event', () => { it('should close the calendar when handling its change event', async () => { await openCalendar(element); - expect(element['isCalendarOpen']).to.be.true; + expect(isCalendarOpen(element)).to.be.true; const closed = oneEvent(element, 'sp-closed'); await dispatchCalendarChange( @@ -672,7 +673,7 @@ describe('DateTimePicker', () => { ); await closed; - expect(element['isCalendarOpen']).to.be.false; + expect(isCalendarOpen(element)).to.be.false; }); it('should update the value as CalendarDate when its the most specific date value', async () => { @@ -929,6 +930,7 @@ describe('DateTimePicker', () => { it('should focus the first editable segment when the focus method is called', async () => { element.focus(); + await elementUpdated(element); expectFocused(document, element, 'element not focused'); expectFocused(element.shadowRoot, element.firstEditableSegment); @@ -944,6 +946,7 @@ describe('DateTimePicker', () => { ); element.focus(); + await elementUpdated(element); await sendKeyMultipleTimes( 'ArrowRight', editableSegments.length - 1 @@ -1056,6 +1059,7 @@ describe('DateTimePicker', () => { it("should change focus up to the calendar button by using the 'Tab' key", async () => { element.focus(); + await elementUpdated(element); const dayPeriodSegment = editableSegments.getByType( SegmentTypes.DayPeriod ); @@ -4391,10 +4395,44 @@ describe('DateTimePicker', () => { }); describe('Disabled', () => { - it('should not accept focus'); - it('should not accept typed in values'); - it('should not accept arrow key inputs'); - it('should not open the calendar'); + beforeEach(async () => { + element = await fixtureElement({ props: { disabled: true } }); + editableSegments = getEditableSegments(element); + }); + + it('should not accept focus', async () => { + element.focus(); + await elementUpdated(element); + expect(document.activeElement === element).to.be.false; + + const yearSegment = editableSegments.getByType(SegmentTypes.Year); + yearSegment.focus(); + + expect(document.activeElement === element).to.be.false; + + const monthSegment = editableSegments.getByType(SegmentTypes.Month); + await sendMouse({ + type: 'click', + position: getElementCenter(monthSegment), + }); + await sendKeys({ press: 'Tab' }); + await sendKeys({ press: 'Shift+Tab' }); + + expect(document.activeElement === element).to.be.false; + }); + + it('should not open the calendar', async () => { + const calendarButton = element.shadowRoot!.querySelector( + 'sp-picker-button' + ) as PickerButton; + + await sendMouse({ + type: 'click', + position: getElementCenter(calendarButton), + }); + + expect(isCalendarOpen(element)).to.be.false; + }); }); describe('Localization', () => { diff --git a/packages/date-time-picker/test/helpers.ts b/packages/date-time-picker/test/helpers.ts index eda7794c3e..0ba2b52f2d 100644 --- a/packages/date-time-picker/test/helpers.ts +++ b/packages/date-time-picker/test/helpers.ts @@ -24,6 +24,7 @@ import { SegmentPlaceholders, } from '@spectrum-web-components/date-time-picker'; import '@spectrum-web-components/date-time-picker/sp-date-time-picker.js'; +import { Overlay } from '@spectrum-web-components/overlay/src/Overlay.js'; import '@spectrum-web-components/theme/sp-theme.js'; import { sendKeys } from '@web/test-runner-commands'; import { spreadProps } from '../../../test/lit-helpers.js'; @@ -193,3 +194,13 @@ export function expectFocused( ): void { expect(rootEl.activeElement === focusedEl, message).to.be.true; } + +/** + * @param element - The DateTimePicker to check + * @returns Whether the Calendar is open + */ +export function isCalendarOpen(element: DateTimePicker): boolean { + const calendar = element.shadowRoot.querySelector('sp-calendar'); + const calendarOverlay = calendar?.closest('sp-overlay') as Overlay; + return calendarOverlay.open; +} From 7f48f0f09f39786c4fe41f998594e47d53d3e1e6 Mon Sep 17 00:00:00 2001 From: Mizga Ionut-Alexandru Date: Thu, 28 Nov 2024 09:54:17 +0200 Subject: [PATCH 09/16] test(calendar): added disabled and localized tests --- packages/calendar/stories/calendar.stories.ts | 20 +++++- packages/calendar/test/calendar.test.ts | 68 +++++++++++++------ packages/calendar/test/helpers.ts | 24 +++++++ packages/date-time-picker/test/helpers.ts | 12 ++-- 4 files changed, 95 insertions(+), 29 deletions(-) diff --git a/packages/calendar/stories/calendar.stories.ts b/packages/calendar/stories/calendar.stories.ts index b58b90b5ce..bdca5e1b67 100644 --- a/packages/calendar/stories/calendar.stories.ts +++ b/packages/calendar/stories/calendar.stories.ts @@ -9,11 +9,12 @@ the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTA OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ +import { CalendarDate, DateValue } from '@internationalized/date'; import { html, type TemplateResult } from '@spectrum-web-components/base'; +import '@spectrum-web-components/calendar/sp-calendar.js'; +import '@spectrum-web-components/theme/sp-theme.js'; import { spreadProps } from '../../../test/lit-helpers.js'; import { CalendarValue } from '../src/types.js'; -import { CalendarDate, DateValue } from '@internationalized/date'; -import '@spectrum-web-components/calendar/sp-calendar.js'; type ComponentArgs = { value?: CalendarValue; @@ -119,6 +120,10 @@ const Template = (args: StoryArgs = {}): TemplateResult => { }; export const Default = (args: StoryArgs): TemplateResult => Template(args); +Default.swc_vrt = { + // Needed because the style on the current day will cause the snapshot to fail every day it runs + skip: true, +}; export const disabled = (args: StoryArgs): TemplateResult => Template(args); disabled.args = { @@ -173,3 +178,14 @@ export const minAndMaxDates = (args: StoryArgs): TemplateResult => { `; }; minAndMaxDates.argTypes = dateControlsDisabledArgTypes; + +export const bengaliIndiaLocale = (args: StoryArgs): TemplateResult => { + return html` + + + + `; +}; diff --git a/packages/calendar/test/calendar.test.ts b/packages/calendar/test/calendar.test.ts index 676c42f2b6..0de3c6c473 100644 --- a/packages/calendar/test/calendar.test.ts +++ b/packages/calendar/test/calendar.test.ts @@ -28,6 +28,7 @@ import { testForLitDevWarnings } from '../../../test/testing-helpers.js'; import { expectSameDates, fixtureElement, + getElementCenter, sendKeyMultipleTimes, } from './helpers.js'; @@ -498,13 +499,9 @@ describe('Calendar', () => { await sendKeys({ press: 'Enter' }); await elementUpdated(element); - const rect = unavailableDayElement.getBoundingClientRect(); - const centerX = Math.round(rect.left + rect.width / 2); - const centerY = Math.round(rect.top + rect.height / 2); - await sendMouse({ type: 'click', - position: [centerX, centerY], + position: getElementCenter(unavailableDayElement), }); await elementUpdated(element); @@ -652,13 +649,9 @@ describe('Calendar', () => { }); it('should update value when an available day is clicked', async () => { - const rect = availableDayElement.getBoundingClientRect(); - const centerX = Math.round(rect.left + rect.width / 2); - const centerY = Math.round(rect.top + rect.height / 2); - await sendMouse({ type: 'click', - position: [centerX, centerY], + position: getElementCenter(availableDayElement), }); await elementUpdated(element); @@ -701,13 +694,9 @@ describe('Calendar', () => { }); it("should dispatch 'change' when an available day is selected by clicking", async () => { - const rect = availableDayElement.getBoundingClientRect(); - const centerX = Math.round(rect.left + rect.width / 2); - const centerY = Math.round(rect.top + rect.height / 2); - await sendMouse({ type: 'click', - position: [centerX, centerY], + position: getElementCenter(availableDayElement), }); await elementUpdated(element); @@ -716,7 +705,7 @@ describe('Calendar', () => { changeSpy.resetHistory(); await sendMouse({ type: 'click', - position: [centerX, centerY], + position: getElementCenter(availableDayElement), }); await elementUpdated(element); expect(changeSpy.callCount).to.equal(0); @@ -797,9 +786,48 @@ describe('Calendar', () => { }); describe('Disabled', () => { - it('should disable the next and previous month buttons'); - it("should not focus the calendar's days"); - it("should not select a day when it's clicked"); + beforeEach(async () => { + element = await fixtureElement({ props: { disabled: true } }); + }); + + it('should disable the next and previous month buttons', () => { + const nextButton = element.shadowRoot.querySelector( + NEXT_BUTTON_SELECTOR + ) as ActionButton; + const prevButton = element.shadowRoot.querySelector( + PREV_BUTTON_SELECTOR + ) as ActionButton; + + expect(nextButton.disabled).to.be.true; + expect(prevButton.disabled).to.be.true; + }); + + it('should not have focusable days', () => { + const focusableDay = element.shadowRoot.querySelector( + "td.tableCell[tabindex='0']" + ) as HTMLElement; + + expect(focusableDay).to.be.null; + }); + + it("should not select a day when it's clicked", async () => { + const availableDateToSelect = new CalendarDate( + fixedYear, + fixedMonth, + fixedDay + 1 + ); + const availableDayElement = element.shadowRoot.querySelector( + `[data-value='${availableDateToSelect.toString()}']` + ) as HTMLElement; + + await sendMouse({ + type: 'click', + position: getElementCenter(availableDayElement), + }); + await elementUpdated(element); + + expect(element.value).to.be.undefined; + }); }); describe('Gregorian AD era limits', () => { @@ -903,6 +931,4 @@ describe('Calendar', () => { expectSameDates(element['currentDate'], lastDate); }); }); - - describe('Localized', () => {}); }); diff --git a/packages/calendar/test/helpers.ts b/packages/calendar/test/helpers.ts index 77b2f4fe02..0b0b6c5c82 100644 --- a/packages/calendar/test/helpers.ts +++ b/packages/calendar/test/helpers.ts @@ -39,6 +39,24 @@ export async function fixtureElement({ return el; } +/** + * Computes the x and y coordinates of the center of the given element, rounded to the nearest integer. + * @param element - The element to get the center of + * @returns - The x and y coordinates of the center of the element + */ +export function getElementCenter(element: HTMLElement): [number, number] { + const rect = element.getBoundingClientRect(); + return [ + Math.round(rect.left + rect.width / 2), + Math.round(rect.top + rect.height / 2), + ]; +} + +/** + * Sends the specified key the given number of times. + * @param key - The key to send + * @param times - The number of times to send the key + */ export function sendKeyMultipleTimes( key: string, times: number @@ -48,6 +66,12 @@ export function sendKeyMultipleTimes( ); } +/** + * Asserts that the given date values are the same day. + * @param a - The first date value + * @param b - The second date value + * @param message - The message to display if the assertion fails + */ export function expectSameDates( a: DateValue, b: DateValue, diff --git a/packages/date-time-picker/test/helpers.ts b/packages/date-time-picker/test/helpers.ts index 0ba2b52f2d..d089ce3ac0 100644 --- a/packages/date-time-picker/test/helpers.ts +++ b/packages/date-time-picker/test/helpers.ts @@ -78,7 +78,7 @@ export function getEditableSegments(element: DateTimePicker): EditableSegments { } /** - * Returns a promise that resolves when the key has been sent for the given number of times. + * Sends the specified key the given number of times. * @param key - The key to send * @param times - The number of times to send the key */ @@ -91,6 +91,10 @@ export function sendKeyMultipleTimes( ); } +/** + * Opens the Calendar by focusing the Calendar button and pressing Enter. + * @param element - The DateTimePicker with the Calendar to open + */ export async function openCalendar(element: DateTimePicker): Promise { const calendarButton = element.shadowRoot!.querySelector( 'sp-picker-button' @@ -123,7 +127,7 @@ export async function dispatchCalendarChange( } /** - * Returns the x and y coordinates of the center of the given element, rounded to the nearest integer. + * Computes the x and y coordinates of the center of the given element, rounded to the nearest integer. * @param element - The element to get the center of * @returns - The x and y coordinates of the center of the element */ @@ -195,10 +199,6 @@ export function expectFocused( expect(rootEl.activeElement === focusedEl, message).to.be.true; } -/** - * @param element - The DateTimePicker to check - * @returns Whether the Calendar is open - */ export function isCalendarOpen(element: DateTimePicker): boolean { const calendar = element.shadowRoot.querySelector('sp-calendar'); const calendarOverlay = calendar?.closest('sp-overlay') as Overlay; From e15fff7a719493ef62e538f4d1f8e741ba51f5b7 Mon Sep 17 00:00:00 2001 From: Mizga Ionut-Alexandru Date: Thu, 28 Nov 2024 10:16:31 +0200 Subject: [PATCH 10/16] docs: allow value overrides in storybook --- packages/calendar/stories/calendar.stories.ts | 83 ++++++-------- .../stories/date-time-picker.stories.ts | 103 ++++++++---------- 2 files changed, 82 insertions(+), 104 deletions(-) diff --git a/packages/calendar/stories/calendar.stories.ts b/packages/calendar/stories/calendar.stories.ts index bdca5e1b67..0d9c96c5c6 100644 --- a/packages/calendar/stories/calendar.stories.ts +++ b/packages/calendar/stories/calendar.stories.ts @@ -10,11 +10,14 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ import { CalendarDate, DateValue } from '@internationalized/date'; + import { html, type TemplateResult } from '@spectrum-web-components/base'; +import { CalendarValue } from '@spectrum-web-components/calendar'; + +import { spreadProps } from '../../../test/lit-helpers.js'; + import '@spectrum-web-components/calendar/sp-calendar.js'; import '@spectrum-web-components/theme/sp-theme.js'; -import { spreadProps } from '../../../test/lit-helpers.js'; -import { CalendarValue } from '../src/types.js'; type ComponentArgs = { value?: CalendarValue; @@ -72,48 +75,36 @@ export default { }, }; -const dateControlsDisabledArgTypes = { - min: { - table: { - disable: true, - }, - }, - max: { - table: { - disable: true, - }, - }, - value: { - table: { - disable: true, - }, - }, -}; - -const timestampToValue = (timestamp: number): CalendarValue => { - const date = new Date(); - date.setTime(timestamp); - return new CalendarDate( - date.getFullYear(), - date.getMonth() + 1, // Date months are 0-indexed while CalendarDate months are 1-indexed - date.getDate() - ); +const computeProps = (args: StoryArgs): ComponentArgs => { + const timestampToValue = (timestamp: number): CalendarValue => { + const date = new Date(); + date.setTime(timestamp); + return new CalendarDate( + date.getFullYear(), + date.getMonth() + 1, // Date months are 0-indexed while CalendarDate months are 1-indexed + date.getDate() + ); + }; + + return { + value: args.value + ? timestampToValue(args.value as unknown as number) + : undefined, + min: args.min + ? timestampToValue(args.min as unknown as number) + : undefined, + max: args.max + ? timestampToValue(args.max as unknown as number) + : undefined, + padded: args.padded, + disabled: args.disabled, + }; }; const Template = (args: StoryArgs = {}): TemplateResult => { - args.value = args.value - ? timestampToValue(args.value as unknown as number) - : undefined; - args.min = args.min - ? timestampToValue(args.min as unknown as number) - : undefined; - args.max = args.max - ? timestampToValue(args.max as unknown as number) - : undefined; - return html` `; @@ -138,53 +129,49 @@ padded.args = { export const preselectedValue = (args: StoryArgs): TemplateResult => { return html` `; }; -preselectedValue.argTypes = dateControlsDisabledArgTypes; export const minDate = (args: StoryArgs): TemplateResult => { return html` `; }; -minDate.argTypes = dateControlsDisabledArgTypes; export const maxDate = (args: StoryArgs): TemplateResult => { return html` `; }; -maxDate.argTypes = dateControlsDisabledArgTypes; export const minAndMaxDates = (args: StoryArgs): TemplateResult => { return html` `; }; -minAndMaxDates.argTypes = dateControlsDisabledArgTypes; export const bengaliIndiaLocale = (args: StoryArgs): TemplateResult => { return html` `; diff --git a/packages/date-time-picker/stories/date-time-picker.stories.ts b/packages/date-time-picker/stories/date-time-picker.stories.ts index f5bd99fff8..ffb890a24d 100644 --- a/packages/date-time-picker/stories/date-time-picker.stories.ts +++ b/packages/date-time-picker/stories/date-time-picker.stories.ts @@ -12,15 +12,16 @@ governing permissions and limitations under the License. import { CalendarDate, CalendarDateTime, + DateValue, toZoned, } from '@internationalized/date'; + import { css, html, TemplateResult, unsafeCSS, } from '@spectrum-web-components/base'; -import { DateValue } from '@spectrum-web-components/calendar'; import { DateTimePickerValue, Precision, @@ -115,35 +116,45 @@ const storyMeta = { }, }; -const timestampToValue = (timestamp: number): DateValue => { - const date = new Date(); - date.setTime(timestamp); - return new CalendarDateTime( - date.getFullYear(), - date.getMonth() + 1, // Date months are 0-indexed while CalendarDate months are 1-indexed - date.getDate(), - date.getHours(), - date.getMinutes(), - date.getSeconds() - ); +const computeProps = (args: StoryArgs): ComponentArgs => { + const timestampToValue = (timestamp: number): DateValue => { + const date = new Date(); + date.setTime(timestamp); + return new CalendarDateTime( + date.getFullYear(), + date.getMonth() + 1, // Date months are 0-indexed while CalendarDate months are 1-indexed + date.getDate(), + date.getHours(), + date.getMinutes(), + date.getSeconds() + ); + }; + + return { + value: args.value + ? timestampToValue(args.value as unknown as number) + : undefined, + min: args.min + ? timestampToValue(args.min as unknown as number) + : undefined, + max: args.max + ? timestampToValue(args.max as unknown as number) + : undefined, + disabled: args.disabled, + readonly: args.readonly, + quiet: args.quiet, + invalid: args.invalid, + autofocus: args.autofocus, + precision: args.precision, + }; }; const Template = (args: StoryArgs = {}): TemplateResult => { - args.value = args.value - ? timestampToValue(args.value as unknown as number) - : undefined; - args.min = args.min - ? timestampToValue(args.min as unknown as number) - : undefined; - args.max = args.max - ? timestampToValue(args.max as unknown as number) - : undefined; - return html` `; }; @@ -175,84 +186,65 @@ autofocus.args = { autofocus: true, }; -const dateControlsDisabledArgTypes = { - min: { - table: { - disable: true, - }, - }, - max: { - table: { - disable: true, - }, - }, - value: { - table: { - disable: true, - }, - }, -}; - export const preselectedValue = (args: StoryArgs): TemplateResult => { return html` `; }; -preselectedValue.argTypes = dateControlsDisabledArgTypes; export const minDate = (args: StoryArgs): TemplateResult => { return html` `; }; -minDate.argTypes = dateControlsDisabledArgTypes; export const maxDate = (args: StoryArgs): TemplateResult => { return html` `; }; -maxDate.argTypes = dateControlsDisabledArgTypes; export const minAndMaxDates = (args: StoryArgs): TemplateResult => { return html` `; }; -minAndMaxDates.argTypes = dateControlsDisabledArgTypes; export const secondPrecision = (args: StoryArgs): TemplateResult => { return html` `; }; export const helpText = (args: StoryArgs): TemplateResult => { return html` - + Please select your birthday @@ -263,9 +255,9 @@ export const helpText = (args: StoryArgs): TemplateResult => { export const negativeHelpText = (args: StoryArgs): TemplateResult => { return html` Change state to invalid to see the negative help text @@ -276,11 +268,10 @@ export const negativeHelpText = (args: StoryArgs): TemplateResult => { `; }; -negativeHelpText.argTypes = dateControlsDisabledArgTypes; -export const customIcon = (): TemplateResult => { +export const customIcon = (args: StoryArgs): TemplateResult => { return html` - + `; @@ -303,7 +294,7 @@ export const customWidth = (args: StoryArgs): TemplateResult[] => {
`; From 3006c66c43e27a2f08c3339f98e24d0390878e22 Mon Sep 17 00:00:00 2001 From: Mizga Ionut-Alexandru Date: Thu, 28 Nov 2024 11:16:29 +0200 Subject: [PATCH 11/16] test(calendar): added clear method test --- packages/calendar/test/calendar.test.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/calendar/test/calendar.test.ts b/packages/calendar/test/calendar.test.ts index 0de3c6c473..c6613d82fb 100644 --- a/packages/calendar/test/calendar.test.ts +++ b/packages/calendar/test/calendar.test.ts @@ -673,6 +673,19 @@ describe('Calendar', () => { expectSameDates(element.value!, availableDateToSelect); }); + + it('should clear the selected value when the clear method is called', async () => { + await sendMouse({ + type: 'click', + position: getElementCenter(availableDayElement), + }); + await elementUpdated(element); + + element.clear(); + await elementUpdated(element); + + expect(element.value).to.be.undefined; + }); }); describe('Dispatched change', () => { From 50bb8807ea0cd60b111c6643e27f9a85fe165754 Mon Sep 17 00:00:00 2001 From: Mizga Ionut-Alexandru Date: Thu, 28 Nov 2024 11:26:17 +0200 Subject: [PATCH 12/16] test(date-time-picker): added calendar close when disabled changes test --- packages/date-time-picker/src/DateTimePicker.ts | 7 ++----- .../date-time-picker/test/date-time-picker.test.ts | 10 ++++++++++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/packages/date-time-picker/src/DateTimePicker.ts b/packages/date-time-picker/src/DateTimePicker.ts index ac336ca28a..8f9cdd2ac3 100644 --- a/packages/date-time-picker/src/DateTimePicker.ts +++ b/packages/date-time-picker/src/DateTimePicker.ts @@ -497,7 +497,7 @@ export class DateTimePicker extends ManageHelpText( ${segment.formatted ?? ''} + >${segment.formatted} `; } @@ -561,7 +561,6 @@ export class DateTimePicker extends ManageHelpText( private handleKeydown(event: KeyboardEvent): void { const segmentElement = event.target as HTMLElement; - if (!segmentElement) return; const segmentType = segmentElement.dataset.type as EditableSegmentType; if (!segmentType) return; @@ -732,12 +731,10 @@ export class DateTimePicker extends ManageHelpText( segment: EditableSegment, segmentElement: HTMLElement ): void { - const content = + segmentElement.innerText = segment.value !== undefined ? segment.formatted : segment.placeholder; - - segmentElement.innerText = content ?? ''; } private dispatchChange(): void { diff --git a/packages/date-time-picker/test/date-time-picker.test.ts b/packages/date-time-picker/test/date-time-picker.test.ts index d51b8c2f13..1e48ce8fb1 100644 --- a/packages/date-time-picker/test/date-time-picker.test.ts +++ b/packages/date-time-picker/test/date-time-picker.test.ts @@ -661,6 +661,16 @@ describe('DateTimePicker', () => { ); }); + it("should close the calendar when the component gets disabled and it's open", async () => { + await openCalendar(element); + expect(isCalendarOpen(element)).to.be.true; + + element.disabled = true; + await elementUpdated(element); + + expect(isCalendarOpen(element)).to.be.false; + }); + describe('change event', () => { it('should close the calendar when handling its change event', async () => { await openCalendar(element); From e3c759f94d13faae7537cbaef478e9fdaaf649f1 Mon Sep 17 00:00:00 2001 From: Mizga Ionut-Alexandru Date: Thu, 28 Nov 2024 11:53:38 +0200 Subject: [PATCH 13/16] chore: organize imports --- packages/calendar/src/Calendar.ts | 13 ++++++------ packages/calendar/test/calendar.test.ts | 5 ++++- .../date-time-picker/src/DateTimePicker.ts | 20 ++++++++++--------- .../src/segments/SegmentsFactory.ts | 1 - .../test/date-time-picker.test.ts | 16 ++++++++------- 5 files changed, 31 insertions(+), 24 deletions(-) diff --git a/packages/calendar/src/Calendar.ts b/packages/calendar/src/Calendar.ts index 1487de1612..4e5cc85340 100644 --- a/packages/calendar/src/Calendar.ts +++ b/packages/calendar/src/Calendar.ts @@ -24,6 +24,7 @@ import { today, } from '@internationalized/date'; import { NumberFormatter } from '@internationalized/number'; + import { CSSResultArray, html, @@ -45,6 +46,12 @@ import { languageResolverUpdatedSymbol, } from '@spectrum-web-components/reactive-controllers/src/LanguageResolution.js'; +import styles from './calendar.css.js'; + +import '@spectrum-web-components/action-button/sp-action-button.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-chevron-left.js'; +import '@spectrum-web-components/icons-workflow/icons/sp-icon-chevron-right.js'; + import { CalendarValue, CalendarWeekday, @@ -52,12 +59,6 @@ import { DateValue, } from './types.js'; -import styles from './calendar.css.js'; - -import '@spectrum-web-components/action-button/sp-action-button.js'; -import '@spectrum-web-components/icons-workflow/icons/sp-icon-chevron-left.js'; -import '@spectrum-web-components/icons-workflow/icons/sp-icon-chevron-right.js'; - export const DAYS_PER_WEEK = 7; /** * @element sp-calendar diff --git a/packages/calendar/test/calendar.test.ts b/packages/calendar/test/calendar.test.ts index c6613d82fb..219997118c 100644 --- a/packages/calendar/test/calendar.test.ts +++ b/packages/calendar/test/calendar.test.ts @@ -17,11 +17,14 @@ import { parseDate, today, } from '@internationalized/date'; -import { elementUpdated, expect, fixture, html } from '@open-wc/testing'; + import { ActionButton } from '@spectrum-web-components/action-button'; import { Calendar, DAYS_PER_WEEK } from '@spectrum-web-components/calendar'; + import '@spectrum-web-components/calendar/sp-calendar.js'; import '@spectrum-web-components/theme/sp-theme.js'; + +import { elementUpdated, expect, fixture, html } from '@open-wc/testing'; import { sendKeys, sendMouse } from '@web/test-runner-commands'; import { spy, stub } from 'sinon'; import { testForLitDevWarnings } from '../../../test/testing-helpers.js'; diff --git a/packages/date-time-picker/src/DateTimePicker.ts b/packages/date-time-picker/src/DateTimePicker.ts index 8f9cdd2ac3..7e6966ccd1 100644 --- a/packages/date-time-picker/src/DateTimePicker.ts +++ b/packages/date-time-picker/src/DateTimePicker.ts @@ -23,6 +23,7 @@ import { ZonedDateTime, } from '@internationalized/date'; import { NumberParser } from '@internationalized/number'; + import { CSSResultArray, html, @@ -53,13 +54,6 @@ import { import { Focusable } from '@spectrum-web-components/shared/src/focusable.js'; import styles from './date-time-picker.css.js'; -import { - DateTimePickerValue, - EditableSegmentType, - Precision, - Precisions, - SegmentTypes, -} from './types.js'; // TODO: Load dependencies lazily when possible import '@spectrum-web-components/calendar/sp-calendar.js'; @@ -69,6 +63,7 @@ import '@spectrum-web-components/icons-workflow/icons/sp-icon-calendar.js'; import '@spectrum-web-components/overlay/sp-overlay.js'; import '@spectrum-web-components/picker-button/sp-picker-button.js'; import '@spectrum-web-components/popover/sp-popover.js'; + import { equalSegmentValues, isCalendarDate, @@ -84,6 +79,13 @@ import { DecrementModifier } from './segments/modifiers/DecrementModifier.js'; import { IncrementModifier } from './segments/modifiers/IncrementModifier.js'; import { InputModifier } from './segments/modifiers/InputModifier.js'; import { type SegmentsModifierParams } from './segments/modifiers/SegmentsModifier.js'; +import { + DateTimePickerValue, + EditableSegmentType, + Precision, + Precisions, + SegmentTypes, +} from './types.js'; /** * @element sp-date-time-picker @@ -197,7 +199,7 @@ export class DateTimePicker extends ManageHelpText( } /** - * Returns whether the component's precision includes time segments (hour, minute, second) + * @return Whether the component's precision includes time segments (hour, minute, second) */ private get includesTime(): boolean { const timePrecisions = [ @@ -260,7 +262,7 @@ export class DateTimePicker extends ManageHelpText( } /** - * Returns the component's most precise date property (min, max or value) or undefined if none is defined. + * Computes the component's most precise date property (min, max or value) or undefined if none is defined. * The order of precedence is: ZonedDateTime, CalendarDateTime, CalendarDate. */ private get mostSpecificDateValue(): DateValue | undefined { diff --git a/packages/date-time-picker/src/segments/SegmentsFactory.ts b/packages/date-time-picker/src/segments/SegmentsFactory.ts index 4e2e619bfe..d95433a16f 100644 --- a/packages/date-time-picker/src/segments/SegmentsFactory.ts +++ b/packages/date-time-picker/src/segments/SegmentsFactory.ts @@ -10,7 +10,6 @@ OF ANY KIND, either express or implied. See the License for the specific languag governing permissions and limitations under the License. */ -// import { ZonedDateTime } from '@internationalized/date'; import { DateFormatter, ZonedDateTime } from '@internationalized/date'; import { NumberFormatter } from '@internationalized/number'; import { SegmentType, SegmentTypes } from '../types'; diff --git a/packages/date-time-picker/test/date-time-picker.test.ts b/packages/date-time-picker/test/date-time-picker.test.ts index 1e48ce8fb1..1888296d07 100644 --- a/packages/date-time-picker/test/date-time-picker.test.ts +++ b/packages/date-time-picker/test/date-time-picker.test.ts @@ -18,13 +18,7 @@ import { ZonedDateTime, } from '@internationalized/date'; import { NumberFormatter } from '@internationalized/number'; -import { - elementUpdated, - expect, - fixture, - html, - oneEvent, -} from '@open-wc/testing'; + import { Calendar } from '@spectrum-web-components/calendar'; import { DateTimePicker, @@ -34,6 +28,14 @@ import { SegmentTypes, } from '@spectrum-web-components/date-time-picker'; import { PickerButton } from '@spectrum-web-components/picker-button'; + +import { + elementUpdated, + expect, + fixture, + html, + oneEvent, +} from '@open-wc/testing'; import { sendKeys, sendMouse } from '@web/test-runner-commands'; import { spy, stub } from 'sinon'; import { testForLitDevWarnings } from '../../../test/testing-helpers.js'; From 0804a8832f367b5fbc12d79626d04693cc021f05 Mon Sep 17 00:00:00 2001 From: Mizga Ionut-Alexandru Date: Thu, 28 Nov 2024 12:08:42 +0200 Subject: [PATCH 14/16] chore: build --- yarn.lock | 159 ------------------------------------------------------ 1 file changed, 159 deletions(-) diff --git a/yarn.lock b/yarn.lock index 290538b0e7..7233c96bb0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5365,168 +5365,9 @@ resolved "https://registry.yarnpkg.com/@spectrum-css/vars/-/vars-9.0.8.tgz#6af3bcdace903b8461f5fcd4c9aa23e70128a456" integrity sha512-rGfd7jqXOdR69bEjrRP58ynuIeJU0czPfwQvzhtCzg7jKVukV+efNHqrs086sC6xutB3W4TF71K/dZMr3oyTyg== -"@spectrum-web-components/action-button@^0.47.2": - version "0.47.2" - resolved "https://registry.yarnpkg.com/@spectrum-web-components/action-button/-/action-button-0.47.2.tgz#8db417bfbb4d9e77b7d7ff6a6ad311764c93f7e8" - integrity sha512-29hiRHxokHzVMqAjX8QeR3iP5MVjJXxPp7AG9x4Sz7yidGeXCHbItdkA/8ADpDVoULEUxQoyp5alqBl5b8ZrMQ== - dependencies: - "@spectrum-web-components/base" "^0.47.2" - "@spectrum-web-components/button" "^0.47.2" - "@spectrum-web-components/icon" "^0.47.2" - "@spectrum-web-components/icons-ui" "^0.47.2" - "@spectrum-web-components/shared" "^0.47.2" - -"@spectrum-web-components/base@^0.47.2": - version "0.47.2" - resolved "https://registry.yarnpkg.com/@spectrum-web-components/base/-/base-0.47.2.tgz#83ce0fbd6a5f29757445224f56f34eb85860ca31" - integrity sha512-jWktMJUfFIFkV0Q/rC6kx/O4zuTLKSubuPk2dRlucilBxGCUzBFOtdQLYnr4B7nYkukNvBdBloVr2be0bRT0jg== - dependencies: - lit "^2.5.0 || ^3.1.3" - -"@spectrum-web-components/button@^0.47.2": - version "0.47.2" - resolved "https://registry.yarnpkg.com/@spectrum-web-components/button/-/button-0.47.2.tgz#cebf73bbc7edcff68d7966bd3fb52dc011186206" - integrity sha512-y0IV0zaPTC4z24RYaZcXy8apzXWIjKQm9aPQdYmeHWwwT/8PDEC83hSbaQXQcVLXpeQJZCPXYNTX5d/5j4a0cg== - dependencies: - "@spectrum-web-components/base" "^0.47.2" - "@spectrum-web-components/clear-button" "^0.47.2" - "@spectrum-web-components/close-button" "^0.47.2" - "@spectrum-web-components/icon" "^0.47.2" - "@spectrum-web-components/icons-ui" "^0.47.2" - "@spectrum-web-components/progress-circle" "^0.47.2" - "@spectrum-web-components/shared" "^0.47.2" - -"@spectrum-web-components/clear-button@^0.47.2": - version "0.47.2" - resolved "https://registry.yarnpkg.com/@spectrum-web-components/clear-button/-/clear-button-0.47.2.tgz#60aa43d8fc1b5b0c9ba79391a233785febde5efc" - integrity sha512-Yhf8aRmHtXnlGM6eUFdq4eoi/P4zuI3NVA8uQLA8m99waYv9/TdKvDe2QSuwI4GyFcKnUTBnvmq3Rs6rrw/YcA== - dependencies: - "@spectrum-web-components/base" "^0.47.2" - -"@spectrum-web-components/close-button@^0.47.2": - version "0.47.2" - resolved "https://registry.yarnpkg.com/@spectrum-web-components/close-button/-/close-button-0.47.2.tgz#dfcba19d0d7d40dc277d20f672a6eac85cc7fc91" - integrity sha512-EbaxJmK+RqYPZ3wk46urj9bptUX5UvusVWcWaVV6rTI5x+tvcIIJYaCIo2faBijEqteGN1q+HDGgi09448WCNA== - dependencies: - "@spectrum-web-components/base" "^0.47.2" - "@spectrum-web-components/eslint-plugin@file:./linters/eslint": version "0.49.0" -"@spectrum-web-components/field-label@^0.47.2": - version "0.47.2" - resolved "https://registry.yarnpkg.com/@spectrum-web-components/field-label/-/field-label-0.47.2.tgz#52c8b6c85fa03c9fdd7a1ecbbf5b391137afa734" - integrity sha512-oosf4eQ+oisrzO08rB9HR+7zpsqV1EjfUSLLfIPbfe59wY69DzKMidZcHVIR3TzrTs5HnW3JTbXRqycgBCMSug== - dependencies: - "@spectrum-web-components/base" "^0.47.2" - "@spectrum-web-components/icon" "^0.47.2" - "@spectrum-web-components/icons-ui" "^0.47.2" - "@spectrum-web-components/reactive-controllers" "^0.47.2" - "@spectrum-web-components/shared" "^0.47.2" - -"@spectrum-web-components/icon@^0.47.2": - version "0.47.2" - resolved "https://registry.yarnpkg.com/@spectrum-web-components/icon/-/icon-0.47.2.tgz#24ab873ecf3a48f5d5f93e5e59362bd75cd5ff9a" - integrity sha512-BSgFtfHhvmfjdEG7ANzG7YpwiRttefRfgeYsa/8xK9QuH7Mu1MA8BPhDlHIIqaMq9/8CaYY6JxhAJxnlvnlxpA== - dependencies: - "@spectrum-web-components/base" "^0.47.2" - "@spectrum-web-components/iconset" "^0.47.2" - -"@spectrum-web-components/icons-ui@^0.47.2": - version "0.47.2" - resolved "https://registry.yarnpkg.com/@spectrum-web-components/icons-ui/-/icons-ui-0.47.2.tgz#cb38e173327da890daa87132a44016a4ebacb260" - integrity sha512-LOKUGU/Es6gMq5+/1ci7azVSVv76hqlmap/Vg+vxrFygr+Ne7g0D6jd4ICz7i5/WCYG7j5wvgS7Xs5l0epUxGg== - dependencies: - "@spectrum-web-components/base" "^0.47.2" - "@spectrum-web-components/icon" "^0.47.2" - "@spectrum-web-components/iconset" "^0.47.2" - -"@spectrum-web-components/icons-workflow@^0.47.2": - version "0.47.2" - resolved "https://registry.yarnpkg.com/@spectrum-web-components/icons-workflow/-/icons-workflow-0.47.2.tgz#77b6132478182ab7aea790c2db9cfb086966af17" - integrity sha512-jpGcKKHcXrLf7HarBoV/iXYBfT7K8HYgFsYM/qSN0IynsaLMkplGX1bubRCnfACYszTzEXGw2+9yCpzblknG5Q== - dependencies: - "@spectrum-web-components/base" "^0.47.2" - "@spectrum-web-components/icon" "^0.47.2" - -"@spectrum-web-components/iconset@^0.47.2": - version "0.47.2" - resolved "https://registry.yarnpkg.com/@spectrum-web-components/iconset/-/iconset-0.47.2.tgz#a4b438f3d37dc303bcb8eb8182ba6d265548295d" - integrity sha512-fLYj5Xb1rhpCqOgLsR4d776F48i2zW0s0j2L78pMKVDqipmFI4rQqX+Zgg7n4nhfTzzYZH1K6mr8/xQvjVd7Fg== - dependencies: - "@spectrum-web-components/base" "^0.47.2" - -"@spectrum-web-components/overlay@^0.47.2": - version "0.47.2" - resolved "https://registry.yarnpkg.com/@spectrum-web-components/overlay/-/overlay-0.47.2.tgz#357a35c79fb3936af81ecc84d106d3a0ce79e3d7" - integrity sha512-JSwgRfWOblCC2UB5/QaLvBD0peNJOp4ZVKG8mBHHsdC0U4Pudk67pzbNcJPq77MuoSKvG/MF5JIaUfxnQ7XbPg== - dependencies: - "@floating-ui/dom" "^1.6.1" - "@floating-ui/utils" "^0.2.1" - "@spectrum-web-components/action-button" "^0.47.2" - "@spectrum-web-components/base" "^0.47.2" - "@spectrum-web-components/reactive-controllers" "^0.47.2" - "@spectrum-web-components/shared" "^0.47.2" - "@spectrum-web-components/theme" "^0.47.2" - -"@spectrum-web-components/picker-button@^0.47.2": - version "0.47.2" - resolved "https://registry.yarnpkg.com/@spectrum-web-components/picker-button/-/picker-button-0.47.2.tgz#30e1b3f448567f60aa0e7efa67ec39f034071064" - integrity sha512-jzoUW5xbyk5EnHON6gjAZMkYFZ9Du5vezGmfozAOgENXQDV/pcNr3z40Hd2U321zYJaUr3ya98rt76kUuot7+g== - dependencies: - "@spectrum-web-components/base" "^0.47.2" - "@spectrum-web-components/button" "^0.47.2" - "@spectrum-web-components/icon" "^0.47.2" - "@spectrum-web-components/icons-ui" "^0.47.2" - "@spectrum-web-components/shared" "^0.47.2" - -"@spectrum-web-components/popover@^0.47.2": - version "0.47.2" - resolved "https://registry.yarnpkg.com/@spectrum-web-components/popover/-/popover-0.47.2.tgz#691530d3edf659cada6a72d02e87c5ee890922af" - integrity sha512-dHxK8rje6NoA0FEDl06vcA/HNpn+le8Qk6l2YFJx+mg0Zup4fYHYPHNXVJMeSEKPBnVr8J8LLg9TXxb8Ukk2aw== - dependencies: - "@spectrum-web-components/base" "^0.47.2" - "@spectrum-web-components/overlay" "^0.47.2" - -"@spectrum-web-components/progress-circle@^0.47.2": - version "0.47.2" - resolved "https://registry.yarnpkg.com/@spectrum-web-components/progress-circle/-/progress-circle-0.47.2.tgz#b41446fdb8af91b18b007069886a9ef60e960f25" - integrity sha512-sp5yv7Bt0kTs9Vpip31MKlnJTdfi4A1xOyyjz+haXAVWXSIBp7q+y2/KXLP5sToaTDGRzFOx9c8X7ZNt/OHOTA== - dependencies: - "@spectrum-web-components/base" "^0.47.2" - "@spectrum-web-components/shared" "^0.47.2" - -"@spectrum-web-components/reactive-controllers@^0.47.2": - version "0.47.2" - resolved "https://registry.yarnpkg.com/@spectrum-web-components/reactive-controllers/-/reactive-controllers-0.47.2.tgz#87eebd9d08b769bfaee2347823087f74ff41fe38" - integrity sha512-rJ6tWx7LNWmz1vjup3ozzcR+XowIu8HBuD5KiwkHsYuTFA1pK/2iIMaJl4FMNsG2X6EUM2U114atasy01pnJbA== - dependencies: - lit "^3.1.3" - -"@spectrum-web-components/shared@^0.47.2": - version "0.47.2" - resolved "https://registry.yarnpkg.com/@spectrum-web-components/shared/-/shared-0.47.2.tgz#b535954898209f35b5cf2454f1168938eb1094e4" - integrity sha512-S7WU7AS+iw4p9TUZgl2JF/KEB5c2FfjNloYdTPP+4kRC0HiZ57Wj7vSPrL4a7Kt8ucIwHqzm23GwaTcwQckMXQ== - dependencies: - "@lit-labs/observers" "^2.0.2" - "@spectrum-web-components/base" "^0.47.2" - focus-visible "^5.1.0" - -"@spectrum-web-components/styles@^0.47.2": - version "0.47.2" - resolved "https://registry.yarnpkg.com/@spectrum-web-components/styles/-/styles-0.47.2.tgz#cf6d6cd3fb67711470f77160dd8f82099f68bd1b" - integrity sha512-l3b9srYFQlwKWXTZ9DPDPcVqu2fQVQEdP0flzaLXm0zn5lIpWz0VIzNphV3jFsTFXsZcjZzwFsLWGFzfz6geJw== - dependencies: - "@spectrum-web-components/base" "^0.47.2" - -"@spectrum-web-components/theme@^0.47.2": - version "0.47.2" - resolved "https://registry.yarnpkg.com/@spectrum-web-components/theme/-/theme-0.47.2.tgz#1e82db4dcd6f9601fa3082e64e1dbe15f711f3ed" - integrity sha512-bK+sTtHLxakgDNI3yV0R6lnVTjR3rpa09y+8Wq6qX4+xFOVxWHw+1RP6/3M1JxUM7SK0Qw8jhUR7aIiZ36tR6A== - dependencies: - "@spectrum-web-components/base" "^0.47.2" - "@spectrum-web-components/styles" "^0.47.2" - "@storybook/addon-a11y@^7.5.0": version "7.6.19" resolved "https://registry.yarnpkg.com/@storybook/addon-a11y/-/addon-a11y-7.6.19.tgz#8b684edfb3a387d24398e81517dc734f0b76a1db" From 7171e15b59061e3e7f20059d0c3237daab32aef7 Mon Sep 17 00:00:00 2001 From: Mizga Ionut-Alexandru Date: Thu, 28 Nov 2024 12:25:08 +0200 Subject: [PATCH 15/16] fix(date-time-picker): mobile text inputMode on dayPeriod segment --- packages/date-time-picker/src/DateTimePicker.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/date-time-picker/src/DateTimePicker.ts b/packages/date-time-picker/src/DateTimePicker.ts index 7e6966ccd1..9566826691 100644 --- a/packages/date-time-picker/src/DateTimePicker.ts +++ b/packages/date-time-picker/src/DateTimePicker.ts @@ -506,6 +506,8 @@ export class DateTimePicker extends ManageHelpText( public renderEditableSegment(segment: EditableSegment): TemplateResult { const isActive = !this.disabled && !this.readonly; const usePlaceholder = segment.value === undefined; + const inputMode = + segment.type === SegmentTypes.DayPeriod ? 'text' : 'numeric'; const segmentClasses: ClassInfo = { 'editable-segment': true, @@ -540,7 +542,7 @@ export class DateTimePicker extends ManageHelpText(
Date: Wed, 4 Dec 2024 10:09:16 +0200 Subject: [PATCH 16/16] chore: golden img hash update --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ba726b2ebf..7f27a8f823 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -10,7 +10,7 @@ executors: parameters: current_golden_images_hash: type: string - default: 6212f1e2821ec631ba02ddd3784d9c8c03cf6b9a + default: e5761b668fbcb5a97e8f5b297c91b4e2e72c35bd wireit_cache_name: type: string default: wireit