Skip to content
Merged
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
116 changes: 116 additions & 0 deletions packages/fiori/cypress/specs/Search.cy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -891,6 +891,122 @@ describe("Events", () => {
.should("not.exist")
});

it("delete event is fired on clicking the delete button of a search item", () => {
cy.mount(
<Search>
<SearchItem text="Item 1" onDelete={cy.spy().as('deleteSpy')} deletable />
</Search>
);

cy.get("[ui5-search]")
.shadow()
.find("input")
.realClick();

cy.get("[ui5-search]")
.realPress("I");

cy.get("[ui5-search]")
.realPress("ArrowDown");

cy.get("[ui5-search-item]").eq(0)
.as("firstSearchItem");

cy.get("@firstSearchItem")
.shadow()
.find("[ui5-button]")
.realClick();

cy.get("@deleteSpy").should("have.been.calledOnce");
});

it("Fast navigation with F2 key press", () => {
cy.mount(
<Search>
<SearchItem text="Item 1" deletable />
</Search>
);

cy.get("[ui5-search]")
.shadow()
.find("input")
.realClick();

cy.get("[ui5-search]")
.realPress("I");

cy.get("[ui5-search]")
.realPress("ArrowDown");

cy.get("[ui5-search-item]").eq(0)
.as("firstSearchItem");

cy.get("@firstSearchItem")
.should("be.focused");

cy.realPress("F2");

cy.get("@firstSearchItem")
.shadow()
.find("[ui5-button]")
.should("be.focused");

cy.realPress("F2");

cy.get("@firstSearchItem")
.should("be.focused");
});

it("delete event is fired on pressing SPACE on the focused delete button of a search item", () => {
cy.mount(
<Search>
<SearchItem text="Item 1" onDelete={cy.spy().as('deleteSpy')} deletable />
</Search>
);

cy.get("[ui5-search]")
.shadow()
.find("input")
.realClick();

cy.get("[ui5-search]")
.realPress("I");

cy.get("[ui5-search]")
.realPress("ArrowDown");

cy.realPress("F2");

cy.realPress("Space");

cy.get("@deleteSpy").should("have.been.calledOnce");
});

it("delete event is fired on pressing ENTER on the focused delete button of a search item", () => {
cy.mount(
<Search>
<SearchItem text="Item 1" onDelete={cy.spy().as('deleteSpy')} deletable />
</Search>
);

cy.get("[ui5-search]")
.shadow()
.find("input")
.realClick();

cy.get("[ui5-search]")
.realPress("I");

cy.get("[ui5-search]")
.realPress("ArrowDown");

cy.realPress("F2");

cy.realPress("Enter");

cy.get("@deleteSpy").should("have.been.calledOnce");
});

it("should deselect items when backspace or delete key is pressed", () => {
cy.mount(
<Search>
Expand Down
37 changes: 37 additions & 0 deletions packages/fiori/src/SearchItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import generateHighlightedMarkup from "@ui5/webcomponents-base/dist/util/generat
import jsxRenderer from "@ui5/webcomponents-base/dist/renderer/JsxRenderer.js";
import event from "@ui5/webcomponents-base/dist/decorators/event-strict.js";
import { SEARCH_ITEM_DELETE_BUTTON } from "./generated/i18n/i18n-defaults.js";
import getActiveElement from "@ui5/webcomponents-base/dist/util/getActiveElement.js";
import { getFirstFocusableElement } from "@ui5/webcomponents-base/dist/util/FocusableElements.js";
import { isSpace, isEnter, isF2 } from "@ui5/webcomponents-base/dist/Keys.js";
import { i18n } from "@ui5/webcomponents-base/dist/decorators.js";
import type I18nBundle from "@ui5/webcomponents-base/dist/i18nBundle.js";
// @ts-expect-error
Expand Down Expand Up @@ -129,10 +132,44 @@ class SearchItem extends ListItemBase {
this.selected = false;
}

async _onkeydown(e: KeyboardEvent) {
super._onkeydown(e);

if (this.getFocusDomRef()!.matches(":has(:focus-within)")) {
if (isSpace(e) || isEnter(e)) {
e.preventDefault();
return;
}
}

if (isF2(e)) {
e.stopImmediatePropagation();
const activeElement = getActiveElement();
const focusDomRef = this.getFocusDomRef();

if (!focusDomRef) {
return;
}

if (activeElement === focusDomRef) {
const firstFocusable = await getFirstFocusableElement(focusDomRef);
firstFocusable?.focus();
} else {
focusDomRef.focus();
}
}
}

_onDeleteButtonClick() {
this.fireDecoratorEvent("delete");
}

_onDeleteButtonKeyDown(e: KeyboardEvent) {
if (isSpace(e) || isEnter(e)) {
this.fireDecoratorEvent("delete");
}
}

onBeforeRendering(): void {
super.onBeforeRendering();

Expand Down
7 changes: 6 additions & 1 deletion packages/fiori/src/SearchItemTemplate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,12 @@ export default function SearchFieldTemplate(this: SearchItem) {
</div>

{this.deletable &&
<Button class="ui5-search-item-selected-delete" design={ButtonDesign.Transparent} icon={decline} onClick={this._onDeleteButtonClick} tooltip={this._deleteButtonTooltip}></Button>
<Button class="ui5-search-item-selected-delete"
design={ButtonDesign.Transparent}
icon={decline}
onClick={this._onDeleteButtonClick}
tooltip={this._deleteButtonTooltip}
onKeyDown={this._onDeleteButtonKeyDown}></Button>
}
</div>
</div>
Expand Down
14 changes: 3 additions & 11 deletions packages/fiori/test/pages/Search.html
Original file line number Diff line number Diff line change
Expand Up @@ -255,15 +255,6 @@
{ name: 'Tomato', category: 'Vegetable' },
];

function createItems(parent, data) {
data.forEach(item => {
const searchItem = document.createElement('ui5-search-item');
searchItem.text = item.name;
searchItem.icon = 'search';
parent.appendChild(searchItem);
});
}

const filtering = document.getElementById('filtering');
createItems(filtering, data);
filtering.addEventListener('ui5-input', (event) => {
Expand Down Expand Up @@ -370,10 +361,11 @@

const searchDelete = document.getElementById('delete-search');

function onDelete(event) {
function onDelete(event, parent) {
const item = event.target;
if (item) {
item.remove();
parent.focus();
}
}

Expand All @@ -392,7 +384,7 @@
searchItem.text = item.name;
searchItem.icon = 'search';
searchItem.deletable = true;
searchItem.addEventListener('ui5-delete', onDelete);
searchItem.addEventListener('ui5-delete', (e) => onDelete(e, parent));
parent.appendChild(searchItem);
});
}
Expand Down
Loading