Skip to content

Commit

Permalink
feat(Multitab): 新增路由多标签页显示
Browse files Browse the repository at this point in the history
  • Loading branch information
baiwumm committed Jan 16, 2025
1 parent 25932c2 commit 3c55f39
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 30 deletions.
60 changes: 32 additions & 28 deletions src/components/GlobalHeader/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* @Author: 白雾茫茫丶<baiwumm.com>
* @Date: 2024-12-10 11:01:36
* @LastEditors: 白雾茫茫丶<baiwumm.com>
* @LastEditTime: 2025-01-15 16:08:43
* @LastEditTime: 2025-01-16 14:16:22
* @Description: 头部布局
*/
'use client';
Expand All @@ -15,6 +15,7 @@ import { useTranslations } from 'next-intl';
import BackTop from '@/components/BackTop';
import FullScreen from '@/components/FullScreen';
import LangSwitch from '@/components/LangSwitch';
import Multitab from '@/components/Multitab';
import ThemeModeButton from '@/components/ThemeModeButton';
import { SidebarTrigger } from '@/components/ui/sidebar';
import { MenuIconMap } from '@/constants/icon';
Expand All @@ -28,32 +29,35 @@ export default function GlobalHeader() {
// 菜单列表
const menuList = useUserStore((state) => state.menuList);
return (
<header className="sticky w-full flex gap-4 justify-between items-center top-0 h-16 group-has-[[data-collapsible=icon]]/sidebar-wrapper:h-12 shadow-md dark:shadow-[rgba(255,255,255,.15)] backdrop-blur dark:bg-transparent transition-all px-4 z-50">
<div className="flex items-center gap-2">
<SidebarTrigger className="-ml-1" />
<Divider orientation="vertical" className="mr-2 h-4" />
<Breadcrumbs>
{segments.map((path) => {
const menuItem = menuList.find((item) => item.name === path) as App.SystemManage.Menu;
return (
<BreadcrumbItem
key={path}
startContent={
menuItem?.icon ? <div className="breadcrumb-icon">{MenuIconMap[menuItem.icon]}</div> : undefined
}
>
{t(path as ROUTES_NAME)}
</BreadcrumbItem>
);
})}
</Breadcrumbs>
</div>
<div className="flex">
<FullScreen />
<ThemeModeButton />
<LangSwitch />
<BackTop />
</div>
</header>
<div className="sticky top-0 z-50">
<header className="w-full flex gap-4 justify-between items-center h-16 group-has-[[data-collapsible=icon]]/sidebar-wrapper:h-12 shadow-md dark:shadow-[rgba(255,255,255,.15)] backdrop-blur dark:bg-transparent transition-all px-4">
<div className="flex items-center gap-2">
<SidebarTrigger className="-ml-1" />
<Divider orientation="vertical" className="mr-2 h-4" />
<Breadcrumbs>
{segments.map((path) => {
const menuItem = menuList.find((item) => item.name === path) as App.SystemManage.Menu;
return (
<BreadcrumbItem
key={path}
startContent={
menuItem?.icon ? <div className="breadcrumb-icon">{MenuIconMap[menuItem.icon]}</div> : undefined
}
>
{t(path as ROUTES_NAME)}
</BreadcrumbItem>
);
})}
</Breadcrumbs>
</div>
<div className="flex">
<FullScreen />
<ThemeModeButton />
<LangSwitch />
<BackTop />
</div>
</header>
<Multitab />
</div>
);
}
64 changes: 64 additions & 0 deletions src/components/Multitab/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* @Author: 白雾茫茫丶<baiwumm.com>
* @Date: 2025-01-16 11:06:32
* @LastEditors: 白雾茫茫丶<baiwumm.com>
* @LastEditTime: 2025-01-16 13:43:48
* @Description: 多标签页
*/
import { Tab, Tabs } from '@nextui-org/react';
import { usePathname, useRouter } from 'next/navigation';
import { useTranslations } from 'next-intl';
import { useEffect, useState } from 'react';

import { MenuIconMap } from '@/constants/icon';
import { ROUTES_NAME } from '@/enums';
import { useUserStore } from '@/store/userStore';
export default function Multitab() {
const t = useTranslations('Route');
const router = useRouter();
const pathname = usePathname();
// 当前激活的 key
const [activeKey, setActiveKey] = useState(pathname);
// 当前保存的路由标签
const [routeTabs, setRouteTabs] = useState<string[]>([]);

// 菜单列表
const menuList = useUserStore((state) => state.menuList);

// 切换 Tab 标签页回调
const handleChangeTab = (key: string) => {
setActiveKey(key);
router.push(key);
};

useEffect(() => {
setActiveKey(pathname);
if (!routeTabs.includes(pathname)) {
setRouteTabs([...routeTabs, pathname]);
}
}, [pathname]);
return routeTabs.length && menuList.length ? (
<Tabs
aria-label="Multitab"
size="sm"
radius="sm"
selectedKey={activeKey}
onSelectionChange={(key) => handleChangeTab(key as string)}
>
{routeTabs.map((route) => {
const menuItem = menuList.find((item) => item.path === route) as App.SystemManage.Menu;
return (
<Tab
key={route}
title={
<div className="flex items-center space-x-2">
{MenuIconMap[menuItem?.icon]}
<span>{t(menuItem?.name as ROUTES_NAME)}</span>
</div>
}
/>
);
})}
</Tabs>
) : null;
}
8 changes: 6 additions & 2 deletions src/components/NavMain/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
* @Author: 白雾茫茫丶<baiwumm.com>
* @Date: 2024-12-06 14:47:26
* @LastEditors: 白雾茫茫丶<baiwumm.com>
* @LastEditTime: 2025-01-15 15:59:51
* @LastEditTime: 2025-01-16 13:39:41
* @Description: 菜单布局
*/
'use client';
import { RiArrowRightSLine } from '@remixicon/react';
import { useRequest } from 'ahooks';
import { usePathname, useRouter } from 'next/navigation';
import { useTranslations } from 'next-intl';
import { useState } from 'react';
import { useEffect, useState } from 'react';

import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible';
import {
Expand Down Expand Up @@ -54,6 +54,10 @@ export default function NavMain() {
router.push(path);
setActiveKey(path);
};

useEffect(() => {
setActiveKey(pathname);
}, [pathname]);
return (
<SidebarGroup>
<SidebarMenu>
Expand Down

0 comments on commit 3c55f39

Please sign in to comment.