feat: tint enitre file item block

This commit is contained in:
Aleix Soler 2025-11-21 14:57:38 +01:00
parent a13adb265d
commit 48945b3d63
5 changed files with 88 additions and 0 deletions

View file

@ -236,6 +236,17 @@ export const UISettings: React.FC<Props> = ({ settings, onChange }) => {
/>
</SettingItem>
<SettingItem
name="Color the file explorer block based on status"
description="Tint the entire file explorer list item with the active status color."
>
<input
type="checkbox"
checked={settings.fileExplorerColorBlock || false}
onChange={handleChange("fileExplorerColorBlock")}
/>
</SettingItem>
<SettingItem
name="Status icon frame"
description="Choose whether to display a frame around the status icon inside the file explorer."

View file

@ -23,6 +23,7 @@ export const DEFAULT_PLUGIN_SETTINGS: PluginSettings = {
showStatusIconsInExplorer: true,
hideUnknownStatusInExplorer: true, // Default to hide unknown status
fileExplorerColorFileName: false,
fileExplorerColorBlock: false,
enabledTemplates: DEFAULT_ENABLED_TEMPLATES,
useCustomStatusesOnly: false,
useMultipleStatuses: true,

View file

@ -27,6 +27,8 @@ export class FileExplorerIntegration implements IElementProcessor {
private readonly CONTAINER_SELECTOR = ".nav-files-container";
private readonly FILE_NAME_COLORIZED_ATTR = "noteStatusColorized";
private readonly FILE_NAME_ORIGINAL_COLOR_ATTR = "noteStatusOriginalColor";
private readonly FILE_BLOCK_CLASS = "note-status-colored-block";
private readonly FILE_BLOCK_COLOR_VAR = "--note-status-block-color";
constructor(plugin: Plugin) {
this.plugin = plugin;
@ -66,6 +68,7 @@ export class FileExplorerIntegration implements IElementProcessor {
key === "fileExplorerIconFrame" ||
key === "fileExplorerIconColorMode" ||
key === "fileExplorerColorFileName" ||
key === "fileExplorerColorBlock" ||
key === "unknownStatusIcon" ||
key === "unknownStatusLucideIcon" ||
key === "unknownStatusColor" ||
@ -116,9 +119,14 @@ export class FileExplorerIntegration implements IElementProcessor {
textEl as HTMLElement,
noteStatusService.statuses,
);
this.applyFileBlockColor(
textEl as HTMLElement,
noteStatusService.statuses,
);
this.render(textEl, noteStatusService.statuses);
} else {
this.applyFileNameColor(textEl as HTMLElement, null);
this.applyFileBlockColor(textEl as HTMLElement, null);
}
}
}
@ -321,6 +329,48 @@ export class FileExplorerIntegration implements IElementProcessor {
element.style.color = color;
}
private applyFileBlockColor(
element?: HTMLElement | null,
statuses?: GroupedStatuses | null,
): void {
const navItem = this.getNavItemElement(element);
if (!navItem) {
return;
}
if (!settingsService.settings.fileExplorerColorBlock) {
this.clearFileBlockColor(navItem);
return;
}
const primaryStatus = getPrimaryStatus(statuses);
if (!primaryStatus) {
this.clearFileBlockColor(navItem);
return;
}
const color = resolveStatusColor(
primaryStatus,
getUnknownStatusColor(),
);
if (!color) {
this.clearFileBlockColor(navItem);
return;
}
navItem.classList.add(this.FILE_BLOCK_CLASS);
navItem.style.setProperty(this.FILE_BLOCK_COLOR_VAR, color);
}
private getNavItemElement(
element?: HTMLElement | null,
): HTMLElement | null {
if (!element) {
return null;
}
return element.closest(".nav-file, .nav-folder") as HTMLElement | null;
}
private clearFileNameColor(element: HTMLElement): void {
if (!element.dataset[this.FILE_NAME_COLORIZED_ATTR]) {
return;
@ -337,4 +387,9 @@ export class FileExplorerIntegration implements IElementProcessor {
delete element.dataset[this.FILE_NAME_ORIGINAL_COLOR_ATTR];
delete element.dataset[this.FILE_NAME_COLORIZED_ATTR];
}
private clearFileBlockColor(navItem: HTMLElement): void {
navItem.classList.remove(this.FILE_BLOCK_CLASS);
navItem.style.removeProperty(this.FILE_BLOCK_COLOR_VAR);
}
}

View file

@ -11,6 +11,26 @@
right: 0;
}
.note-status-colored-block {
position: relative;
border-radius: var(--radius-s);
z-index: 0;
}
.note-status-colored-block::before {
content: "";
position: absolute;
inset: 0;
border-radius: inherit;
background-color: var(--note-status-block-color, transparent);
opacity: 0.18;
pointer-events: none;
z-index: -1;
transition:
background-color var(--anim-duration-fast) ease,
opacity var(--anim-duration-fast) ease;
}
.status-wrapper {
position: relative;
display: inline-block;

View file

@ -24,6 +24,7 @@ export type PluginSettings = {
showStatusIconsInExplorer: boolean;
hideUnknownStatusInExplorer: boolean;
fileExplorerColorFileName: boolean; // Whether to color the file explorer filename text using the current status color
fileExplorerColorBlock: boolean; // Whether to color the entire file explorer block background with the status color
enabledTemplates: string[]; // IDs of enabled templates
useCustomStatusesOnly: boolean; // Whether to use only custom statuses or include templates
useMultipleStatuses: boolean; // Whether to allow multiple statuses per note