Skip to content

Commit

Permalink
fix(list, list-item): Fix focus behavior when clicking on an item (#5901
Browse files Browse the repository at this point in the history
)

**Related Issue:** #5899

## Summary

fix(list, list-item): Fix focus behavior when clicking on an item.
  • Loading branch information
driskull committed Dec 6, 2022
1 parent 214e3be commit 552e28f
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 4 deletions.
16 changes: 16 additions & 0 deletions src/components/list-item/list-item.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,20 @@ describe("calcite-list-item", () => {

expect(eventSpy).toHaveReceivedEventTimes(1);
});

it("emits calciteInternalListItemActive on click", async () => {
const page = await newE2EPage({
html: `<calcite-list-item selection-mode="none" label="hello" description="world"></calcite-list-item>`
});

await page.waitForChanges();

const contentContainer = await page.find(`calcite-list-item >>> .${CSS.contentContainer}`);

const eventSpy = await page.spyOnEvent("calciteInternalListItemActive");

await contentContainer.click();

expect(eventSpy).toHaveReceivedEventTimes(1);
});
});
17 changes: 14 additions & 3 deletions src/components/list-item/list-item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,12 @@ export class ListItem implements InteractiveComponent, LoadableComponent {
*/
@Event({ cancelable: false }) calciteInternalListItemSelect: EventEmitter<void>;

/**
*
* @internal
*/
@Event({ cancelable: false }) calciteInternalListItemActive: EventEmitter<void>;

/**
*
* @internal
Expand Down Expand Up @@ -250,7 +256,7 @@ export class ListItem implements InteractiveComponent, LoadableComponent {
}

return (
<td class={CSS.selectionContainer} key="selection-container" onClick={this.toggleSelected}>
<td class={CSS.selectionContainer} key="selection-container" onClick={this.itemClicked}>
<calcite-icon
icon={
selected
Expand All @@ -277,7 +283,7 @@ export class ListItem implements InteractiveComponent, LoadableComponent {
/>
</td>
) : parentListEl?.openable ? (
<td class={CSS.openContainer} key="open-container" onClick={this.toggleSelected}>
<td class={CSS.openContainer} key="open-container" onClick={this.itemClicked}>
<calcite-icon icon={ICONS.blank} scale="s" />
</td>
) : null;
Expand Down Expand Up @@ -380,7 +386,7 @@ export class ListItem implements InteractiveComponent, LoadableComponent {
[CSS.contentContainerHasCenterContent]: hasCenterContent
}}
key="content-container"
onClick={this.toggleSelected}
onClick={this.itemClicked}
ref={(el) => (this.contentEl = el)}
role="gridcell"
>
Expand Down Expand Up @@ -509,6 +515,11 @@ export class ListItem implements InteractiveComponent, LoadableComponent {
this.open = !this.open;
};

itemClicked = (): void => {
this.toggleSelected();
this.calciteInternalListItemActive.emit();
};

toggleSelected = (): void => {
if (this.disabled) {
return;
Expand Down
31 changes: 31 additions & 0 deletions src/components/list/list.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,4 +147,35 @@ describe("calcite-list", () => {
expect(await list.getProperty("filteredData")).toHaveLength(0);
expect(await list.getProperty("filterText")).toBe("twoblah");
});

it("should update active item on init and click", async () => {
const page = await newE2EPage({
html: html`<calcite-list selection-mode="none">
<calcite-list-item id="item-1" label="hello" description="world"></calcite-list-item>
<calcite-list-item id="item-2" label="hello 2" description="world 2"></calcite-list-item>
<calcite-list-item id="item-3" label="hello 3" description="world 3"></calcite-list-item>
</calcite-list>`
});

await page.waitForTimeout(debounceTimeout);
await page.waitForChanges();

const items = await page.findAll("calcite-list-item");

expect(await items[0].getProperty("active")).toBe(true);
expect(await items[1].getProperty("active")).toBe(false);
expect(await items[2].getProperty("active")).toBe(false);

const eventSpy = await page.spyOnEvent("calciteInternalListItemActive");

await items[1].click();

await page.waitForTimeout(debounceTimeout);
await page.waitForChanges();
expect(eventSpy).toHaveReceivedEventTimes(1);

expect(await items[0].getProperty("active")).toBe(false);
expect(await items[1].getProperty("active")).toBe(true);
expect(await items[2].getProperty("active")).toBe(false);
});
});
11 changes: 10 additions & 1 deletion src/components/list/list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,22 @@ export class List implements InteractiveComponent, LoadableComponent {
}
}

@Listen("calciteInternalListItemActive")
handleCalciteListItemActive(event: CustomEvent): void {
const target = event.target as HTMLCalciteListItemElement;
const { listItems } = this;

listItems.forEach((listItem) => {
listItem.active = listItem === target;
});
}

@Listen("calciteInternalListItemSelect")
handleCalciteListItemSelect(event: CustomEvent): void {
const target = event.target as HTMLCalciteListItemElement;
const { listItems, selectionMode } = this;

listItems.forEach((listItem) => {
listItem.active = listItem === target;
if (selectionMode === "single") {
listItem.selected = listItem === target;
}
Expand Down

0 comments on commit 552e28f

Please sign in to comment.