Skip to content

Commit b082fcf

Browse files
authored
fix(ui5-carousel): navigateTo method no longer moves the focus (#12920)
1 parent 09471a1 commit b082fcf

4 files changed

Lines changed: 329 additions & 17 deletions

File tree

packages/main/cypress/specs/Carousel.cy.tsx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,4 +702,32 @@ describe("Carousel general interaction", () => {
702702
.find(".ui5-carousel-navigation-dot")
703703
.should("have.length", 3);
704704
});
705+
706+
it("navigateTo method should NOT move the focus", () => {
707+
cy.mount(
708+
<>
709+
<Button id="outsideButton">Outside Button</Button>
710+
<Carousel id="carousel">
711+
<div>item 1</div>
712+
<div>item 2</div>
713+
<div>item 3</div>
714+
</Carousel>
715+
</>
716+
);
717+
718+
cy.get("#outsideButton").realClick();
719+
cy.get("#outsideButton").should("be.focused");
720+
721+
cy.get<Carousel>("#carousel")
722+
.then($carousel => {
723+
$carousel[0].navigateTo(2);
724+
});
725+
726+
cy.get("#carousel")
727+
.shadow()
728+
.find(".ui5-carousel-item[aria-posinset='3'][data-sap-focus-ref]")
729+
.should("exist")
730+
731+
cy.get("#outsideButton").should("be.focused");
732+
});
705733
});

packages/main/src/Carousel.ts

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -550,24 +550,32 @@ class Carousel extends UI5Element {
550550
return this.content.every(item => observableContentSet.has(item));
551551
}
552552

553-
_handleHome(e: KeyboardEvent) {
553+
async _handleHome(e: KeyboardEvent) {
554554
e.preventDefault();
555555
this.navigateTo(0);
556+
await renderFinished();
557+
this.focusItem();
556558
}
557559

558-
_handleEnd(e: KeyboardEvent) {
560+
async _handleEnd(e: KeyboardEvent) {
559561
e.preventDefault();
560562
this.navigateTo(this.items.length - 1);
563+
await renderFinished();
564+
this.focusItem();
561565
}
562566

563-
_handlePageUp(e: KeyboardEvent) {
567+
async _handlePageUp(e: KeyboardEvent) {
564568
e.preventDefault();
565569
this.navigateTo(this._focusedItemIndex + this._pageStep < this.items.length ? this._focusedItemIndex + this._pageStep : this.items.length - 1);
570+
await renderFinished();
571+
this.focusItem();
566572
}
567573

568-
_handlePageDown(e: KeyboardEvent) {
574+
async _handlePageDown(e: KeyboardEvent) {
569575
e.preventDefault();
570576
this.navigateTo(this._focusedItemIndex - this._pageStep > 0 ? this._focusedItemIndex - this._pageStep : 0);
577+
await renderFinished();
578+
this.focusItem();
571579
}
572580

573581
get _backgroundDesign() {
@@ -586,7 +594,7 @@ class Carousel extends UI5Element {
586594
return this._focusedItemIndex;
587595
}
588596

589-
navigateLeft() {
597+
async navigateLeft() {
590598
this._resizing = false;
591599

592600
const previousSelectedIndex = this._focusedItemIndex;
@@ -605,11 +613,13 @@ class Carousel extends UI5Element {
605613

606614
if (previousSelectedIndex !== this._focusedItemIndex) {
607615
this.skipToItem(this._focusedItemIndex, -1);
616+
await renderFinished();
617+
this.focusItem();
608618
this.fireDecoratorEvent("navigate", { selectedIndex: this._focusedItemIndex });
609619
}
610620
}
611621

612-
navigateRight() {
622+
async navigateRight() {
613623
this._resizing = false;
614624

615625
const previousSelectedIndex = this._focusedItemIndex;
@@ -630,27 +640,33 @@ class Carousel extends UI5Element {
630640

631641
if (previousSelectedIndex !== this._focusedItemIndex) {
632642
this.skipToItem(this._focusedItemIndex, 1);
643+
await renderFinished();
644+
this.focusItem();
633645
this.fireDecoratorEvent("navigate", { selectedIndex: this._focusedItemIndex });
634646
}
635647
}
636648

637649
navigateArrowRight() {
638650
if (this._focusedItemIndex === this._visibleItemsIndexes[0]) {
639651
this.navigateTo(this._focusedItemIndex + 1);
652+
this.focusItem();
640653
this._moveToItem(this._currentSlideIndex + 1);
641654
} else {
642655
this._moveToItem(this._currentSlideIndex + 1);
643656
this.navigateTo(this._focusedItemIndex);
657+
this.focusItem();
644658
}
645659
}
646660

647661
navigateArrowLeft() {
648662
if (this._focusedItemIndex > 0 && this._focusedItemIndex === this._visibleItemsIndexes[this._visibleItemsIndexes.length - 1]) {
649663
this.navigateTo(this._focusedItemIndex - 1);
664+
this.focusItem();
650665
this._moveToItem(this._currentSlideIndex - 1);
651666
} else {
652667
this._moveToItem(this._currentSlideIndex === 0 ? this.pagesCount - 1 : this._currentSlideIndex - 1);
653668
this.navigateTo(this._focusedItemIndex === 0 ? this.items.length - 1 : this._focusedItemIndex);
669+
this.focusItem();
654670
}
655671
}
656672

@@ -731,7 +747,7 @@ class Carousel extends UI5Element {
731747

732748
/**
733749
* Changes the currently displayed page.
734-
* @param itemIndex The index of the target page
750+
* @param itemIndex The index of the target item
735751
* @since 1.0.0-rc.15
736752
* @public
737753
*/
@@ -745,26 +761,22 @@ class Carousel extends UI5Element {
745761
}
746762
this._focusedItemIndex = itemIndex;
747763
this._currentSlideIndex = itemIndex - this._itemIndicator;
764+
748765
if (this.isItemInViewport(itemIndex)) {
749766
this._currentSlideIndex = this._visibleItemsIndexes[0];
750-
this.focusItem();
751-
return;
767+
} else {
768+
this.skipToItem(this._focusedItemIndex, 1);
752769
}
753-
this.skipToItem(this._focusedItemIndex, 1);
754770
}
755771

756-
async skipToItem(focusIndex: number, offset: number) {
772+
skipToItem(focusIndex: number, offset: number) {
757773
if (!this.isItemInViewport(focusIndex)) {
758774
let slideIndex = this._calculateItemSlideIndex(this._currentSlideIndex, offset);
759775
if (focusIndex === 0) {
760776
slideIndex = 0;
761777
}
762778
this._moveToItem(slideIndex);
763779
}
764-
765-
await renderFinished();
766-
767-
this.focusItem();
768780
}
769781

770782
/**

packages/main/src/CarouselTemplate.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ export default function CarouselTemplate(this: Carousel) {
2222
>
2323
<div class={this.classes.viewport} part="content">
2424
<div role="list" aria-label={this._ariaListLabel} class={this.classes.content} style={{ transform: `translate3d(${this._isRTL ? "" : "-"}${this._currentSlideIndex * (this._itemWidth || 0)}px, 0, 0` }}>
25-
{this.items.map(itemInfo =>
25+
{this.items.map((itemInfo, i) =>
2626
<div
27-
data-sap-focus-ref
27+
data-sap-focus-ref={this._focusedItemIndex === i ? true : undefined}
2828
id={itemInfo.id}
2929
class={{
3030
"ui5-carousel-item": true,

0 commit comments

Comments
 (0)