Просмотр исходного кода

Revert "feat(sidebar): collapse to icon rail, expand on hover"

This reverts commit 573c43e4458239c068db61318f7cf67ce1b1ec38.
MHSanaei 1 день назад
Родитель
Сommit
42d7f62d8b
2 измененных файлов с 27 добавлено и 37 удалено
  1. 0 23
      frontend/src/layouts/AppSidebar.css
  2. 27 14
      frontend/src/layouts/AppSidebar.tsx

+ 0 - 23
frontend/src/layouts/AppSidebar.css

@@ -5,20 +5,6 @@
   align-self: flex-start;
 }
 
-.ant-sidebar.is-rail {
-  flex: 0 0 80px;
-  width: 80px;
-  overflow: visible;
-}
-
-.ant-sidebar.is-rail > .ant-layout-sider {
-  z-index: 100;
-}
-
-.ant-sidebar.is-rail:hover > .ant-layout-sider {
-  box-shadow: 2px 0 16px rgba(0, 0, 0, 0.18);
-}
-
 .sider-brand,
 .drawer-brand {
   font-weight: 600;
@@ -259,15 +245,6 @@
     min-width: 0 !important;
     width: 0 !important;
   }
-
-  .ant-sidebar,
-  .ant-sidebar.is-rail {
-    flex: 0 0 0 !important;
-    width: 0 !important;
-    min-width: 0 !important;
-    max-width: 0 !important;
-    overflow: hidden !important;
-  }
 }
 
 body.dark .ant-drawer-content,

+ 27 - 14
frontend/src/layouts/AppSidebar.tsx

@@ -35,6 +35,7 @@ import { pauseAnimationsUntilLeave, useTheme } from '@/hooks/useTheme';
 import { useAllSettings } from '@/api/queries/useAllSettings';
 import './AppSidebar.css';
 
+const SIDEBAR_COLLAPSED_KEY = 'isSidebarCollapsed';
 const DONATE_URL = 'https://donate.sanaei.dev/';
 const REPO_URL = 'https://github.com/MHSanaei/3x-ui';
 const LOGOUT_KEY = '__logout__';
@@ -53,6 +54,14 @@ const iconByName: Record<IconName, ComponentType> = {
   apidocs: ApiOutlined,
 };
 
+function readCollapsed(): boolean {
+  try {
+    return JSON.parse(localStorage.getItem(SIDEBAR_COLLAPSED_KEY) || 'false');
+  } catch {
+    return false;
+  }
+}
+
 function DonateButton({ ariaLabel }: { ariaLabel: string }) {
   return (
     <a
@@ -116,9 +125,8 @@ export default function AppSidebar() {
   const { allSetting } = useAllSettings();
   const showSubFormats = !!(allSetting.subJsonEnable || allSetting.subClashEnable);
 
-  const [hovered, setHovered] = useState(false);
+  const [collapsed, setCollapsed] = useState<boolean>(() => readCollapsed());
   const [drawerOpen, setDrawerOpen] = useState(false);
-  const collapsedView = !hovered;
 
   const currentTheme: 'light' | 'dark' = isDark ? 'dark' : 'light';
   const panelVersion = window.X_UI_CUR_VER || '';
@@ -202,6 +210,13 @@ export default function AppSidebar() {
     openLink(String(key));
   }, [openLink]);
 
+  const onSiderCollapse = useCallback((isCollapsed: boolean, type: 'clickTrigger' | 'responsive') => {
+    if (type === 'clickTrigger') {
+      localStorage.setItem(SIDEBAR_COLLAPSED_KEY, String(isCollapsed));
+      setCollapsed(isCollapsed);
+    }
+  }, []);
+
   const cycleTheme = useCallback((id: string) => {
     pauseAnimationsUntilLeave(id);
     if (!isDark) {
@@ -216,21 +231,19 @@ export default function AppSidebar() {
   }, [isDark, isUltra, toggleTheme, toggleUltra]);
 
   return (
-    <div
-      className="ant-sidebar is-rail"
-      onMouseEnter={() => setHovered(true)}
-      onMouseLeave={() => setHovered(false)}
-    >
+    <div className="ant-sidebar">
       <Layout.Sider
         theme={currentTheme}
-        collapsed={collapsedView}
-        trigger={null}
+        collapsible
+        collapsed={collapsed}
+        breakpoint="md"
+        onCollapse={onSiderCollapse}
       >
-        <div className={`sider-brand${collapsedView ? ' sider-brand-collapsed' : ''}`}>
+        <div className={`sider-brand${collapsed ? ' sider-brand-collapsed' : ''}`}>
           <div className="brand-block">
-            <span className="brand-text">{collapsedView ? '3X' : '3X-UI'}</span>
+            <span className="brand-text">{collapsed ? '3X' : '3X-UI'}</span>
           </div>
-          {!collapsedView && (
+          {!collapsed && (
             <div className="brand-actions">
               <DonateButton ariaLabel={t('menu.donate') || 'Donate'} />
               <ThemeCycleButton
@@ -247,7 +260,7 @@ export default function AppSidebar() {
           theme={currentTheme}
           mode="inline"
           selectedKeys={[selectedKey]}
-          openKeys={collapsedView ? undefined : openKeys}
+          openKeys={collapsed ? undefined : openKeys}
           onOpenChange={(keys) => setOpenKeys(keys as string[])}
           className="sider-nav"
           items={toMenuItems(navItems)}
@@ -262,7 +275,7 @@ export default function AppSidebar() {
           onClick={onMenuClick}
         />
         <div className="sider-footer">
-          <VersionBadge version={panelVersion} collapsed={collapsedView} />
+          <VersionBadge version={panelVersion} collapsed={collapsed} />
         </div>
       </Layout.Sider>