diff --git a/packages/main/cypress/specs/Carousel.cy.tsx b/packages/main/cypress/specs/Carousel.cy.tsx index 9e871a96435e..a0141e601106 100644 --- a/packages/main/cypress/specs/Carousel.cy.tsx +++ b/packages/main/cypress/specs/Carousel.cy.tsx @@ -702,4 +702,32 @@ describe("Carousel general interaction", () => { .find(".ui5-carousel-navigation-dot") .should("have.length", 3); }); + + it("navigateTo method should NOT move the focus", () => { + cy.mount( + <> + + +
item 1
+
item 2
+
item 3
+
+ + ); + + cy.get("#outsideButton").realClick(); + cy.get("#outsideButton").should("be.focused"); + + cy.get("#carousel") + .then($carousel => { + $carousel[0].navigateTo(2); + }); + + cy.get("#carousel") + .shadow() + .find(".ui5-carousel-item[aria-posinset='3'][data-sap-focus-ref]") + .should("exist") + + cy.get("#outsideButton").should("be.focused"); + }); }); \ No newline at end of file diff --git a/packages/main/src/Carousel.ts b/packages/main/src/Carousel.ts index cc369f7f78e5..c9a309c69621 100644 --- a/packages/main/src/Carousel.ts +++ b/packages/main/src/Carousel.ts @@ -550,24 +550,32 @@ class Carousel extends UI5Element { return this.content.every(item => observableContentSet.has(item)); } - _handleHome(e: KeyboardEvent) { + async _handleHome(e: KeyboardEvent) { e.preventDefault(); this.navigateTo(0); + await renderFinished(); + this.focusItem(); } - _handleEnd(e: KeyboardEvent) { + async _handleEnd(e: KeyboardEvent) { e.preventDefault(); this.navigateTo(this.items.length - 1); + await renderFinished(); + this.focusItem(); } - _handlePageUp(e: KeyboardEvent) { + async _handlePageUp(e: KeyboardEvent) { e.preventDefault(); this.navigateTo(this._focusedItemIndex + this._pageStep < this.items.length ? this._focusedItemIndex + this._pageStep : this.items.length - 1); + await renderFinished(); + this.focusItem(); } - _handlePageDown(e: KeyboardEvent) { + async _handlePageDown(e: KeyboardEvent) { e.preventDefault(); this.navigateTo(this._focusedItemIndex - this._pageStep > 0 ? this._focusedItemIndex - this._pageStep : 0); + await renderFinished(); + this.focusItem(); } get _backgroundDesign() { @@ -586,7 +594,7 @@ class Carousel extends UI5Element { return this._focusedItemIndex; } - navigateLeft() { + async navigateLeft() { this._resizing = false; const previousSelectedIndex = this._focusedItemIndex; @@ -605,11 +613,13 @@ class Carousel extends UI5Element { if (previousSelectedIndex !== this._focusedItemIndex) { this.skipToItem(this._focusedItemIndex, -1); + await renderFinished(); + this.focusItem(); this.fireDecoratorEvent("navigate", { selectedIndex: this._focusedItemIndex }); } } - navigateRight() { + async navigateRight() { this._resizing = false; const previousSelectedIndex = this._focusedItemIndex; @@ -630,6 +640,8 @@ class Carousel extends UI5Element { if (previousSelectedIndex !== this._focusedItemIndex) { this.skipToItem(this._focusedItemIndex, 1); + await renderFinished(); + this.focusItem(); this.fireDecoratorEvent("navigate", { selectedIndex: this._focusedItemIndex }); } } @@ -637,20 +649,24 @@ class Carousel extends UI5Element { navigateArrowRight() { if (this._focusedItemIndex === this._visibleItemsIndexes[0]) { this.navigateTo(this._focusedItemIndex + 1); + this.focusItem(); this._moveToItem(this._currentSlideIndex + 1); } else { this._moveToItem(this._currentSlideIndex + 1); this.navigateTo(this._focusedItemIndex); + this.focusItem(); } } navigateArrowLeft() { if (this._focusedItemIndex > 0 && this._focusedItemIndex === this._visibleItemsIndexes[this._visibleItemsIndexes.length - 1]) { this.navigateTo(this._focusedItemIndex - 1); + this.focusItem(); this._moveToItem(this._currentSlideIndex - 1); } else { this._moveToItem(this._currentSlideIndex === 0 ? this.pagesCount - 1 : this._currentSlideIndex - 1); this.navigateTo(this._focusedItemIndex === 0 ? this.items.length - 1 : this._focusedItemIndex); + this.focusItem(); } } @@ -731,7 +747,7 @@ class Carousel extends UI5Element { /** * Changes the currently displayed page. - * @param itemIndex The index of the target page + * @param itemIndex The index of the target item * @since 1.0.0-rc.15 * @public */ @@ -745,15 +761,15 @@ class Carousel extends UI5Element { } this._focusedItemIndex = itemIndex; this._currentSlideIndex = itemIndex - this._itemIndicator; + if (this.isItemInViewport(itemIndex)) { this._currentSlideIndex = this._visibleItemsIndexes[0]; - this.focusItem(); - return; + } else { + this.skipToItem(this._focusedItemIndex, 1); } - this.skipToItem(this._focusedItemIndex, 1); } - async skipToItem(focusIndex: number, offset: number) { + skipToItem(focusIndex: number, offset: number) { if (!this.isItemInViewport(focusIndex)) { let slideIndex = this._calculateItemSlideIndex(this._currentSlideIndex, offset); if (focusIndex === 0) { @@ -761,10 +777,6 @@ class Carousel extends UI5Element { } this._moveToItem(slideIndex); } - - await renderFinished(); - - this.focusItem(); } /** diff --git a/packages/main/src/CarouselTemplate.tsx b/packages/main/src/CarouselTemplate.tsx index 5ae041996380..2848830907cd 100644 --- a/packages/main/src/CarouselTemplate.tsx +++ b/packages/main/src/CarouselTemplate.tsx @@ -22,9 +22,9 @@ export default function CarouselTemplate(this: Carousel) { >
- {this.items.map(itemInfo => + {this.items.map((itemInfo, i) =>
+ + + + + + Carousel + + + + + +
+ Navigate the items: + + +
+ + + + + + Template Based Segmentation + Segmentation Models + Marketing plans + + + + + + + + + + Template Based Segmentation + Segmentation Models + + + + + + + Template Based Segmentation + Segmentation Models + + + + + + + Template Based Segmentation + Segmentation Models + Marketing plans + + + + + + + + + + Template Based Segmentation + Segmentation Models + + + + + + + Template Based Segmentation + Segmentation Models + + + + + + + Template Based Segmentation + Segmentation Models + Marketing plans + + + + + + + + + + Template Based Segmentation + Segmentation Models + + + + + + + Template Based Segmentation + Segmentation Models + + + + + + + + Template Based Segmentation + Segmentation Models + + + + + + + Template Based Segmentation + Segmentation Models + + + + + + + + + Template Based Segmentation + Segmentation Models + + + + + + + + Template Based Segmentation + Segmentation Models + + + + + + + + Template Based Segmentation + Segmentation Models + Marketing plans + + + + + + + + + + + Template Based Segmentation + Segmentation Models + + + + + + + + Template Based Segmentation + Segmentation Models + + + + + + + + Template Based Segmentation + Segmentation Models + Marketing plans + + + + + + + + + + + Template Based Segmentation + Segmentation Models + + + + + + + + Template Based Segmentation + Segmentation Models + + + + + + + + + Template Based Segmentation + Segmentation Models + + + + + + + + Template Based Segmentation + Segmentation Models + + + + + + + Event Planning + Team Management + + + + + + + Documentation + Tutorials + + + + + + + + + \ No newline at end of file