tui: show monochrome file icons by default in tree view, revealing colors on hover to reduce visual clutter and help users focus on code content

This commit is contained in:
David Hill
2026-02-17 18:23:04 +00:00
parent ce7484b4f5
commit a685e7a805
3 changed files with 73 additions and 5 deletions

View File

@@ -3,3 +3,35 @@
width: 16px;
height: 16px;
}
/*
File tree: show monochrome weak icons by default.
On hover, show the original file-type colors.
*/
[data-component="filetree"] .filetree-icon--mono {
color: var(--icon-base);
}
[data-component="filetree"] .filetree-iconpair {
position: relative;
display: inline-flex;
width: 16px;
height: 16px;
}
[data-component="filetree"] .filetree-iconpair [data-component="file-icon"] {
position: absolute;
inset: 0;
}
[data-component="filetree"] .filetree-iconpair .filetree-icon--color {
opacity: 0;
}
[data-component="filetree"]:hover .filetree-iconpair .filetree-icon--color {
opacity: 1;
}
[data-component="filetree"]:hover .filetree-iconpair .filetree-icon--mono {
opacity: 0;
}

View File

@@ -1,16 +1,20 @@
import type { Component, JSX } from "solid-js"
import { createMemo, splitProps } from "solid-js"
import { createMemo, splitProps, Show } from "solid-js"
import sprite from "./file-icons/sprite.svg"
import type { IconName } from "./file-icons/types"
let filter = 0
export type FileIconProps = JSX.GSVGAttributes<SVGSVGElement> & {
node: { path: string; type: "file" | "directory" }
expanded?: boolean
mono?: boolean
}
export const FileIcon: Component<FileIconProps> = (props) => {
const [local, rest] = splitProps(props, ["node", "class", "classList", "expanded"])
const [local, rest] = splitProps(props, ["node", "class", "classList", "expanded", "mono"])
const name = createMemo(() => chooseIconName(local.node.path, local.node.type, local.expanded || false))
const id = `file-icon-mono-${filter++}`
return (
<svg
data-component="file-icon"
@@ -20,7 +24,15 @@ export const FileIcon: Component<FileIconProps> = (props) => {
[local.class ?? ""]: !!local.class,
}}
>
<use href={`${sprite}#${name()}`} />
<Show when={local.mono}>
<defs>
<filter id={id} color-interpolation-filters="sRGB">
<feFlood flood-color="currentColor" result="flood" />
<feComposite in="flood" in2="SourceAlpha" operator="in" />
</filter>
</defs>
</Show>
<use href={`${sprite}#${name()}`} filter={local.mono ? `url(#${id})` : undefined} />
</svg>
)
}