Skip to content

Commit

Permalink
feat(autocomplete): add scrollContentTo method and automatically scro…
Browse files Browse the repository at this point in the history
…ll when navigating items via keyboard (#11153)

**Related Issue:** #11152

## Summary

- add `scrollContentTo` method
- add test
- automatically scroll to items when using keyboard

BEGIN_COMMIT_OVERRIDE
END_COMMIT_OVERRIDE
  • Loading branch information
driskull authored Dec 31, 2024
1 parent 3935861 commit be57a3b
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,33 @@ const simpleHTML = html`
</calcite-autocomplete>
`;

const scrollHTML = html`<calcite-autocomplete label="Item list" id="myAutocomplete">
<calcite-autocomplete-item label="Item one" value="one" heading="Item one"></calcite-autocomplete-item>
<calcite-autocomplete-item label="Item two" value="two" heading="Item two"></calcite-autocomplete-item>
<calcite-autocomplete-item label="Item three" value="three" heading="Item three"></calcite-autocomplete-item>
<calcite-autocomplete-item label="Item four" value="four" heading="Item four"></calcite-autocomplete-item>
<calcite-autocomplete-item disabled label="Item five" value="five" heading="Item five"></calcite-autocomplete-item>
<calcite-autocomplete-item label="Item six" value="six" heading="Item six"></calcite-autocomplete-item>
<calcite-autocomplete-item label="Item seven" value="seven" heading="Item seven"></calcite-autocomplete-item>
<calcite-autocomplete-item label="Item eight" value="eight" heading="Item eight"></calcite-autocomplete-item>
<calcite-autocomplete-item label="Item nine" value="nine" heading="Item nine"></calcite-autocomplete-item>
<calcite-autocomplete-item label="Item ten" value="ten" heading="Item ten"></calcite-autocomplete-item>
<calcite-autocomplete-item label="Item eleven" value="eleven" heading="Item eleven"></calcite-autocomplete-item>
<calcite-autocomplete-item label="Item twelve" value="twelve" heading="Item twelve"></calcite-autocomplete-item>
<calcite-autocomplete-item label="Item thirteen" value="thirteen" heading="Item thirteen"></calcite-autocomplete-item>
<calcite-autocomplete-item label="Item fourteen" value="fourteen" heading="Item fourteen"></calcite-autocomplete-item>
<calcite-autocomplete-item label="Item fifteen" value="fifteen" heading="Item fifteen"></calcite-autocomplete-item>
<calcite-autocomplete-item label="Item sixteen" value="sixteen" heading="Item sixteen"></calcite-autocomplete-item>
<calcite-autocomplete-item
label="Item seventeen"
value="seventeen"
heading="Item seventeen"
></calcite-autocomplete-item>
<calcite-autocomplete-item label="Item eighteen" value="eighteen" heading="Item eighteen"></calcite-autocomplete-item>
<calcite-autocomplete-item label="Item nineteen" value="nineteen" heading="Item nineteen"></calcite-autocomplete-item>
<calcite-autocomplete-item label="Item twenty" value="twenty" heading="Item twenty"></calcite-autocomplete-item>
</calcite-autocomplete>`;

const simpleGroupHTML = html`
<calcite-autocomplete label="Pets">
<calcite-autocomplete-item-group heading="Dogs">
Expand Down Expand Up @@ -585,6 +612,26 @@ describe("calcite-autocomplete", () => {
expect(await isElementFocused(page, "#myAutocomplete")).toBe(true);
});

it("handles scrollContentTo method", async () => {
const page = await newE2EPage();
await page.setContent(scrollHTML);

const autocomplete = await page.find("calcite-autocomplete");
autocomplete.setProperty("open", true);

await page.waitForChanges();

const scrollEl = await page.find(`calcite-autocomplete >>> .${CSS.contentAnimation}`);

expect(await scrollEl.getProperty("scrollTop")).toBe(0);

await page.$eval("calcite-autocomplete", async (autocomplete: Autocomplete["el"]) => {
await autocomplete.scrollContentTo({ top: 100 });
});

expect(await scrollEl.getProperty("scrollTop")).toBe(100);
});

it("should set value, close, and emit calciteAutocompleteChange when item is selected via keyboard", async () => {
const page = await newE2EPage();
await page.setContent(simpleHTML);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,23 @@ export class Autocomplete
);
}

/**
* Scrolls the component's content to a specified set of coordinates.
*
* @example
* myAutocomplete.scrollContentTo({
* left: 0, // Specifies the number of pixels along the X axis to scroll the window or element.
* top: 0, // Specifies the number of pixels along the Y axis to scroll the window or element
* behavior: "auto" // Specifies whether the scrolling should animate smoothly (smooth), or happen instantly in a single jump (auto, the default value).
* });
* @param options - allows specific coordinates to be defined.
* @returns - promise that resolves once the content is scrolled to.
*/
@method()
async scrollContentTo(options?: ScrollToOptions): Promise<void> {
this.transitionEl?.scrollTo(options);
}

/**
* Selects the text of the component's `value`.
*
Expand Down Expand Up @@ -689,27 +706,35 @@ export class Autocomplete
this.open = true;
this.activeIndex =
activeIndex !== -1 ? Math.min(activeIndex + 1, enabledItems.length - 1) : 0;
this.scrollToActiveItem();
event.preventDefault();
break;
case "ArrowUp":
this.open = true;
this.activeIndex =
activeIndex !== -1 ? Math.max(activeIndex - 1, 0) : enabledItems.length - 1;
this.scrollToActiveItem();
event.preventDefault();
break;
case "Home":
this.open = true;
this.activeIndex = 0;
this.scrollToActiveItem();
event.preventDefault();
break;
case "End":
this.open = true;
this.activeIndex = enabledItems.length - 1;
this.scrollToActiveItem();
event.preventDefault();
break;
}
}

private scrollToActiveItem(): void {
this.enabledItems[this.activeIndex]?.scrollIntoView({ block: "nearest" });
}

private changeHandler(event: CustomEvent): void {
event.stopPropagation();
this.inputValue = (event.target as Input["el"]).value;
Expand Down
3 changes: 2 additions & 1 deletion packages/calcite-components/src/demos/autocomplete.html
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,7 @@ <h1 style="margin: 0; text-align: center">Autocomplete</h1>
"https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer",
{
text: locatorAutocomplete.inputValue,
maxSuggestions: 5,
},
{ signal },
);
Expand All @@ -535,7 +536,7 @@ <h1 style="margin: 0; text-align: center">Autocomplete</h1>
noResults.slot = "content-top";
locatorAutocomplete.appendChild(noResults);
} else {
response.slice(0, 5).forEach((location) => {
response.forEach((location) => {
const item = document.createElement("calcite-autocomplete-item");
item.className = "temporary";
item.value = location.magicKey;
Expand Down

0 comments on commit be57a3b

Please sign in to comment.