Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 1 addition & 9 deletions packages/main/cypress/specs/DateTimePicker.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -343,15 +343,7 @@ describe("DateTimePicker general interaction", () => {
.ui5DateTimePickerClose();
});

// Skipped: this test has been failing intermittently on CI for weeks.
// The "Unstable test, needs investigation" note below has been there from before.
// Root cause appears to be a focus race in TimeSelectionClocks._activateClock,
// which waits for `animationend` to advance focus between hours/minutes/seconds.
// When animations are disabled (as this test does via setAnimationMode(None)),
// `animationend` never fires, so the next clock button never becomes focused.
// Skipping until the underlying component is fixed.
//Unstable test, needs investigation
it.skip("tests selection of 12:34:56 AM", () => {
it("tests selection of 12:34:56 AM", () => {
setAnimationMode(AnimationMode.None);

cy.mount(<DateTimePickerTemplate formatPattern="dd/MM/yyyy, hh:mm:ss a" value="13/04/2020, 03:16:16 AM" />);
Expand Down
10 changes: 8 additions & 2 deletions packages/main/src/Calendar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import CalendarDate from "./CalendarDate.js";
import CalendarDateRange from "./CalendarDateRange.js";
import "./SpecialCalendarDate.js";
import CalendarPart from "./CalendarPart.js";
import type { DayPickerChangeEventDetail } from "./DayPicker.js";
import type { DayPickerChangeEventDetail, DayPickerNavigateEventDetail } from "./DayPicker.js";
import type { MonthPickerChangeEventDetail } from "./MonthPicker.js";
import type { YearPickerChangeEventDetail } from "./YearPicker.js";
import CalendarSelectionMode from "./types/CalendarSelectionMode.js";
Expand Down Expand Up @@ -918,8 +918,14 @@ class Calendar extends CalendarPart {
this.switchToYearPicker();
}

async onNavigate(e: CustomEvent) {
async onNavigate(e: CustomEvent<DayPickerNavigateEventDetail>) {
this.timestamp = e.detail.timestamp;
// Mouse-driven navigation handles its own focus; the click already landed
// where the user wants. Refocusing after the deferred render would steal
// focus from a sibling component (e.g. a time picker in DateTimePicker).
if (e.detail.mouse) {
return;
}
await renderFinished();
this._currentPickerDOM.focus();
}
Expand Down
3 changes: 2 additions & 1 deletion packages/main/src/DayPicker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ type DayPickerChangeEventDetail = {

type DayPickerNavigateEventDetail = {
timestamp: number,
mouse?: boolean,
}

/**
Expand Down Expand Up @@ -612,7 +613,7 @@ class DayPicker extends CalendarPart implements ICalendarPicker {
}

this._safelySetTimestamp(this._getTimestampFromDom(target));
this.fireDecoratorEvent("navigate", { timestamp: this.timestamp! });
this.fireDecoratorEvent("navigate", { timestamp: this.timestamp!, mouse: true });
}

/**
Expand Down
14 changes: 10 additions & 4 deletions packages/main/src/TimeSelectionClocks.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js";
import property from "@ui5/webcomponents-base/dist/decorators/property.js";
import event from "@ui5/webcomponents-base/dist/decorators/event-strict.js";
import AnimationMode from "@ui5/webcomponents-base/dist/types/AnimationMode.js";
import { getAnimationMode } from "@ui5/webcomponents-base/dist/config/AnimationMode.js";
import "@ui5/webcomponents-localization/dist/features/calendar/Gregorian.js"; // default calendar for bundling
import {
isDown,
Expand Down Expand Up @@ -416,6 +418,10 @@ class TimeSelectionClocks extends TimePickerInternals {
return;
}

if (getAnimationMode() === AnimationMode.None) {
skipAnimation = true;
}

const currentClockComponent = this._clockComponent(this._activeIndex);
const newClockComponent = this._clockComponent(clockIndex);

Expand All @@ -428,7 +434,7 @@ class TimeSelectionClocks extends TimePickerInternals {
newClockComponent._skipAnimation = true;
this._activateClock(clockIndex);
} else {
currentClockComponent?._firstNumberElement?.addEventListener("animationend", () => this._activateClock(clockIndex), { once: true });
currentClockComponent?._firstNumberElement?.addEventListener("animationend", () => { this._activateClock(clockIndex); }, { once: true });
currentClockComponent?._clockWrapper?.classList.add("ui5-tp-clock-transition");
}
}
Expand All @@ -438,12 +444,12 @@ class TimeSelectionClocks extends TimePickerInternals {
* @param clockIndex the index of the clock to be activated
*/
_activateClock(clockIndex: number) {
const newButton = this._buttonComponent(clockIndex);

this._entities[this._activeIndex].active = false;
this._activeIndex = clockIndex;
this._entities[this._activeIndex].active = true;
newButton && newButton.focus();

const newButton = this._buttonComponent(clockIndex);
newButton?.getFocusDomRef()?.focus();
}

/**
Expand Down
Loading