feat: enhance background layer handling and uploader functionality

- Introduced automatic overlay opacity and gradient based on layer ID in BackgroundLayer component.
- Added disabled state to BackgroundUploader, preventing actions when disabled.
- Updated component CSS editor to handle disabled state, preventing changes when disabled.
- Modified Header and Layout components to manage background inheritance from the page layer.
- Improved Sidebar and Card components to respect background inheritance and layering.
- Refactored theme management to include default accent color and normalization functions.
- Enhanced AppearanceTab to manage accent color changes with debouncing and validation.
- Added UI feedback for inherited background layers in AppearanceTab.
This commit is contained in:
DrSmoothl
2026-03-16 22:19:05 +08:00
parent a5a6d2cb26
commit 0811213db0
16 changed files with 359 additions and 170 deletions

View File

@@ -45,7 +45,8 @@ export function Header({
}: HeaderProps) {
const { t, i18n: i18nInstance } = useTranslation()
const currentLang = i18nInstance.language || 'zh'
const headerBg = useBackground('header')
const { config: headerBg, inheritedFrom } = useBackground('header')
const inheritsPageBackground = inheritedFrom === 'page'
const [backendManagerOpen, setBackendManagerOpen] = useState(false)
const [activeBackendName, setActiveBackendName] = useState<string>('')
@@ -61,9 +62,12 @@ export function Header({
}
return (
<header className="flex h-16 items-center justify-between border-b bg-card/80 backdrop-blur-md px-4 sticky top-0 z-10">
<BackgroundLayer config={headerBg} layerId="header" />
<div className="flex items-center gap-4">
<header className={cn(
'sticky top-0 z-10 flex h-16 items-center justify-between border-b px-4 backdrop-blur-md isolate',
inheritsPageBackground ? 'bg-transparent' : 'bg-card/80',
)}>
{!inheritsPageBackground && <BackgroundLayer config={headerBg} layerId="header" />}
<div className="relative z-10 flex items-center gap-4">
{/* 移动端菜单按钮 */}
<button
onClick={onMobileMenuToggle}
@@ -87,7 +91,7 @@ export function Header({
</button>
</div>
<div className="flex items-center gap-2">
<div className="relative z-10 flex items-center gap-2">
{/* 后端切换按钮(仅 Electron */}
{isElectron() && (
<>

View File

@@ -101,7 +101,7 @@ export function Layout({ children }: LayoutProps) {
}
const actualTheme = getActualTheme()
const pageBg = useBackground('page')
const { config: pageBg } = useBackground('page')
// 认证检查中,显示加载状态
if (checking) {
@@ -116,7 +116,9 @@ export function Layout({ children }: LayoutProps) {
<TooltipProvider delayDuration={300}>
<SkipNav />
{isElectron() && <TitleBar />}
<div className={cn('flex h-screen overflow-hidden', isElectron() && 'pt-8')}>
<div className={cn('relative isolate flex h-screen overflow-hidden', isElectron() && 'pt-8')}>
<BackgroundLayer config={pageBg} layerId="page" />
<div className="relative z-10 flex h-full w-full overflow-hidden">
{/* Sidebar */}
<Sidebar
sidebarOpen={sidebarOpen}
@@ -155,16 +157,21 @@ export function Layout({ children }: LayoutProps) {
<main
id="main-content"
tabIndex={-1}
className="relative flex-1 overflow-hidden bg-background outline-none"
className={cn(
'relative isolate flex-1 overflow-hidden outline-none',
pageBg.type === 'none' ? 'bg-background' : 'bg-transparent',
)}
>
<BackgroundLayer config={pageBg} layerId="page" />
{children}
<div className="relative z-10 h-full">
{children}
</div>
</main>
{/* Back to Top Button */}
<BackToTop />
</div>
</div>
</div>
</TooltipProvider>
)
}

View File

@@ -23,24 +23,29 @@ export function Sidebar({
onMobileMenuClose
}: SidebarProps) {
const { t } = useTranslation()
const sidebarBg = useBackground('sidebar')
const { config: sidebarBg, inheritedFrom } = useBackground('sidebar')
const inheritsPageBackground = inheritedFrom === 'page'
return (
<aside
className={cn(
'fixed inset-y-0 left-0 z-50 flex flex-col border-r bg-card transition-all duration-300 lg:relative lg:z-0',
'fixed inset-y-0 left-0 z-50 isolate flex flex-col border-r transition-all duration-300 lg:relative lg:z-0',
inheritsPageBackground ? 'bg-transparent' : 'bg-card',
// 移动端始终显示完整宽度,桌面端根据 sidebarOpen 切换
'w-64 lg:w-auto',
sidebarOpen ? 'lg:w-64' : 'lg:w-16',
mobileMenuOpen ? 'translate-x-0' : '-translate-x-full lg:translate-x-0'
)}
>
<BackgroundLayer config={sidebarBg} layerId="sidebar" />
{!inheritsPageBackground && <BackgroundLayer config={sidebarBg} layerId="sidebar" />}
{/* Logo 区域 */}
<LogoArea sidebarOpen={sidebarOpen} />
<div className="relative z-10">
<LogoArea sidebarOpen={sidebarOpen} />
</div>
<ScrollArea className={cn(
'relative z-10',
"flex-1 overflow-x-hidden",
!sidebarOpen && "lg:w-16"
)}>