CommandBar, ResultList, ActionPage and useCommandBar over the same model docs/COMMAND-BAR.md specifies: sigils, empty-query session order, the drill-in action page, and the keys. The highlight now walks the rows in the order they render. The legacy bar indexed the highlight by display order but activated by rank order, so Enter could act on a different row than the one lit.
77 lines
2.3 KiB
TypeScript
77 lines
2.3 KiB
TypeScript
// @vitest-environment happy-dom
|
|
import { act, cleanup, render } from "@testing-library/react";
|
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
|
|
import { OPEN_COMMAND_BAR_EVENT } from "../../catalog.js";
|
|
import { useCommandBar, type UseCommandBarOptions } from "./useCommandBar.js";
|
|
|
|
let controls: ReturnType<typeof useCommandBar>;
|
|
|
|
function Probe(opts: UseCommandBarOptions) {
|
|
controls = useCommandBar(opts);
|
|
return <div>{controls.open ? "open" : "closed"}</div>;
|
|
}
|
|
|
|
function ctrlK(target: EventTarget = window): void {
|
|
act(() => {
|
|
target.dispatchEvent(
|
|
new KeyboardEvent("keydown", { key: "k", ctrlKey: true, bubbles: true, cancelable: true }),
|
|
);
|
|
});
|
|
}
|
|
|
|
afterEach(cleanup);
|
|
|
|
describe("useCommandBar", () => {
|
|
it("opens on ctrl-k, from the capture phase so an attached xterm never sees it", () => {
|
|
const view = render(<Probe />);
|
|
ctrlK();
|
|
expect(view.container.textContent).toBe("open");
|
|
});
|
|
|
|
it("stays deaf while the bar is already up — its own input owns the keys", () => {
|
|
const onOpen = vi.fn();
|
|
render(<Probe onOpen={onOpen} />);
|
|
ctrlK();
|
|
ctrlK();
|
|
expect(onOpen).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it("leaves a form field's own Ctrl-K alone", () => {
|
|
const field = document.createElement("input");
|
|
document.body.appendChild(field);
|
|
const view = render(<Probe />);
|
|
ctrlK(field);
|
|
expect(view.container.textContent).toBe("closed");
|
|
field.remove();
|
|
});
|
|
|
|
it("opens from the sidebar's search field, the touch entry point", () => {
|
|
const view = render(<Probe />);
|
|
act(() => {
|
|
document.dispatchEvent(new CustomEvent(OPEN_COMMAND_BAR_EVENT));
|
|
});
|
|
expect(view.container.textContent).toBe("open");
|
|
});
|
|
|
|
it("runs the caller's hook before opening, so a preview is discarded first", () => {
|
|
const onOpen = vi.fn();
|
|
render(<Probe onOpen={onOpen} />);
|
|
ctrlK();
|
|
expect(onOpen).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it("closes on demand", () => {
|
|
const view = render(<Probe />);
|
|
ctrlK();
|
|
act(() => controls.closeBar());
|
|
expect(view.container.textContent).toBe("closed");
|
|
});
|
|
|
|
it("binds nothing while disabled — another overlay owns the keyboard", () => {
|
|
const view = render(<Probe enabled={false} />);
|
|
ctrlK();
|
|
expect(view.container.textContent).toBe("closed");
|
|
});
|
|
});
|