fix(grid): improve condition suggestion keyboard behavior
This commit is contained in:
3 files changed
+45
-7
No files matched your search
@@ -123,6 +123,26 @@ describe("DataGridConditionEditor quote completion", () => {
|
||||
expect(input.selectionEnd).toBe(20);
|
||||
});
|
||||
|
||||
it("starts without an active suggestion and selects the first item on ArrowDown", async () => {
|
||||
const { value, input } = mountEditor("orderBy", "", { columns: ["name", "namespace"] });
|
||||
input.focus();
|
||||
input.value = "na";
|
||||
input.setSelectionRange(2, 2);
|
||||
input.dispatchEvent(new Event("input", { bubbles: true }));
|
||||
|
||||
await vi.waitFor(() => expect(document.querySelectorAll('[role="option"]')).toHaveLength(2));
|
||||
expect(document.querySelector('[role="option"][aria-selected="true"]')).toBeNull();
|
||||
expect(value.value).toBe("na");
|
||||
|
||||
input.dispatchEvent(new KeyboardEvent("keydown", { key: "ArrowDown", bubbles: true, cancelable: true }));
|
||||
await nextTick();
|
||||
expect(document.querySelector('[role="option"][aria-selected="true"]')?.textContent).toContain("name");
|
||||
|
||||
input.dispatchEvent(new KeyboardEvent("keydown", { key: "Enter", bubbles: true, cancelable: true }));
|
||||
await nextTick();
|
||||
expect(value.value).toBe("name");
|
||||
});
|
||||
|
||||
it("keeps expanded input first-line indent and wraps long tokens", () => {
|
||||
const source = readFileSync(resolve(process.cwd(), "apps/desktop/src/components/grid/DataGridConditionEditor.vue"), "utf8");
|
||||
const expandedInputCss = source.match(/\.data-grid-topbar-condition-input--expanded\s*\{(?<body>[\s\S]*?)\n\}/)?.groups?.body;
|
||||
|
||||
@@ -34,6 +34,8 @@ describe("useDataGridConditionEditor", () => {
|
||||
await nextTick();
|
||||
await vi.waitFor(() => expect(editor.suggestions.value.map((item) => item.value)).toEqual(["customer_id", "customer_name"]));
|
||||
expect(editor.navigate(1)).toBe(true);
|
||||
expect(editor.highlightedIndex.value).toBe(0);
|
||||
expect(editor.navigate(1)).toBe(true);
|
||||
expect(editor.highlightedIndex.value).toBe(1);
|
||||
expect(editor.navigate(1)).toBe(true);
|
||||
expect(editor.highlightedIndex.value).toBe(1);
|
||||
@@ -381,18 +383,34 @@ describe("useDataGridConditionEditor", () => {
|
||||
|
||||
it("maps Enter, Tab, arrows, and Escape without applying stale selections", async () => {
|
||||
const value = ref("");
|
||||
const editor = useDataGridConditionEditor({ kind: "orderBy", value, columns: ["name"], historyScope: {} });
|
||||
const editor = useDataGridConditionEditor({ kind: "orderBy", value, columns: ["name", "namespace"], historyScope: {} });
|
||||
value.value = "na";
|
||||
await nextTick();
|
||||
await vi.waitFor(() => expect(editor.suggestions.value).toHaveLength(1));
|
||||
await vi.waitFor(() => expect(editor.suggestions.value).toHaveLength(2));
|
||||
expect(editor.highlightedIndex.value).toBe(-1);
|
||||
|
||||
const initialEnter = keyboardEvent("Enter");
|
||||
expect(editor.handleKeydown(initialEnter)).toBe("apply");
|
||||
expect(initialEnter.preventDefault).toHaveBeenCalledOnce();
|
||||
expect(value.value).toBe("na");
|
||||
|
||||
const down = keyboardEvent("ArrowDown");
|
||||
expect(editor.handleKeydown(down)).toBe("navigate");
|
||||
expect(down.preventDefault).toHaveBeenCalledOnce();
|
||||
const tab = keyboardEvent("Tab");
|
||||
expect(editor.handleKeydown(tab)).toBe("accept");
|
||||
expect(editor.highlightedIndex.value).toBe(0);
|
||||
const navigatedEnter = keyboardEvent("Enter");
|
||||
expect(editor.handleKeydown(navigatedEnter)).toBe("accept");
|
||||
expect(value.value).toBe("name");
|
||||
|
||||
const tabValue = ref("");
|
||||
const tabEditor = useDataGridConditionEditor({ kind: "orderBy", value: tabValue, columns: ["name"], historyScope: {} });
|
||||
tabValue.value = "na";
|
||||
await nextTick();
|
||||
await vi.waitFor(() => expect(tabEditor.suggestions.value).toHaveLength(1));
|
||||
const tab = keyboardEvent("Tab");
|
||||
expect(tabEditor.handleKeydown(tab)).toBe("accept");
|
||||
expect(tabValue.value).toBe("name");
|
||||
|
||||
const enter = keyboardEvent("Enter");
|
||||
expect(editor.handleKeydown(enter)).toBe("apply");
|
||||
editor.openHistory();
|
||||
|
||||
@@ -264,7 +264,7 @@ export function useDataGridConditionEditor(options: UseDataGridConditionEditorOp
|
||||
const limit = options.suggestionLimit ?? 8;
|
||||
suggestions.value = values ? [...new Set(values)].slice(0, limit).map((suggestion) => ({ value: suggestion, kind: "column" })) : defaultSuggestions(target).slice(0, limit);
|
||||
replacementRange.value = { from: target.from, to: target.to };
|
||||
highlightedIndex.value = suggestions.value.length > 0 ? 0 : -1;
|
||||
highlightedIndex.value = -1;
|
||||
} catch (error) {
|
||||
if (!controller.signal.aborted && requestId === suggestionRequestId) {
|
||||
suggestions.value = [];
|
||||
@@ -310,7 +310,7 @@ export function useDataGridConditionEditor(options: UseDataGridConditionEditorOp
|
||||
const history = forgetDataGridConditionHistory(options.kind, toValue(options.historyScope), value);
|
||||
const query = options.value.value.trim().toLowerCase();
|
||||
suggestions.value = history.filter((item) => !query || item.toLowerCase().includes(query)).map((item) => ({ value: item, kind: "history" }));
|
||||
highlightedIndex.value = suggestions.value.length > 0 ? Math.min(Math.max(highlightedIndex.value, 0), suggestions.value.length - 1) : -1;
|
||||
highlightedIndex.value = suggestions.value.length > 0 && highlightedIndex.value >= 0 ? Math.min(highlightedIndex.value, suggestions.value.length - 1) : -1;
|
||||
historyOpen.value = true;
|
||||
}
|
||||
|
||||
@@ -328,7 +328,7 @@ export function useDataGridConditionEditor(options: UseDataGridConditionEditorOp
|
||||
return true;
|
||||
}
|
||||
|
||||
function accept(index = highlightedIndex.value) {
|
||||
function accept(index = highlightedIndex.value >= 0 ? highlightedIndex.value : 0) {
|
||||
const suggestion = suggestions.value[index];
|
||||
if (!suggestion) return false;
|
||||
let caret: number;
|
||||
|
||||
Reference in new issue
Block a user