Shell

主应用布局组件,包含侧边栏和标题栏

概述

Shell 是应用的主布局组件,提供:

  • 顶部标题栏(TitleBar)
  • 侧边栏导航
  • 主内容区域
  • 插槽支持

导入

import { Shell } from '@linch-tech/desktop-core';

Props

interface ShellProps {
  /**
   * 子组件(在 noOutlet 模式下使用)
   */
  children?: ReactNode;

  /**
   * 自定义 className
   */
  className?: string;

  /**
   * 如果为 true,不渲染 Outlet(直接渲染 children)
   */
  noOutlet?: boolean;
}

基本用法

作为路由布局组件使用:

import { Routes, Route } from 'react-router-dom';
import { Shell } from '@linch-tech/desktop-core';

function App() {
  return (
    <Routes>
      <Route element={<Shell />}>
        <Route path="/" element={<Home />} />
        <Route path="/settings" element={<Settings />} />
      </Route>
    </Routes>
  );
}

布局结构

┌─────────────────────────────────────────────────┐
│                   TitleBar                       │
│  [Logo] [App Name]              [Theme] [×]     │
├────────────┬────────────────────────────────────┤
│            │                                    │
│  Sidebar   │         Main Content               │
│            │         (<Outlet />)               │
│  [Nav 1]   │                                    │
│  [Nav 2]   │                                    │
│  [Nav 3]   │                                    │
│            │                                    │
├────────────┤                                    │
│  [Footer]  │                                    │
└────────────┴────────────────────────────────────┘

noOutlet 模式

如果不使用 react-router-dom 的 Outlet,可以使用 noOutlet 模式:

<Shell noOutlet>
  <MyContent />
</Shell>

自定义样式

<Shell className="custom-shell-class" />

配置驱动

Shell 的行为由配置控制:

// src/config.ts
export const config = {
  nav: [
    { title: 'Home', path: '/', icon: Home },
    { title: 'Settings', path: '/settings', icon: Settings },
  ],

  layout: {
    sidebar: {
      width: 200,
      position: 'left',  // 或 'right'
    },
  },

  slots: {
    sidebar: {
      header: <WorkspaceSwitcher />,
      footer: <UserProfile />,
    },
    shell: {
      beforeContent: <AlertBanner />,
    },
  },
};

覆盖 Shell 组件

完全自定义 Shell:

import type { ShellProps } from '@linch-tech/desktop-core';

function CustomShell({ children, className, noOutlet }: ShellProps) {
  return (
    <div className={className}>
      {/* 完全自定义的布局 */}
      <MyCustomSidebar />
      <main>
        {noOutlet ? children : <Outlet />}
      </main>
    </div>
  );
}

// 在配置中使用
export const config = {
  components: {
    Shell: CustomShell,
  },
};

导航项渲染

导航项根据配置自动渲染,支持:

  • 图标
  • 标题(支持 i18n)
  • 徽标
  • 激活状态高亮

自定义导航项组件:

import type { NavItemComponentProps } from '@linch-tech/desktop-core';

function CustomNavItem({ item, isActive, onClick }: NavItemComponentProps) {
  return (
    <button
      onClick={onClick}
      className={isActive ? 'active' : ''}
    >
      <item.icon />
      <span>{item.title}</span>
    </button>
  );
}

export const config = {
  components: {
    NavItem: CustomNavItem,
  },
};

侧边栏插槽

插槽位置
slots.sidebar.header侧边栏顶部
slots.sidebar.beforeNav导航列表前
slots.sidebar.afterNav导航列表后
slots.sidebar.footer侧边栏底部

Shell 插槽

插槽位置
slots.shell.beforeContent主内容区域上方
slots.shell.afterContent主内容区域下方