Files
xiaoxia-saas/apps/web/src/components/layout/MainLayout.tsx
T
xiaoxia 0fcb77b991
CI/CD Pipeline / Check if frontend-only change (push) Has been skipped
CI/CD Pipeline / Frontend Lint (push) Successful in 1m6s
CI Build & Deploy Pipeline / Build Staging Web Image (push) Successful in 1m49s
CI Build & Deploy Pipeline / Build Production API Image (push) Has been skipped
CI Build & Deploy Pipeline / Build Production Web Image (push) Has been skipped
CI Build & Deploy Pipeline / Build Production Worker Image (push) Has been skipped
CI Build & Deploy Pipeline / Deploy Production (push) Has been skipped
CI Build & Deploy Pipeline / Production Browser E2E (push) Has been skipped
CI/CD Pipeline / Validate Code Quality And Tests (push) Successful in 3m1s
CI/CD Pipeline / Unit Tests (push) Successful in 3m20s
CI/CD Pipeline / Integration Tests (push) Successful in 1m29s
CI Build & Deploy Pipeline / Build Staging API Image (push) Successful in 7m4s
CI Build & Deploy Pipeline / Build Staging Worker Image (push) Successful in 7m54s
CI Build & Deploy Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Successful in 45s
CI Build & Deploy Pipeline / Staging E2E Tests (push) Failing after 2m50s
CI Build & Deploy Pipeline / Staging API Integration Tests (push) Successful in 3m28s
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