fix(ui): unify list hover and selection highlighting
This commit is contained in:
11 files changed
+142
-31
No files matched your search
@@ -381,8 +381,8 @@ function clearContextTarget() {
|
||||
<div v-else>
|
||||
<div v-for="(folder, fi) in folders" :key="folder.path" class="border-b last:border-b-0">
|
||||
<div
|
||||
class="flex cursor-default items-center gap-1 px-2 py-1.5 text-[11px] font-medium text-muted-foreground bg-muted/10 sticky top-0 select-none hover:bg-muted/30"
|
||||
:class="selectedPath === folder.path ? 'bg-accent/60 text-accent-foreground' : ''"
|
||||
class="flex cursor-default items-center gap-1 px-2 py-1.5 text-[11px] font-medium text-muted-foreground bg-muted/10 sticky top-0 select-none"
|
||||
:class="selectedPath === folder.path ? 'bg-accent text-accent-foreground' : 'hover:bg-accent/40'"
|
||||
@click="
|
||||
toggleFolderCollapse(folder);
|
||||
selectPath(folder.path);
|
||||
@@ -429,8 +429,8 @@ function clearContextTarget() {
|
||||
<div
|
||||
v-for="{ entry, depth } in flatTree(folder.entries, folder.expanded)"
|
||||
:key="entry.path"
|
||||
class="flex cursor-default items-center gap-1 px-2 py-1 hover:bg-muted/60 text-sm"
|
||||
:class="[entry.is_dir ? 'rounded-sm' : 'rounded-none', selectedPath === entry.path ? 'bg-accent text-accent-foreground' : '']"
|
||||
class="flex cursor-default select-none items-center gap-1 px-2 py-1 text-sm"
|
||||
:class="[entry.is_dir ? 'rounded-sm' : 'rounded-none', selectedPath === entry.path ? 'bg-accent text-accent-foreground' : 'hover:bg-accent/40']"
|
||||
:style="{ paddingLeft: depth * 16 + 8 + 'px' }"
|
||||
@click="
|
||||
selectPath(entry.path);
|
||||
|
||||
@@ -517,22 +517,21 @@ function isFolderActive(folderId: string): boolean {
|
||||
return activeItemType.value === "folder" && activeItemId.value === folderId;
|
||||
}
|
||||
|
||||
function selectionRowClass(selected: boolean, active: boolean): string {
|
||||
if (selected) return "bg-primary/10 text-foreground";
|
||||
if (active) return "bg-primary/12 text-foreground";
|
||||
return "hover:bg-accent";
|
||||
function selectionRowClass(selected: boolean, active: boolean, contextOpen: boolean): string {
|
||||
if (selected || active || contextOpen) return "bg-accent text-accent-foreground";
|
||||
return "hover:bg-accent/40";
|
||||
}
|
||||
|
||||
function fileRowClass(fileId: string): string {
|
||||
return selectionRowClass(isFileSelected(fileId), isFileActive(fileId));
|
||||
return selectionRowClass(isFileSelected(fileId), isFileActive(fileId), isContextFile(fileId));
|
||||
}
|
||||
|
||||
function folderRowClass(folderId: string): string {
|
||||
return selectionRowClass(isFolderSelected(folderId), isFolderActive(folderId));
|
||||
return selectionRowClass(isFolderSelected(folderId), isFolderActive(folderId), isContextFolder(folderId));
|
||||
}
|
||||
|
||||
function fileMetaClass(fileId: string): string {
|
||||
return isFileSelected(fileId) || isFileActive(fileId) ? "text-foreground/70" : "text-muted-foreground";
|
||||
return isFileSelected(fileId) || isFileActive(fileId) || isContextFile(fileId) ? "text-accent-foreground" : "text-muted-foreground";
|
||||
}
|
||||
|
||||
function isFileDirty(file: SavedSqlFile): boolean {
|
||||
@@ -798,6 +797,14 @@ function handleFolderClick(folder: SavedSqlFolder, event: MouseEvent) {
|
||||
|
||||
const contextTarget = ref<SavedSqlFolder | SavedSqlFile | "panel" | null>(null);
|
||||
|
||||
function isContextFile(fileId: string): boolean {
|
||||
return contextTarget.value !== null && contextTarget.value !== "panel" && "sql" in contextTarget.value && contextTarget.value.id === fileId;
|
||||
}
|
||||
|
||||
function isContextFolder(folderId: string): boolean {
|
||||
return contextTarget.value !== null && contextTarget.value !== "panel" && !("sql" in contextTarget.value) && contextTarget.value.id === folderId;
|
||||
}
|
||||
|
||||
function folderMoveMenuItems(fileIds: string[]): CtxMenuItem[] {
|
||||
const files = [...new Set(fileIds)].map((id) => savedSqlStore.getFile(id)).filter((file): file is SavedSqlFile => Boolean(file));
|
||||
const allInUnfiled = files.length > 0 && files.every((file) => !file.folderId);
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import { readFileSync } from "node:fs";
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
const panelSource = readFileSync(new URL("../SqlLibraryPanel.vue", import.meta.url), "utf8");
|
||||
|
||||
describe("SqlLibraryPanel selection contrast", () => {
|
||||
it("uses the accent foreground for selected rows and their metadata", () => {
|
||||
expect(panelSource).toContain('return "bg-accent text-accent-foreground";');
|
||||
expect(panelSource).toMatch(/function fileMetaClass[\s\S]*\? "text-accent-foreground" : "text-muted-foreground";/);
|
||||
expect(panelSource).not.toContain('contextFile(fileId) ? "text-foreground/70"');
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user