Переглянути джерело

fix(SplitLayout): 修复右边栏拖拽失效,正文限宽居中

- lazy 模式下拖拽只触发 onResizeEnd,补上该回调,松手后宽度不再回弹
- 右边栏默认宽度 500 -> 400
- 正文区包一层 .centerInner,最大宽度默认 1000px 并居中,
  右边栏弹出只占用两侧留白,不再引起正文重排;
  新增 contentMaxWidth prop(<=0 表示不限宽)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017yTwQRLgLC6gPT71JtDiNb
visuddhinanda 1 тиждень тому
батько
коміт
64bc1a5dc7

+ 12 - 0
dashboard-v6/src/components/general/SplitLayout/SplitLayout.module.css

@@ -79,6 +79,18 @@
 .centerPanel {
 .centerPanel {
   overflow: hidden;
   overflow: hidden;
   height: 100%;
   height: 100%;
+  /* 让内容区居中,两侧留白;右边栏弹出时正文宽度不变,避免重排 */
+  display: flex;
+  justify-content: center;
+}
+
+/* 正文容器:限制最大宽度,宽屏时两侧留白 */
+.centerInner {
+  flex: 1;
+  min-width: 0;
+  max-width: var(--split-layout-content-max-width, 1000px);
+  height: 100%;
+  overflow: hidden;
 }
 }
 
 
 /* 展开按钮(由中间内容区组件放置) */
 /* 展开按钮(由中间内容区组件放置) */

+ 31 - 5
dashboard-v6/src/components/general/SplitLayout/SplitLayout.tsx

@@ -1,6 +1,11 @@
 import { MenuFoldOutlined, MenuUnfoldOutlined } from "@ant-design/icons";
 import { MenuFoldOutlined, MenuUnfoldOutlined } from "@ant-design/icons";
 import { Affix, Button, Popover, Splitter } from "antd";
 import { Affix, Button, Popover, Splitter } from "antd";
-import { useCallback, useState, type ReactNode } from "react";
+import {
+  useCallback,
+  useState,
+  type CSSProperties,
+  type ReactNode,
+} from "react";
 import RightToolbar, { type RightToolbarTab } from "./RightToolbar";
 import RightToolbar, { type RightToolbarTab } from "./RightToolbar";
 import styles from "./SplitLayout.module.css";
 import styles from "./SplitLayout.module.css";
 import {
 import {
@@ -66,12 +71,19 @@ export interface SplitLayoutProps {
    */
    */
   openRequest?: { key: string; seq: number };
   openRequest?: { key: string; seq: number };
 
 
-  /** 右边栏面板默认宽度(px),默认 500 */
+  /** 右边栏面板默认宽度(px),默认 400 */
   defaultRightSize?: number;
   defaultRightSize?: number;
   /** 右边栏面板最小宽度(px),默认 280 */
   /** 右边栏面板最小宽度(px),默认 280 */
   minRightSize?: number;
   minRightSize?: number;
   /** 右边栏面板最大宽度(px),默认 800 */
   /** 右边栏面板最大宽度(px),默认 800 */
   maxRightSize?: number;
   maxRightSize?: number;
+
+  /**
+   * 正文区最大宽度(px),默认 1000。
+   * 正文居中显示,宽屏时两侧留白,右边栏弹出/收起不会导致正文重排。
+   * 传 0 或负数表示不限制(占满可用宽度)。
+   */
+  contentMaxWidth?: number;
 }
 }
 
 
 // ─────────────────────────────────────────────
 // ─────────────────────────────────────────────
@@ -84,9 +96,10 @@ export default function SplitLayout({
   children,
   children,
   rightTabs,
   rightTabs,
   openRequest,
   openRequest,
-  defaultRightSize = 500,
+  defaultRightSize = 400,
   minRightSize = 280,
   minRightSize = 280,
   maxRightSize = 800,
   maxRightSize = 800,
+  contentMaxWidth = 1000,
 }: SplitLayoutProps) {
 }: SplitLayoutProps) {
   // ── 左侧收起状态(持久化)──
   // ── 左侧收起状态(持久化)──
   const [collapsed, setCollapsed] = useState<boolean>(() => {
   const [collapsed, setCollapsed] = useState<boolean>(() => {
@@ -161,6 +174,12 @@ export default function SplitLayout({
   const centerContent =
   const centerContent =
     typeof children === "function" ? children({ expandButton }) : children;
     typeof children === "function" ? children({ expandButton }) : children;
 
 
+  // 正文最大宽度(<=0 表示不限制)
+  const contentMaxWidthStyle = {
+    "--split-layout-content-max-width":
+      contentMaxWidth > 0 ? `${contentMaxWidth}px` : "none",
+  } as CSSProperties;
+
   // ── 右边栏面板宽度(持久化)──
   // ── 右边栏面板宽度(持久化)──
   const [rightPanelWidth, setRightPanelWidth] = useState<number>(() => {
   const [rightPanelWidth, setRightPanelWidth] = useState<number>(() => {
     try {
     try {
@@ -234,10 +253,13 @@ export default function SplitLayout({
               lazy
               lazy
               className={styles.splitter}
               className={styles.splitter}
               onResize={handleSplitterResize}
               onResize={handleSplitterResize}
+              onResizeEnd={handleSplitterResize}
             >
             >
               {/* 中间内容 */}
               {/* 中间内容 */}
               <Splitter.Panel className={styles.centerPanel}>
               <Splitter.Panel className={styles.centerPanel}>
-                {centerContent}
+                <div className={styles.centerInner} style={contentMaxWidthStyle}>
+                  {centerContent}
+                </div>
               </Splitter.Panel>
               </Splitter.Panel>
 
 
               {/* 右边栏:RightToolbar 内部管理面板的懒创建与隐藏 */}
               {/* 右边栏:RightToolbar 内部管理面板的懒创建与隐藏 */}
@@ -259,7 +281,11 @@ export default function SplitLayout({
               </Splitter.Panel>
               </Splitter.Panel>
             </Splitter>
             </Splitter>
           ) : (
           ) : (
-            <div className={styles.centerPanel}>{centerContent}</div>
+            <div className={styles.centerPanel}>
+              <div className={styles.centerInner} style={contentMaxWidthStyle}>
+                {centerContent}
+              </div>
+            </div>
           )}
           )}
         </div>
         </div>
       </div>
       </div>