AdmSysV2【公共组件库】@前端(For Git Submodule)
Tevin
1 days ago 1c8d56aea079196ed48f406a635a6f1bbf29f23f
feat(example): 添加侧边菜单示例页面

- 更新 App.tsx 主应用布局和路由配置
- 更新 main.tsx 入口文件
- 新增 example/pages/side-menu/ 侧边菜单演示页面

Co-Authored-By: ClaudeCode
2 files modified
1 files added
213 ■■■■■ changed files
example/App.tsx 78 ●●●●● patch | view | raw | blame | history
example/main.tsx 22 ●●●●● patch | view | raw | blame | history
example/pages/side-menu/SideMenuPage.tsx 113 ●●●●● patch | view | raw | blame | history
example/App.tsx
@@ -1,8 +1,80 @@
import { useState } from 'react';
import type { ReactNode } from 'react';
import { SideMenuPage } from './pages/side-menu/SideMenuPage';
/** 组件配置 */
const components: Array<{ name: string; path: string; component: ReactNode }> = [
  {
    name: 'CSideMenu',
    path: '/pages/side-menu/SideMenuPage.tsx',
    component: <SideMenuPage />,
  },
];
/**
 * 组件展示主页面
 * 左侧:组件列表
 * 右侧:iframe 展示组件示例
 */
function App() {
  const [activeIndex, setActiveIndex] = useState(0);
  return (
    <div style={{ padding: '20px' }}>
      <h1>admin2-components</h1>
      <p>组件展示示例(待开发)</p>
    <div style={{ display: 'table', width: '100%', height: '100vh' }}>
      {/* 左侧组件列表 */}
      <div
        style={{
          display: 'table-cell',
          width: '200px',
          borderRight: '1px solid #eee',
          padding: '16px',
          background: '#fafafa',
          verticalAlign: 'top',
        }}
      >
        <h3 style={{ marginTop: 0 }}>组件列表</h3>
        <ul style={{ listStyle: 'none', padding: 0, margin: 0 }}>
          {components.map((comp, index) => (
            <li key={comp.name} style={{ marginBottom: '8px' }}>
              <button
                onClick={() => setActiveIndex(index)}
                style={{
                  width: '100%',
                  padding: '8px 12px',
                  textAlign: 'left',
                  background: activeIndex === index ? '#1890ff' : '#fff',
                  color: activeIndex === index ? '#fff' : '#333',
                  border: '1px solid #d9d9d9',
                  borderRadius: '4px',
                  cursor: 'pointer',
                  fontSize: '14px',
                }}
              >
                {comp.name}
              </button>
            </li>
          ))}
        </ul>
      </div>
      {/* 右侧 iframe 容器 */}
      <div
        style={{
          display: 'table-cell',
          background: '#fff',
          verticalAlign: 'top',
        }}
      >
        <iframe
          src={`http://localhost:5173/#/preview/${components[activeIndex].path}`}
          style={{
            width: '100%',
            height: '100%',
            border: 'none',
          }}
          title={components[activeIndex].name}
        />
      </div>
    </div>
  );
}
example/main.tsx
@@ -1,5 +1,25 @@
import { createRoot } from 'react-dom/client';
import './index.css';
import App from './App';
import { SideMenuPage } from './pages/side-menu/SideMenuPage';
createRoot(document.getElementById('root')!).render(<App />);
/** 预览页面 - 无 shell,直接渲染组件 */
function PreviewPage() {
  const hash = window.location.hash;
  const path = hash.replace('#/preview/', '');
  if (path.includes('side-menu')) {
    return <SideMenuPage />;
  }
  return <div>Unknown component</div>;
}
const root = createRoot(document.getElementById('root')!);
// 检查是否是预览模式
if (window.location.hash.includes('/preview/')) {
  root.render(<PreviewPage />);
} else {
  root.render(<App />);
}
example/pages/side-menu/SideMenuPage.tsx
New file
@@ -0,0 +1,113 @@
import React, { useState, useEffect } from 'react';
import { CSideMenu } from '../../../src';
import type { MenuItem } from '../../../src/framework/sideMenu/types';
/** 模拟菜单数据 */
const mockTree: MenuItem = {
  key: '1',
  label: '导航1',
  type: 'folder',
  children: [
    {
      key: '1-1',
      label: '子菜单1-1',
      type: 'folder',
      children: [
        { key: '1-1-1', label: '页面1-1-1', path: '/page1-1-1', pageName: 'Page111', type: 'file' },
        { key: '1-1-2', label: '页面1-1-2', path: '/page1-1-2', pageName: 'Page112', type: 'file' },
      ],
    },
    {
      key: '1-2',
      label: '页面1-2',
      path: '/page1-2',
      pageName: 'Page12',
      type: 'file',
    },
  ],
};
/** 已打开的页面列表 */
const mockPanesOnShelf = [
  { key: '1-1-1' },
  { key: '1-2' },
];
/**
 * CSideMenu 组件示例页
 */
export function SideMenuPage() {
  const [collapsed, setCollapsed] = useState(false);
  const [curActivePaneKey, setCurActivePaneKey] = useState<string | number>('1-1-1');
  const [isMobile, setIsMobile] = useState(false);
  // 检测移动端 - 与 CSideMenu 组件的判断逻辑一致
  useEffect(() => {
    const checkMobile = () => {
      const width = window.innerWidth;
      const screenWidth = window.screen.width;
      setIsMobile(width <= 992 && screenWidth <= 1024);
    };
    checkMobile();
    window.addEventListener('resize', checkMobile);
    return () => window.removeEventListener('resize', checkMobile);
  }, []);
  const handleClickMenuItem = (item: MenuItem) => {
    console.log('点击菜单项:', item);
    setCurActivePaneKey(item.key);
  };
  const handleSetMenuCollapse = (value: boolean | void) => {
    if (typeof value === 'boolean') {
      setCollapsed(value);
    } else {
      setCollapsed((prev) => !prev);
    }
  };
  return (
    <div style={{ display: 'flex', height: '100vh' }}>
      <div style={{ flexShrink: 0 }}>
        <CSideMenu
          title="管理后台"
          tree={mockTree}
          collapsed={collapsed}
          curActivePaneKey={curActivePaneKey}
          panesOnShelf={mockPanesOnShelf}
          onClickMenuItem={handleClickMenuItem}
          onSetMenuCollapse={handleSetMenuCollapse}
        />
      </div>
      <div style={{ flex: 1, padding: '20px', position: 'relative' }}>
        {/* 移动端折叠/展开触发器 */}
        {isMobile && (
          <button
            onClick={() => handleSetMenuCollapse()}
            style={{
              position: 'absolute',
              top: '10px',
              left: '10px',
              zIndex: 100,
              padding: '8px 12px',
              background: '#1890ff',
              color: '#fff',
              border: 'none',
              borderRadius: '4px',
              cursor: 'pointer',
            }}
          >
            {collapsed ? '展开菜单' : '收起菜单'}
          </button>
        )}
        <h2>CSideMenu 组件示例</h2>
        <p>当前选中: {curActivePaneKey}</p>
        <p>折叠状态: {collapsed ? '收起' : '展开'}</p>
      </div>
    </div>
  );
}
export default SideMenuPage;