Files
xiaoxia-saas/apps/web/src/components/layout/MainLayout.tsx
T
xiaoxia 0fcb77b991
CI Build & Deploy Pipeline / Staging E2E Tests (push) Failing after 2m50s
CI Build & Deploy Pipeline / Production Browser E2E (push) Failing after 1437h19m24s
CI Build & Deploy Pipeline / Build Production Web Image (push) Failing after 1437h19m26s
CI Build & Deploy Pipeline / Deploy Production (push) Failing after 1437h19m25s
CI Build & Deploy Pipeline / Build Production API Image (push) Failing after 1437h19m26s
CI/CD Pipeline / Check if frontend-only change (push) Failing after 1437h21m16s
CI Build & Deploy Pipeline / Build Staging API Image (push) Has been skipped
CI Build & Deploy Pipeline / Build Staging Web Image (push) Has been skipped
CI Build & Deploy Pipeline / Build Staging Worker Image (push) Has been skipped
CI Build & Deploy Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Has been skipped
CI Build & Deploy Pipeline / Staging API Integration Tests (push) Has been skipped
CI Build & Deploy Pipeline / Build Production Worker Image (push) Failing after 1437h51m29s
CI/CD Pipeline / Validate Code Quality And Tests (push) Has been skipped
CI/CD Pipeline / Unit Tests (push) Has been skipped
CI/CD Pipeline / Integration Tests (push) Has been skipped
CI/CD Pipeline / Frontend Lint (push) Has been skipped
ci: Prettier纳入两层防御体系 (#520)
Co-authored-by: xiaoxia <dev@xiaoxiajianji.com>
Co-committed-by: xiaoxia <dev@xiaoxiajianji.com>
2026-07-18 18:08:19 +08:00

65 lines
2.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* MainLayout - 主布局组件(Task 1.2)
*
* 三栏布局:左侧侧边栏 + 顶部导航栏 + 主内容区
* - 侧边栏:240px 固定宽度,可折叠至 64px 图标栏
* - 顶部导航:复用 Header 组件(68px 固定高度)
* - 主内容区:自适应填充剩余空间
* - 响应式:移动端(<768px)隐藏侧边栏
*
* 侧边栏/导航具体内容 deferred to Tasks 1.3, 1.4
*/
import React, { useState } from "react"
import { MenuFoldOutlined, MenuUnfoldOutlined } from "@ant-design/icons"
import AppLayout from "./AppLayout"
import Sidebar from "./Sidebar"
import "./MainLayout.css"
/** 侧边栏上下文 —— 子组件可读取折叠状态 */
export interface SidebarContextValue {
collapsed: boolean
}
// eslint-disable-next-line react-refresh/only-export-components
export const SidebarContext = React.createContext<SidebarContextValue>({
collapsed: false,
})
const MainLayout: React.FC = () => {
// 移动端默认折叠,桌面端默认展开
const [collapsed, setCollapsed] = useState(() => window.innerWidth <= 768)
const sidebar = (
<>
{/* 移动端遮罩层 —— 仅在侧边栏展开时由 CSS 显示 */}
<div className="xx-sidebar-overlay" onClick={() => setCollapsed(true)} aria-hidden="true" />
<aside className={`xx-app-sidebar${collapsed ? " xx-collapsed" : ""}`} aria-label="侧边栏">
<div className="xx-sidebar-toggle">
<button
type="button"
onClick={() => setCollapsed((prev) => !prev)}
aria-label={collapsed ? "展开侧边栏" : "收起侧边栏"}
>
{collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}
<span className="xx-sidebar-toggle-label">{collapsed ? "展开" : "收起"}</span>
</button>
</div>
{/* 侧边栏导航 */}
<nav className="xx-sidebar-content" aria-label="侧边栏导航">
<Sidebar />
</nav>
</aside>
</>
)
return (
<SidebarContext.Provider value={{ collapsed }}>
<AppLayout sidebar={sidebar} />
</SidebarContext.Provider>
)
}
export default MainLayout