页面美化

This commit is contained in:
2026-07-08 14:39:08 +08:00
parent bb4e376528
commit a7bcd03534
8 changed files with 649 additions and 149 deletions

View File

@@ -5,6 +5,7 @@ import TreeEntry from "./TreeEntry.vue";
type SettingsPage = "about" | "editor";
type DocumentMode = "preview" | "edit" | "mixed";
type AppTheme = "system" | "warm" | "white" | "black" | "gruvbox" | "gray";
interface DirEntry {
name: string;
@@ -21,12 +22,14 @@ const props = withDefaults(
settingsRequest?: number;
settingsInitialPage?: SettingsPage;
defaultDocumentMode?: DocumentMode;
appTheme?: AppTheme;
}>(),
{
currentFilePath: null,
settingsRequest: 0,
settingsInitialPage: "about",
defaultDocumentMode: "edit",
appTheme: "warm",
},
);
@@ -37,6 +40,7 @@ const emit = defineEmits<{
createFile: [];
createFolder: [];
updateDefaultDocumentMode: [mode: DocumentMode];
updateAppTheme: [theme: AppTheme];
}>();
// Wrap the workspace root as a top-level tree node
@@ -82,14 +86,14 @@ function openSettings(page: SettingsPage) {
<template>
<aside
:class="['flex flex-row border-r border-[#e8e4da] bg-[#f4f1eb]/80 transition-all duration-300 ease-in-out overflow-hidden shrink-0', expanded ? 'w-72' : 'w-12']"
:class="['directory-sidebar flex flex-row transition-all duration-300 ease-in-out overflow-hidden shrink-0', expanded ? 'w-72' : 'w-12']"
>
<!-- ============ Icon bar ============ -->
<div class="w-12 shrink-0 flex flex-col items-center gap-1 py-3">
<!-- Folder -->
<button
class="px-2 py-1 cursor-pointer rounded-md transition-colors"
:class="activeView === 'folder' ? 'text-[#bf6a3b] bg-[#ede8de]' : 'text-[#b8b3a8] hover:text-[#5c574e] hover:bg-[#ede8de]'"
class="sidebar-icon-btn px-2 py-1 cursor-pointer rounded-md transition-colors"
:class="{ 'sidebar-icon-btn-active': activeView === 'folder' }"
title="文件"
@click="switchView('folder')"
>
@@ -97,8 +101,8 @@ function openSettings(page: SettingsPage) {
</button>
<!-- Search -->
<button
class="px-2 py-1 cursor-pointer rounded-md transition-colors"
:class="activeView === 'search' ? 'text-[#bf6a3b] bg-[#ede8de]' : 'text-[#b8b3a8] hover:text-[#5c574e] hover:bg-[#ede8de]'"
class="sidebar-icon-btn px-2 py-1 cursor-pointer rounded-md transition-colors"
:class="{ 'sidebar-icon-btn-active': activeView === 'search' }"
title="搜索"
@click="switchView('search')"
>
@@ -106,8 +110,8 @@ function openSettings(page: SettingsPage) {
</button>
<!-- ===== Settings ===== -->
<button
class="px-2 py-1 cursor-pointer rounded-md transition-colors mt-auto"
:class="showSettings ? 'text-[#bf6a3b] bg-[#ede8de]' : 'text-[#b8b3a8] hover:text-[#5c574e] hover:bg-[#ede8de]'"
class="sidebar-icon-btn px-2 py-1 cursor-pointer rounded-md transition-colors mt-auto"
:class="{ 'sidebar-icon-btn-active': showSettings }"
title="设置"
@click="openSettings('about')"
>
@@ -116,7 +120,7 @@ function openSettings(page: SettingsPage) {
</div>
<!-- ============ Expanded panel ============ -->
<div v-show="expanded" class="flex-1 flex flex-col overflow-hidden border-l border-[#e8e4da]">
<div v-show="expanded" class="directory-sidebar-panel flex-1 flex flex-col overflow-hidden">
<!-- ===== FOLDER VIEW ===== -->
<div v-if="activeView === 'folder'" class="flex flex-col flex-1 overflow-hidden">
<!-- File tree -->
@@ -134,11 +138,11 @@ function openSettings(page: SettingsPage) {
<!-- Empty state -->
<div
v-if="!folderPath"
class="px-2 py-4 text-xs text-[#b8b3a8] text-center"
class="sidebar-empty px-2 py-4 text-xs text-center"
>
<p class="mb-3">暂无打开的文件夹</p>
<button
class="inline-flex items-center gap-1.5 px-3 py-1.5 text-xs cursor-pointer rounded-md bg-[#fdf0e5] text-[#bf6a3b] border border-[#d4a574]/40 hover:bg-[#fdf0e5]/80 hover:text-[#bf6a3b] transition-colors"
class="sidebar-empty-btn inline-flex items-center gap-1.5 px-3 py-1.5 text-xs cursor-pointer rounded-md transition-colors"
@click="$emit('openFolder')"
>
<i class="ri-folder-open-line"></i>
@@ -152,16 +156,16 @@ function openSettings(page: SettingsPage) {
<div v-if="activeView === 'search'" class="flex flex-col flex-1 overflow-hidden">
<div class="px-3 py-3">
<div class="relative">
<i class="ri-search-line absolute left-2.5 top-1/2 -translate-y-1/2 text-sm text-[#b8b3a8]"></i>
<i class="sidebar-search-icon ri-search-line absolute left-2.5 top-1/2 -translate-y-1/2 text-sm"></i>
<input
class="w-full pl-8 pr-3 py-1.5 text-xs bg-[#ede8de] border border-[#e0dbcf] rounded-md text-[#38342e] outline-none focus:border-[#bf6a3b] placeholder-[#b8b3a8]"
class="sidebar-search-input w-full pl-8 pr-3 py-1.5 text-xs rounded-md outline-none"
placeholder="搜索文件内容..."
disabled
/>
</div>
</div>
<div class="flex-1 flex items-center justify-center px-3 pb-8">
<p class="text-xs text-[#b8b3a8] text-center leading-relaxed">
<p class="sidebar-empty text-xs text-center leading-relaxed">
搜索功能即将上线
</p>
</div>
@@ -173,6 +177,59 @@ function openSettings(page: SettingsPage) {
v-model:show="showSettings"
:initial-page="settingsPage"
:default-document-mode="defaultDocumentMode"
:app-theme="appTheme"
@update-default-document-mode="(mode: DocumentMode) => emit('updateDefaultDocumentMode', mode)"
@update-app-theme="(theme: AppTheme) => emit('updateAppTheme', theme)"
/>
</template>
<style scoped>
.directory-sidebar {
border-right: 1px solid var(--app-border);
background: color-mix(in srgb, var(--app-sidebar-bg) 82%, transparent);
}
.directory-sidebar-panel {
border-left: 1px solid var(--app-border);
}
.sidebar-icon-btn {
color: var(--app-subtle);
}
.sidebar-icon-btn:hover,
.sidebar-icon-btn-active {
background: var(--app-hover);
color: var(--app-accent);
}
.sidebar-empty,
.sidebar-search-icon {
color: var(--app-subtle);
}
.sidebar-empty-btn {
border: 1px solid color-mix(in srgb, var(--app-accent-muted) 42%, transparent);
background: var(--app-active-bg);
color: var(--app-accent);
}
.sidebar-empty-btn:hover {
background: color-mix(in srgb, var(--app-active-bg) 84%, var(--app-surface));
color: var(--app-accent);
}
.sidebar-search-input {
border: 1px solid var(--app-border-strong);
background: var(--app-hover);
color: var(--app-text);
}
.sidebar-search-input:focus {
border-color: var(--app-accent);
}
.sidebar-search-input::placeholder {
color: var(--app-subtle);
}
</style>