将导航栏展开收起按钮移至顶栏

This commit is contained in:
JSR
2026-03-18 21:54:10 +08:00
parent 87bdfcef7c
commit 8a8cfeac2e
3 changed files with 72 additions and 46 deletions
+23 -1
View File
@@ -53,6 +53,7 @@ function MainContent(): React.JSX.Element {
const [authLoading, setAuthLoading] = useState(false) const [authLoading, setAuthLoading] = useState(false)
const [isPortraitMode, setIsPortraitMode] = useState(false) const [isPortraitMode, setIsPortraitMode] = useState(false)
const [sidebarCollapsed, setSidebarCollapsed] = useState(false) const [sidebarCollapsed, setSidebarCollapsed] = useState(false)
const [floatingSidebarExpanded, setFloatingSidebarExpanded] = useState(false)
const activeMenu = useMemo(() => { const activeMenu = useMemo(() => {
const p = location.pathname const p = location.pathname
@@ -143,10 +144,12 @@ function MainContent(): React.JSX.Element {
await api.windowSetResizable(false) await api.windowSetResizable(false)
await api.windowResize(940, 1600) await api.windowResize(940, 1600)
setSidebarCollapsed(true) setSidebarCollapsed(true)
setFloatingSidebarExpanded(false)
} else { } else {
await api.windowSetResizable(true) await api.windowSetResizable(true)
await api.windowResize(2560, 1440) await api.windowResize(2560, 1440)
setSidebarCollapsed(false) setSidebarCollapsed(false)
setFloatingSidebarExpanded(false)
} }
setIsPortraitMode(nextPortraitMode) setIsPortraitMode(nextPortraitMode)
} catch (error) { } catch (error) {
@@ -155,6 +158,20 @@ function MainContent(): React.JSX.Element {
} }
} }
useEffect(() => {
if (!isPortraitMode || !sidebarCollapsed) {
setFloatingSidebarExpanded(false)
}
}, [isPortraitMode, sidebarCollapsed])
const toggleSidebar = () => {
if (isPortraitMode && sidebarCollapsed) {
setFloatingSidebarExpanded((prev) => !prev)
return
}
setSidebarCollapsed((prev) => !prev)
}
const isDark = currentTheme?.mode === "dark" const isDark = currentTheme?.mode === "dark"
const brandColor = currentTheme?.config?.tdesign?.brandColor || "#0052D9" const brandColor = currentTheme?.config?.tdesign?.brandColor || "#0052D9"
@@ -175,7 +192,8 @@ function MainContent(): React.JSX.Element {
onMenuChange={onMenuChange} onMenuChange={onMenuChange}
collapsed={sidebarCollapsed} collapsed={sidebarCollapsed}
floatingExpand={isPortraitMode} floatingExpand={isPortraitMode}
onCollapsedChange={setSidebarCollapsed} floatingExpanded={floatingSidebarExpanded}
onFloatingExpandedChange={setFloatingSidebarExpanded}
/> />
<ContentArea <ContentArea
permission={permission} permission={permission}
@@ -183,6 +201,10 @@ function MainContent(): React.JSX.Element {
onAuthClick={() => setAuthVisible(true)} onAuthClick={() => setAuthVisible(true)}
onLogout={logout} onLogout={logout}
isPortraitMode={isPortraitMode} isPortraitMode={isPortraitMode}
sidebarCollapsed={sidebarCollapsed}
floatingExpand={isPortraitMode}
floatingExpanded={floatingSidebarExpanded}
onToggleSidebar={toggleSidebar}
onToggleOrientation={toggleOrientationMode} onToggleOrientation={toggleOrientationMode}
/> />
+38
View File
@@ -1,5 +1,6 @@
import React, { Suspense, lazy, useEffect } from "react" import React, { Suspense, lazy, useEffect } from "react"
import { Layout, Space, Button, Tag, Spin } from "antd" import { Layout, Space, Button, Tag, Spin } from "antd"
import { MenuFoldOutlined, MenuUnfoldOutlined } from "@ant-design/icons"
import { Routes, Route, Navigate } from "react-router-dom" import { Routes, Route, Navigate } from "react-router-dom"
import { useTranslation } from "react-i18next" import { useTranslation } from "react-i18next"
import { WindowControls } from "./WindowControls" import { WindowControls } from "./WindowControls"
@@ -46,6 +47,10 @@ interface ContentAreaProps {
onAuthClick: () => void onAuthClick: () => void
onLogout: () => void onLogout: () => void
isPortraitMode: boolean isPortraitMode: boolean
sidebarCollapsed: boolean
floatingExpand: boolean
floatingExpanded: boolean
onToggleSidebar: () => void
onToggleOrientation: () => void onToggleOrientation: () => void
} }
@@ -55,6 +60,10 @@ export function ContentArea({
onAuthClick, onAuthClick,
onLogout, onLogout,
isPortraitMode, isPortraitMode,
sidebarCollapsed,
floatingExpand,
floatingExpanded,
onToggleSidebar,
onToggleOrientation, onToggleOrientation,
}: ContentAreaProps): React.JSX.Element { }: ContentAreaProps): React.JSX.Element {
const { t } = useTranslation() const { t } = useTranslation()
@@ -115,6 +124,35 @@ export function ContentArea({
} as React.CSSProperties } as React.CSSProperties
} }
> >
<div
style={
{
paddingLeft: "8px",
display: "flex",
alignItems: "center",
height: "100%",
WebkitAppRegion: "no-drag",
flexShrink: 0,
} as React.CSSProperties
}
>
<Button
type="text"
size="small"
onClick={onToggleSidebar}
icon={
floatingExpand && sidebarCollapsed
? floatingExpanded
? <MenuFoldOutlined />
: <MenuUnfoldOutlined />
: sidebarCollapsed
? <MenuUnfoldOutlined />
: <MenuFoldOutlined />
}
title={sidebarCollapsed ? "展开导航栏" : "收起导航栏"}
style={{ width: "32px", height: "32px" }}
/>
</div>
<div <div
data-tauri-drag-region data-tauri-drag-region
style={ style={
+11 -45
View File
@@ -9,8 +9,6 @@ import {
FileTextOutlined, FileTextOutlined,
CloudOutlined, CloudOutlined,
UploadOutlined, UploadOutlined,
MenuFoldOutlined,
MenuUnfoldOutlined,
} from "@ant-design/icons" } from "@ant-design/icons"
import { useState, useEffect } from "react" import { useState, useEffect } from "react"
import { useTranslation } from "react-i18next" import { useTranslation } from "react-i18next"
@@ -24,7 +22,8 @@ interface SidebarProps {
onMenuChange: (value: string) => void onMenuChange: (value: string) => void
collapsed: boolean collapsed: boolean
floatingExpand: boolean floatingExpand: boolean
onCollapsedChange: (collapsed: boolean) => void floatingExpanded: boolean
onFloatingExpandedChange: (expanded: boolean) => void
} }
interface DbStatus { interface DbStatus {
@@ -39,10 +38,10 @@ export function Sidebar({
onMenuChange, onMenuChange,
collapsed, collapsed,
floatingExpand, floatingExpand,
onCollapsedChange, floatingExpanded,
onFloatingExpandedChange,
}: SidebarProps): React.JSX.Element { }: SidebarProps): React.JSX.Element {
const { t } = useTranslation() const { t } = useTranslation()
const [floatingExpanded, setFloatingExpanded] = useState(false)
const [dbStatus, setDbStatus] = useState<DbStatus>({ type: "sqlite", connected: true }) const [dbStatus, setDbStatus] = useState<DbStatus>({ type: "sqlite", connected: true })
const [syncLoading, setSyncLoading] = useState(false) const [syncLoading, setSyncLoading] = useState(false)
const [messageApi, contextHolder] = message.useMessage() const [messageApi, contextHolder] = message.useMessage()
@@ -107,9 +106,9 @@ export function Sidebar({
useEffect(() => { useEffect(() => {
if (!floatingExpand || !collapsed) { if (!floatingExpand || !collapsed) {
setFloatingExpanded(false) onFloatingExpandedChange(false)
} }
}, [floatingExpand, collapsed]) }, [floatingExpand, collapsed, onFloatingExpandedChange])
const handleForceSync = async () => { const handleForceSync = async () => {
if (!(window as any).api) return if (!(window as any).api) return
@@ -193,53 +192,20 @@ export function Sidebar({
const showFloatingPanel = floatingExpand && collapsed && floatingExpanded const showFloatingPanel = floatingExpand && collapsed && floatingExpanded
const renderSidebarBody = ( const renderSidebarBody = (isCollapsedView: boolean, hideMenu = false) => (
isCollapsedView: boolean,
isFloatingPanel = false,
hideMenu = false
) => (
<> <>
<div <div
data-tauri-drag-region data-tauri-drag-region
style={ style={
{ {
padding: isCollapsedView ? "24px 8px 12px" : "32px 24px 16px", padding: isCollapsedView ? "20px 8px 12px" : "24px 24px 16px",
textAlign: "center", textAlign: "center",
WebkitAppRegion: "drag", WebkitAppRegion: "drag",
userSelect: "none", userSelect: "none",
flexShrink: 0, flexShrink: 0,
position: "relative",
} as React.CSSProperties } as React.CSSProperties
} }
> >
<Button
type="text"
size="small"
onClick={() => {
if (floatingExpand && collapsed) {
setFloatingExpanded((prev) => !prev)
return
}
onCollapsedChange(!collapsed)
}}
icon={
floatingExpand && collapsed
? isFloatingPanel
? <MenuFoldOutlined />
: <MenuUnfoldOutlined />
: isCollapsedView
? <MenuUnfoldOutlined />
: <MenuFoldOutlined />
}
style={
{
position: "absolute",
top: "8px",
right: "8px",
WebkitAppRegion: "no-drag",
} as React.CSSProperties
}
/>
<img <img
src={appLogo} src={appLogo}
style={{ style={{
@@ -283,7 +249,7 @@ export function Sidebar({
onClick={({ key }) => { onClick={({ key }) => {
onMenuChange(key) onMenuChange(key)
if (floatingExpand && collapsed) { if (floatingExpand && collapsed) {
setFloatingExpanded(false) onFloatingExpandedChange(false)
} }
}} }}
style={{ style={{
@@ -376,7 +342,7 @@ export function Sidebar({
theme="light" theme="light"
> >
{contextHolder} {contextHolder}
{renderSidebarBody(collapsed, false, showFloatingPanel)} {renderSidebarBody(collapsed, showFloatingPanel)}
{showFloatingPanel && ( {showFloatingPanel && (
<div <div
@@ -394,7 +360,7 @@ export function Sidebar({
flexDirection: "column", flexDirection: "column",
}} }}
> >
{renderSidebarBody(false, true)} {renderSidebarBody(false)}
</div> </div>
)} )}
</Sider> </Sider>