useTabStack.ts
2.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// REQ-USR-003: 顶栏标签栈逻辑(复刻原型 tabsOpen/openTab/.close,BR4/BR5/BR6)。
// 纯逻辑 hook:只管标签集合 + activeKey;路由跳转由调用方据 routePath 执行。
import { useCallback, useMemo, useState } from 'react';
/** 业务标签 key(跨组件一致的合同级常量) */
export type BizTabKey = 'userlist' | 'userdetail';
export type TabKey = 'home' | BizTabKey;
export interface TabItem {
key: string;
title: string;
closable: boolean;
routePath: string;
}
/** 固定主页标签:不可关闭,恒在最左 */
export const HOME_TAB: TabItem = {
key: 'home',
title: '主页',
closable: false,
routePath: '/',
};
/** 业务标签定义(标题 / 路由 / 可关闭) */
export const BIZ_TABS: Record<BizTabKey, TabItem> = {
userlist: { key: 'userlist', title: '用户列表', closable: true, routePath: '/usr/users' },
userdetail: { key: 'userdetail', title: '用户信息单据', closable: true, routePath: '/usr/users/new' },
};
export interface TabStack {
tabs: TabItem[];
activeKey: string;
openTab: (key: BizTabKey) => void;
closeTab: (key: string) => void;
setActive: (key: string) => void;
}
export function useTabStack(): TabStack {
// 已打开的业务标签集合(home 恒在,不入此集合)
const [userlistOpen, setUserlistOpen] = useState(false);
const [userdetailOpen, setUserdetailOpen] = useState(false);
const [activeKey, setActiveKey] = useState<string>('home');
const tabs = useMemo<TabItem[]>(() => {
const list: TabItem[] = [HOME_TAB];
if (userlistOpen) list.push(BIZ_TABS.userlist);
if (userdetailOpen) list.push(BIZ_TABS.userdetail);
return list;
}, [userlistOpen, userdetailOpen]);
const openTab = useCallback((key: BizTabKey) => {
if (key === 'userlist') {
setUserlistOpen(true);
setActiveKey('userlist');
} else if (key === 'userdetail') {
// 打开单据前先确保用户列表存在(BR6)
setUserlistOpen(true);
setUserdetailOpen(true);
setActiveKey('userdetail');
}
}, []);
const closeTab = useCallback((key: string) => {
if (key === 'userlist') {
// 关用户列表联动关用户信息单据并回主页(BR5)
setUserlistOpen(false);
setUserdetailOpen(false);
setActiveKey('home');
} else if (key === 'userdetail') {
// 关用户信息单据回用户列表
setUserdetailOpen(false);
setActiveKey('userlist');
}
}, []);
const setActive = useCallback((key: string) => {
setActiveKey(key);
}, []);
return { tabs, activeKey, openTab, closeTab, setActive };
}