import { cleanup, fireEvent, render, screen } from "@testing-library/react";
import { createRef, useState } from "react";
import { afterEach, describe, expect, it, vi } from "vitest";
import { Command, CommandInput, CommandItem, CommandList } from "@kandev/ui/command";
const LIST_TEST_ID = "command-list";
const SEARCH_PLACEHOLDER = "Search commands";
function getList() {
return screen.getByTestId(LIST_TEST_ID) as HTMLDivElement;
}
function renderItems() {
return ["Alpha", "Beta", "Gamma", "Delta", "Epsilon", "Zeta"].map((label) => (
{label}
));
}
function ControlledCommandHarness() {
const [search, setSearch] = useState("");
return (
{renderItems()}
);
}
afterEach(() => {
cleanup();
});
describe("CommandList scroll reset", () => {
it("resets scrollTop when the cmdk query changes", () => {
render(
{renderItems()}
,
);
const list = getList();
list.scrollTop = 123;
fireEvent.change(screen.getByPlaceholderText(SEARCH_PLACEHOLDER), {
target: { value: "be" },
});
expect(list.scrollTop).toBe(0);
});
it("resets scrollTop for controlled inputs that disable cmdk filtering", () => {
render();
const list = getList();
list.scrollTop = 123;
fireEvent.change(screen.getByPlaceholderText(SEARCH_PLACEHOLDER), {
target: { value: "ga" },
});
expect(list.scrollTop).toBe(0);
});
it("resets scrollTop when the query is cleared", () => {
render(
{renderItems()}
,
);
const input = screen.getByPlaceholderText(SEARCH_PLACEHOLDER);
fireEvent.change(input, { target: { value: "de" } });
const list = getList();
list.scrollTop = 88;
fireEvent.change(input, { target: { value: "" } });
expect(list.scrollTop).toBe(0);
});
it("forwards external refs to the underlying list element", () => {
const ref = createRef();
render(
{renderItems()}
,
);
expect(ref.current).toBe(getList());
});
it("runs cleanup returned by a callback ref on unmount", () => {
const refCleanup = vi.fn();
const callbackRef = vi.fn(() => refCleanup);
const { unmount } = render(
{renderItems()}
,
);
expect(callbackRef).toHaveBeenCalledWith(getList());
unmount();
expect(refCleanup).toHaveBeenCalledTimes(1);
});
});