diff --git a/AGENTS.md b/AGENTS.md index 6a98462..1ca699f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -61,7 +61,7 @@ ## UI 规范(antd/pro) -- 页面标题右侧的操作按钮与标题底部对齐(Layout 页头槽内联样式控制,勿在其他位置另造对齐方式)。 +- 页面标题与操作按钮各占一行:标题用 PageContainer 自带 `title`/`subTitle`,按钮经 `usePageActions` 注册到 Layout 页头 content 槽(`Flex justify="flex-end"`),不写自定义对齐样式,勿在其他位置另造对齐方式。 - 页面级操作按钮通过 `usePageActions` 注册到页头槽,不得在卡片内重复渲染。 - 弃用 API 禁止回潮:`Alert` 用 `title`/`description`(非 `message`)、纵向堆叠用 `Flex vertical`(非 `Space direction`)、静态 `message.xxx` 改 `App.useApp()`。以 `antd lint` 结果为准。 diff --git a/web/src/components/PageActions.tsx b/web/src/components/PageActions.tsx index c7a6629..a750d54 100644 --- a/web/src/components/PageActions.tsx +++ b/web/src/components/PageActions.tsx @@ -1,7 +1,7 @@ import { createContext, useContext, useEffect } from 'react'; import type { ReactNode } from 'react'; -// 页头动作槽:页面挂载时把自己的操作按钮注册到布局 PageContainer 的 extra(与标题同一行), +// 页头动作槽:页面挂载时把自己的操作按钮注册到布局 PageContainer 的 content(标题下方独立操作行,右侧对齐), // 卸载时自动清除。Layout 提供 Provider,页面只消费 usePageActions。 const PageActionsContext = createContext<(node: ReactNode) => void>(() => {}); diff --git a/web/src/layouts/index.tsx b/web/src/layouts/index.tsx index a53faee..ec21af3 100644 --- a/web/src/layouts/index.tsx +++ b/web/src/layouts/index.tsx @@ -2,7 +2,7 @@ import { useState } from 'react'; import type { ReactNode } from 'react'; import { history, Outlet, useLocation } from '@umijs/max'; import { PageContainer, ProLayout } from '@ant-design/pro-components'; -import { App, Dropdown, Typography } from 'antd'; +import { App, Dropdown, Flex } from 'antd'; import { LogoutOutlined } from '@ant-design/icons'; import { PageActionsContext } from '@/components/PageActions'; import { menu, menuSelectedKey, pageMetadata } from '@/utils/metadata'; @@ -12,7 +12,7 @@ import { menu, menuSelectedKey, pageMetadata } from '@/utils/metadata'; // (渲染器不传 children prop,用 children 会导致整页空白且无任何报错)。 export default function Layout() { const location = useLocation(); - // 页头动作槽:列表页在挂载时把自己的添加类按钮注册进来,与标题渲染在同一行。 + // 页头动作槽:列表页在挂载时把自己的添加类按钮注册进来,渲染在标题下方的独立操作行(右侧)。 const [pageActions, setPageActions] = useState(null); if (location.pathname === '/login') return ; @@ -58,20 +58,18 @@ export default function Layout() { ), }} > - {/* 页面标题在卡片外(内容区左上角),动作按钮与标题同一行(右侧);卡片内不再重复渲染标题。 */} + {/* 页面标题在卡片外(内容区左上角),动作按钮单独一行渲染在标题下方(content 槽,右侧对齐);卡片内不再重复渲染标题。 */} {/* App 包裹:App.useApp() 的 message 等实例需要此上下文(component=false 不增加 DOM,避免破坏 ProLayout 布局)。 */} - {meta.title} - {meta.subtitle} - - } - subTitle={false} - // 官方 skill 规范:标题右侧操作按钮底部对齐(PageContainer 的 -row 未设 align-items,默认居中)。 - extra={
{pageActions}
} + title={meta.title} + subTitle={meta.subtitle} + // 全站不展示面包屑导航(官方关闭方式:breadcrumbRender={false})。 + breadcrumbRender={false} + // 标题与操作按钮各占一行:标题走 PageContainer 自带 title/subTitle,按钮走 content 槽, + // 右对齐用 Flex 组件 API,不写自定义对齐样式。 + content={pageActions ? {pageActions} : undefined} >