@zat-design/sisyphus-react 3.13.24-beta.1 → 3.14.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/ProLayout/components/Layout/Menu/FoldMenu/index.js +8 -4
- package/es/ProLayout/components/Layout/Menu/OpenMenu/index.js +39 -28
- package/es/ProLayout/components/TabsManager/components/TabContextMenu.d.ts +7 -0
- package/es/ProLayout/components/TabsManager/components/TabContextMenu.js +96 -0
- package/es/ProLayout/components/TabsManager/components/TabItem.d.ts +26 -0
- package/es/ProLayout/components/TabsManager/components/TabItem.js +61 -0
- package/es/ProLayout/components/TabsManager/components/TabsContext.d.ts +6 -0
- package/es/ProLayout/components/TabsManager/components/TabsContext.js +5 -0
- package/es/ProLayout/components/TabsManager/hooks/useActiveTab.d.ts +6 -0
- package/es/ProLayout/components/TabsManager/hooks/useActiveTab.js +14 -0
- package/es/ProLayout/components/TabsManager/hooks/useProLayoutTabs.d.ts +18 -0
- package/es/ProLayout/components/TabsManager/hooks/useProLayoutTabs.js +26 -0
- package/es/ProLayout/components/TabsManager/hooks/useTabsCache.d.ts +31 -0
- package/es/ProLayout/components/TabsManager/hooks/useTabsCache.js +93 -0
- package/es/ProLayout/components/TabsManager/hooks/useTabsState.d.ts +5 -0
- package/es/ProLayout/components/TabsManager/hooks/useTabsState.js +357 -0
- package/es/ProLayout/components/TabsManager/index.d.ts +8 -0
- package/es/ProLayout/components/TabsManager/index.js +171 -0
- package/es/ProLayout/components/TabsManager/propTypes.d.ts +74 -0
- package/es/ProLayout/components/TabsManager/propTypes.js +16 -0
- package/es/ProLayout/components/TabsManager/style/index.less +179 -0
- package/es/ProLayout/components/TabsManager/utils/index.d.ts +38 -0
- package/es/ProLayout/components/TabsManager/utils/index.js +106 -0
- package/es/ProLayout/index.d.ts +10 -4
- package/es/ProLayout/index.js +82 -9
- package/es/ProLayout/propTypes.d.ts +139 -1
- package/es/ProLayout/propTypes.js +37 -1
- package/es/ProLayout/utils/index.js +8 -5
- package/es/index.d.ts +2 -1
- package/es/index.js +1 -1
- package/lib/ProLayout/components/Layout/Menu/FoldMenu/index.js +8 -4
- package/lib/ProLayout/components/Layout/Menu/OpenMenu/index.js +39 -28
- package/lib/ProLayout/components/TabsManager/components/TabContextMenu.d.ts +7 -0
- package/lib/ProLayout/components/TabsManager/components/TabContextMenu.js +103 -0
- package/lib/ProLayout/components/TabsManager/components/TabItem.d.ts +26 -0
- package/lib/ProLayout/components/TabsManager/components/TabItem.js +67 -0
- package/lib/ProLayout/components/TabsManager/components/TabsContext.d.ts +6 -0
- package/lib/ProLayout/components/TabsManager/components/TabsContext.js +11 -0
- package/lib/ProLayout/components/TabsManager/hooks/useActiveTab.d.ts +6 -0
- package/lib/ProLayout/components/TabsManager/hooks/useActiveTab.js +20 -0
- package/lib/ProLayout/components/TabsManager/hooks/useProLayoutTabs.d.ts +18 -0
- package/lib/ProLayout/components/TabsManager/hooks/useProLayoutTabs.js +31 -0
- package/lib/ProLayout/components/TabsManager/hooks/useTabsCache.d.ts +31 -0
- package/lib/ProLayout/components/TabsManager/hooks/useTabsCache.js +101 -0
- package/lib/ProLayout/components/TabsManager/hooks/useTabsState.d.ts +5 -0
- package/lib/ProLayout/components/TabsManager/hooks/useTabsState.js +364 -0
- package/lib/ProLayout/components/TabsManager/index.d.ts +8 -0
- package/lib/ProLayout/components/TabsManager/index.js +175 -0
- package/lib/ProLayout/components/TabsManager/propTypes.d.ts +74 -0
- package/lib/ProLayout/components/TabsManager/propTypes.js +22 -0
- package/lib/ProLayout/components/TabsManager/style/index.less +179 -0
- package/lib/ProLayout/components/TabsManager/utils/index.d.ts +38 -0
- package/lib/ProLayout/components/TabsManager/utils/index.js +119 -0
- package/lib/ProLayout/index.d.ts +10 -4
- package/lib/ProLayout/index.js +94 -8
- package/lib/ProLayout/propTypes.d.ts +139 -1
- package/lib/ProLayout/propTypes.js +40 -1
- package/lib/ProLayout/utils/index.js +8 -5
- package/lib/index.d.ts +2 -1
- package/lib/index.js +9 -2
- package/package.json +1 -1
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
.pro-layout-tabs {
|
|
2
|
+
--pro-layout-tabs-primary: var(--ant-primary-color, #1677ff);
|
|
3
|
+
--pro-layout-tabs-active-bg: var(--ant-color-success, #00b578);
|
|
4
|
+
--pro-layout-tabs-text-color: var(--ant-color-text, #1f1f1f);
|
|
5
|
+
|
|
6
|
+
display: flex;
|
|
7
|
+
flex-direction: column;
|
|
8
|
+
height: 100%;
|
|
9
|
+
|
|
10
|
+
&-header {
|
|
11
|
+
display: flex;
|
|
12
|
+
align-items: center;
|
|
13
|
+
min-height: 48px;
|
|
14
|
+
padding: 12px 0;
|
|
15
|
+
border-bottom: none;
|
|
16
|
+
|
|
17
|
+
.pro-layout-tab-list {
|
|
18
|
+
display: flex;
|
|
19
|
+
flex: 1;
|
|
20
|
+
gap: 12px;
|
|
21
|
+
overflow-x: auto;
|
|
22
|
+
overflow-y: hidden;
|
|
23
|
+
|
|
24
|
+
&::-webkit-scrollbar {
|
|
25
|
+
height: 3px;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
&::-webkit-scrollbar-track {
|
|
29
|
+
background: transparent;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
&::-webkit-scrollbar-thumb {
|
|
33
|
+
background: #d9d9d9;
|
|
34
|
+
border-radius: 3px;
|
|
35
|
+
|
|
36
|
+
&:hover {
|
|
37
|
+
background: #bfbfbf;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
&-extra {
|
|
43
|
+
flex-shrink: 0;
|
|
44
|
+
padding: 0 16px;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
&-content {
|
|
49
|
+
.tab-pane {
|
|
50
|
+
&.hidden {
|
|
51
|
+
display: none;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.pro-layout-tab-item {
|
|
58
|
+
position: relative;
|
|
59
|
+
display: flex;
|
|
60
|
+
flex-shrink: 0;
|
|
61
|
+
align-items: center;
|
|
62
|
+
min-height: 36px;
|
|
63
|
+
padding: 0;
|
|
64
|
+
background: #ffffff;
|
|
65
|
+
border: 1px solid transparent;
|
|
66
|
+
border-radius: 8px;
|
|
67
|
+
cursor: pointer;
|
|
68
|
+
transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
|
|
69
|
+
user-select: none;
|
|
70
|
+
|
|
71
|
+
&:hover {
|
|
72
|
+
background: #ffffff;
|
|
73
|
+
border-color: rgba(0, 0, 0, 0.06);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
&.active {
|
|
77
|
+
z-index: 2;
|
|
78
|
+
background: var(--zaui-primary);
|
|
79
|
+
border-color: transparent;
|
|
80
|
+
|
|
81
|
+
&::before {
|
|
82
|
+
display: none;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.pro-layout-tab-content {
|
|
87
|
+
display: flex;
|
|
88
|
+
align-items: center;
|
|
89
|
+
min-width: 100px;
|
|
90
|
+
padding: 6px 12px;
|
|
91
|
+
text-align: left;
|
|
92
|
+
|
|
93
|
+
.pro-layout-tab-icon {
|
|
94
|
+
display: flex;
|
|
95
|
+
flex-shrink: 0;
|
|
96
|
+
align-items: center;
|
|
97
|
+
margin-right: 8px;
|
|
98
|
+
|
|
99
|
+
.iconfont {
|
|
100
|
+
color: inherit;
|
|
101
|
+
font-size: 14px;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
img {
|
|
105
|
+
width: 16px;
|
|
106
|
+
height: 16px;
|
|
107
|
+
object-fit: contain;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.pro-layout-tab-title {
|
|
112
|
+
flex: 1;
|
|
113
|
+
overflow: hidden;
|
|
114
|
+
color: var(--pro-layout-tabs-text-color);
|
|
115
|
+
font-weight: 500;
|
|
116
|
+
font-size: 14px;
|
|
117
|
+
white-space: nowrap;
|
|
118
|
+
text-overflow: ellipsis;
|
|
119
|
+
transition: color 0.3s;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.pro-layout-tab-close {
|
|
123
|
+
display: flex;
|
|
124
|
+
flex-shrink: 0;
|
|
125
|
+
align-items: center;
|
|
126
|
+
justify-content: center;
|
|
127
|
+
margin-left: 8px;
|
|
128
|
+
padding: 3px;
|
|
129
|
+
color: rgba(0, 0, 0, 0.45);
|
|
130
|
+
border-radius: 4px;
|
|
131
|
+
opacity: 0.7;
|
|
132
|
+
transition: all 0.3s;
|
|
133
|
+
|
|
134
|
+
&:hover {
|
|
135
|
+
color: #ff4d4f;
|
|
136
|
+
background: rgba(255, 77, 79, 0.15);
|
|
137
|
+
opacity: 1;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
&.active .pro-layout-tab-content {
|
|
143
|
+
.pro-layout-tab-title {
|
|
144
|
+
color: #ffffff;
|
|
145
|
+
font-weight: 600;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.pro-layout-tab-icon {
|
|
149
|
+
.iconfont {
|
|
150
|
+
color: #ffffff;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.pro-layout-tab-close {
|
|
155
|
+
color: #ffffff;
|
|
156
|
+
|
|
157
|
+
&:hover {
|
|
158
|
+
background: rgba(255, 255, 255, 0.2);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
.pro-layout-dark .pro-layout-tabs {
|
|
165
|
+
--pro-layout-tabs-text-color: rgba(255, 255, 255, 0.85);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// 响应式适配
|
|
169
|
+
@media (max-width: 768px) {
|
|
170
|
+
.pro-layout-tab-item {
|
|
171
|
+
.pro-layout-tab-content {
|
|
172
|
+
padding: 6px 8px;
|
|
173
|
+
|
|
174
|
+
.pro-layout-tab-title {
|
|
175
|
+
max-width: 80px;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { TabItem, MenusType } from '../../../propTypes';
|
|
2
|
+
/**
|
|
3
|
+
* 根据菜单项生成TabItem
|
|
4
|
+
*/
|
|
5
|
+
export declare const createTabFromMenu: (menuItem: MenusType, index?: number) => TabItem;
|
|
6
|
+
/**
|
|
7
|
+
* 生成唯一的tab ID
|
|
8
|
+
*/
|
|
9
|
+
export declare const generateTabId: (menuItem: MenusType, existingIds: string[]) => string;
|
|
10
|
+
/**
|
|
11
|
+
* 检查菜单项是否应该外部跳转
|
|
12
|
+
*/
|
|
13
|
+
export declare const shouldOpenExternal: (menuItem: MenusType, target?: string) => boolean;
|
|
14
|
+
/**
|
|
15
|
+
* 处理外部跳转
|
|
16
|
+
*/
|
|
17
|
+
export declare const handleExternalOpen: (menuItem: MenusType) => void;
|
|
18
|
+
/**
|
|
19
|
+
* 检查是否超出最大标签页限制
|
|
20
|
+
*/
|
|
21
|
+
export declare const checkTabLimit: (currentTabs: TabItem[], maxTabs: number) => boolean;
|
|
22
|
+
/**
|
|
23
|
+
* 移除最旧的标签页(根据访问时间或创建时间)
|
|
24
|
+
*/
|
|
25
|
+
export declare const removeOldestTab: (tabs: TabItem[]) => TabItem[];
|
|
26
|
+
/**
|
|
27
|
+
* 获取右侧标签页
|
|
28
|
+
*/
|
|
29
|
+
export declare const getRightTabs: (tabs: TabItem[], currentTabId: string) => TabItem[];
|
|
30
|
+
/**
|
|
31
|
+
* 扁平化菜单数据
|
|
32
|
+
*/
|
|
33
|
+
export declare const flattenMenuData: (menus?: MenusType[]) => MenusType[];
|
|
34
|
+
/**
|
|
35
|
+
* 判断菜单项是否为最后一级(叶子节点)
|
|
36
|
+
* 只有当菜单项没有子菜单或子菜单为空时,才认为是叶子节点
|
|
37
|
+
*/
|
|
38
|
+
export declare const isLeafMenuItem: (menuItem: MenusType) => boolean;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.shouldOpenExternal = exports.removeOldestTab = exports.isLeafMenuItem = exports.handleExternalOpen = exports.getRightTabs = exports.generateTabId = exports.flattenMenuData = exports.createTabFromMenu = exports.checkTabLimit = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* 根据菜单项生成TabItem
|
|
9
|
+
*/
|
|
10
|
+
var createTabFromMenu = exports.createTabFromMenu = function createTabFromMenu(menuItem) {
|
|
11
|
+
var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
12
|
+
return {
|
|
13
|
+
id: String(menuItem.id || menuItem.code || menuItem.url || index),
|
|
14
|
+
code: menuItem.code,
|
|
15
|
+
name: menuItem.name,
|
|
16
|
+
title: menuItem.name,
|
|
17
|
+
url: menuItem.url,
|
|
18
|
+
closable: true,
|
|
19
|
+
menuItem,
|
|
20
|
+
icon: menuItem.icon || menuItem.imgUrl
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* 生成唯一的tab ID
|
|
26
|
+
*/
|
|
27
|
+
var generateTabId = (menuItem, existingIds) => {
|
|
28
|
+
var baseId = String(menuItem.id || menuItem.code || menuItem.url);
|
|
29
|
+
var finalId = baseId;
|
|
30
|
+
var counter = 1;
|
|
31
|
+
|
|
32
|
+
// 如果ID已存在,则添加数字后缀
|
|
33
|
+
while (existingIds.includes(finalId)) {
|
|
34
|
+
finalId = `${baseId}_${counter}`;
|
|
35
|
+
counter += 1;
|
|
36
|
+
}
|
|
37
|
+
return finalId;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* 检查菜单项是否应该外部跳转
|
|
42
|
+
*/
|
|
43
|
+
exports.generateTabId = generateTabId;
|
|
44
|
+
var shouldOpenExternal = (menuItem, target) => {
|
|
45
|
+
return target === '_blank' || menuItem.redirectUrl && menuItem.redirectUrl !== menuItem.url || menuItem.type === 'EXTERNAL';
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* 处理外部跳转
|
|
50
|
+
*/
|
|
51
|
+
exports.shouldOpenExternal = shouldOpenExternal;
|
|
52
|
+
var handleExternalOpen = menuItem => {
|
|
53
|
+
var url = menuItem.redirectUrl || menuItem.url;
|
|
54
|
+
if (url) {
|
|
55
|
+
window.open(url, '_blank');
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* 检查是否超出最大标签页限制
|
|
61
|
+
*/
|
|
62
|
+
exports.handleExternalOpen = handleExternalOpen;
|
|
63
|
+
var checkTabLimit = (currentTabs, maxTabs) => {
|
|
64
|
+
return currentTabs.length >= maxTabs;
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* 移除最旧的标签页(根据访问时间或创建时间)
|
|
69
|
+
*/
|
|
70
|
+
exports.checkTabLimit = checkTabLimit;
|
|
71
|
+
var removeOldestTab = tabs => {
|
|
72
|
+
if (tabs.length === 0) return tabs;
|
|
73
|
+
|
|
74
|
+
// 找到可关闭的最旧标签页
|
|
75
|
+
var closableTabs = tabs.filter(tab => tab.closable);
|
|
76
|
+
if (closableTabs.length === 0) return tabs;
|
|
77
|
+
|
|
78
|
+
// 移除第一个可关闭的标签页
|
|
79
|
+
var oldestTab = closableTabs[0];
|
|
80
|
+
return tabs.filter(tab => tab.id !== oldestTab.id);
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* 获取右侧标签页
|
|
85
|
+
*/
|
|
86
|
+
exports.removeOldestTab = removeOldestTab;
|
|
87
|
+
var getRightTabs = (tabs, currentTabId) => {
|
|
88
|
+
var currentIndex = tabs.findIndex(tab => tab.id === currentTabId);
|
|
89
|
+
if (currentIndex === -1) return [];
|
|
90
|
+
return tabs.slice(currentIndex + 1);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* 扁平化菜单数据
|
|
95
|
+
*/
|
|
96
|
+
exports.getRightTabs = getRightTabs;
|
|
97
|
+
var flattenMenuData = exports.flattenMenuData = function flattenMenuData() {
|
|
98
|
+
var menus = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
99
|
+
var flatMenus = [];
|
|
100
|
+
menus.forEach(item => {
|
|
101
|
+
flatMenus.push(item);
|
|
102
|
+
if (item.children) {
|
|
103
|
+
flatMenus = [...flatMenus, ...flattenMenuData(item.children)];
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
return flatMenus;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* 判断菜单项是否为最后一级(叶子节点)
|
|
111
|
+
* 只有当菜单项没有子菜单或子菜单为空时,才认为是叶子节点
|
|
112
|
+
*/
|
|
113
|
+
var isLeafMenuItem = menuItem => {
|
|
114
|
+
var _ref = menuItem || {},
|
|
115
|
+
children = _ref.children;
|
|
116
|
+
// 如果 children 不存在、为 null、为 undefined,或者为空数组,则认为是叶子节点
|
|
117
|
+
return !children || Array.isArray(children) && children.length === 0;
|
|
118
|
+
};
|
|
119
|
+
exports.isLeafMenuItem = isLeafMenuItem;
|
package/lib/ProLayout/index.d.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import type { ProLayoutType } from './propTypes';
|
|
3
|
-
|
|
2
|
+
import type { ProLayoutStatesType, ProLayoutType } from './propTypes';
|
|
3
|
+
import { useProLayoutTabs } from './components/TabsManager/hooks/useProLayoutTabs';
|
|
4
|
+
import { useActiveTab } from './components/TabsManager/hooks/useActiveTab';
|
|
5
|
+
interface LayoutContextValue {
|
|
4
6
|
selectedPath: string;
|
|
5
|
-
onSelected: (params:
|
|
7
|
+
onSelected: (params: Partial<ProLayoutStatesType>) => void;
|
|
6
8
|
target: '_blank' | '_parent' | '_self' | '_top';
|
|
7
|
-
}
|
|
9
|
+
}
|
|
10
|
+
export declare const LayoutContext: import("react").Context<LayoutContextValue>;
|
|
8
11
|
declare const ProLayout: {
|
|
9
12
|
(props: ProLayoutType): import("react/jsx-runtime").JSX.Element;
|
|
10
13
|
defaultProps: {
|
|
@@ -21,5 +24,8 @@ declare const ProLayout: {
|
|
|
21
24
|
ProCollapse: (props: import("./components/ProCollapse/PropTypes").ProCollapseType) => import("react/jsx-runtime").JSX.Element;
|
|
22
25
|
ProFooter: import("react").MemoExoticComponent<(props: import("./components/ProFooter/PropTypes").ProFooterType) => import("react/jsx-runtime").JSX.Element>;
|
|
23
26
|
ProHeader: import("react").MemoExoticComponent<(props: import("./components/ProHeader/PropTypes").ProHeaderType) => import("react/jsx-runtime").JSX.Element>;
|
|
27
|
+
useProLayoutTabs: typeof useProLayoutTabs;
|
|
28
|
+
useActiveTab: () => import("./propTypes").TabItem;
|
|
24
29
|
};
|
|
30
|
+
export { useProLayoutTabs, useActiveTab };
|
|
25
31
|
export default ProLayout;
|
package/lib/ProLayout/index.js
CHANGED
|
@@ -5,6 +5,18 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
value: true
|
|
6
6
|
});
|
|
7
7
|
exports.default = exports.LayoutContext = void 0;
|
|
8
|
+
Object.defineProperty(exports, "useActiveTab", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
get: function get() {
|
|
11
|
+
return _useActiveTab.useActiveTab;
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
Object.defineProperty(exports, "useProLayoutTabs", {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: function get() {
|
|
17
|
+
return _useProLayoutTabs.useProLayoutTabs;
|
|
18
|
+
}
|
|
19
|
+
});
|
|
8
20
|
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
|
|
9
21
|
require("antd/es/message/style");
|
|
10
22
|
var _message2 = _interopRequireDefault(require("antd/es/message"));
|
|
@@ -15,9 +27,18 @@ var _ahooks = require("ahooks");
|
|
|
15
27
|
var _index = require("../index");
|
|
16
28
|
var _components = require("./components");
|
|
17
29
|
var _index2 = require("./components/Layout/index");
|
|
30
|
+
var _TabsManager = _interopRequireDefault(require("./components/TabsManager"));
|
|
31
|
+
var _propTypes = require("./propTypes");
|
|
32
|
+
var _useProLayoutTabs = require("./components/TabsManager/hooks/useProLayoutTabs");
|
|
33
|
+
var _useActiveTab = require("./components/TabsManager/hooks/useActiveTab");
|
|
18
34
|
var _utils = require("./utils");
|
|
35
|
+
var _utils2 = require("./components/TabsManager/utils");
|
|
19
36
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
37
|
+
/* eslint-disable func-call-spacing */
|
|
38
|
+
/* eslint-disable no-spaced-func */
|
|
39
|
+
|
|
20
40
|
// 全局上下文
|
|
41
|
+
|
|
21
42
|
var LayoutContext = exports.LayoutContext = /*#__PURE__*/(0, _react.createContext)(undefined);
|
|
22
43
|
var ProLayout = props => {
|
|
23
44
|
var _Object$keys;
|
|
@@ -37,7 +58,13 @@ var ProLayout = props => {
|
|
|
37
58
|
theme = props.theme,
|
|
38
59
|
target = props.target,
|
|
39
60
|
onCollapsedChange = props.onCollapsedChange,
|
|
40
|
-
onMenuClick = props.onMenuClick
|
|
61
|
+
onMenuClick = props.onMenuClick,
|
|
62
|
+
_props$mode = props.mode,
|
|
63
|
+
mode = _props$mode === void 0 ? 'normal' : _props$mode,
|
|
64
|
+
tabs = props.tabs;
|
|
65
|
+
var isTabsLayout = (0, _propTypes.isTabsMode)(props);
|
|
66
|
+
(0, _propTypes.validateTabsProps)(mode, tabs);
|
|
67
|
+
var tabsManagerRef = (0, _react.useRef)(null);
|
|
41
68
|
var _useSetState = (0, _ahooks.useSetState)({
|
|
42
69
|
notice: headerNotice || noticeIn,
|
|
43
70
|
menus: [],
|
|
@@ -69,6 +96,65 @@ var ProLayout = props => {
|
|
|
69
96
|
menus: menuData
|
|
70
97
|
});
|
|
71
98
|
}, [dataSource]);
|
|
99
|
+
var menuDataSource = (0, _react.useMemo)(() => Array.isArray(menus) ? {
|
|
100
|
+
menus
|
|
101
|
+
} : menus, [menus]);
|
|
102
|
+
var handleMenuClick = (0, _react.useCallback)(params => {
|
|
103
|
+
if (isTabsLayout) {
|
|
104
|
+
var _tabsManagerRef$curre, _tabsManagerRef$curre2;
|
|
105
|
+
// 只有最后一级菜单(叶子节点)才设置选中路径
|
|
106
|
+
if (params.item && (0, _utils2.isLeafMenuItem)(params.item)) {
|
|
107
|
+
var _params$item, _params$item2, _params$item3;
|
|
108
|
+
var targetPath = ((_params$item = params.item) === null || _params$item === void 0 ? void 0 : _params$item.url) || ((_params$item2 = params.item) === null || _params$item2 === void 0 ? void 0 : _params$item2.redirectUrl) || ((_params$item3 = params.item) === null || _params$item3 === void 0 ? void 0 : _params$item3.router);
|
|
109
|
+
if (targetPath && targetPath !== selectedPath) {
|
|
110
|
+
setState({
|
|
111
|
+
selectedPath: targetPath
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
(_tabsManagerRef$curre = tabsManagerRef.current) === null || _tabsManagerRef$curre === void 0 || (_tabsManagerRef$curre2 = _tabsManagerRef$curre.handleMenuClick) === null || _tabsManagerRef$curre2 === void 0 || _tabsManagerRef$curre2.call(_tabsManagerRef$curre, params);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
onMenuClick === null || onMenuClick === void 0 || onMenuClick(params);
|
|
119
|
+
}, [isTabsLayout, onMenuClick, selectedPath, setState]);
|
|
120
|
+
var enhancedTabsConfig = (0, _react.useMemo)(() => {
|
|
121
|
+
if (!isTabsLayout || !tabs) {
|
|
122
|
+
return tabs;
|
|
123
|
+
}
|
|
124
|
+
return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, tabs), {}, {
|
|
125
|
+
onTabChange: (activeKey, activeTab, allTabs) => {
|
|
126
|
+
var _activeTab$menuItem, _activeTab$menuItem2, _activeTab$menuItem3, _tabs$onTabChange;
|
|
127
|
+
if (!allTabs || allTabs.length === 0) {
|
|
128
|
+
// 使用一个不可能匹配的路径来清除选中状态,避免 OpenMenu fallback 到 window.location.pathname
|
|
129
|
+
setState({
|
|
130
|
+
selectedPath: '##EMPTY##'
|
|
131
|
+
});
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
var targetPath = (activeTab === null || activeTab === void 0 ? void 0 : activeTab.url) || (activeTab === null || activeTab === void 0 || (_activeTab$menuItem = activeTab.menuItem) === null || _activeTab$menuItem === void 0 ? void 0 : _activeTab$menuItem.router) || (activeTab === null || activeTab === void 0 || (_activeTab$menuItem2 = activeTab.menuItem) === null || _activeTab$menuItem2 === void 0 ? void 0 : _activeTab$menuItem2.url) || (activeTab === null || activeTab === void 0 || (_activeTab$menuItem3 = activeTab.menuItem) === null || _activeTab$menuItem3 === void 0 ? void 0 : _activeTab$menuItem3.redirectUrl);
|
|
135
|
+
if (targetPath && targetPath !== selectedPath) {
|
|
136
|
+
setState({
|
|
137
|
+
selectedPath: targetPath
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
(_tabs$onTabChange = tabs.onTabChange) === null || _tabs$onTabChange === void 0 || _tabs$onTabChange.call(tabs, activeKey, activeTab, allTabs);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}, [isTabsLayout, tabs, selectedPath, setState]);
|
|
144
|
+
var renderContent = () => {
|
|
145
|
+
if (!isTabsLayout || !enhancedTabsConfig) {
|
|
146
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
147
|
+
children: children
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_TabsManager.default, {
|
|
151
|
+
ref: tabsManagerRef,
|
|
152
|
+
config: enhancedTabsConfig,
|
|
153
|
+
dataSource: menuDataSource,
|
|
154
|
+
originalOnMenuClick: onMenuClick,
|
|
155
|
+
children: children
|
|
156
|
+
});
|
|
157
|
+
};
|
|
72
158
|
|
|
73
159
|
/**
|
|
74
160
|
* 关闭提示框
|
|
@@ -99,12 +185,10 @@ var ProLayout = props => {
|
|
|
99
185
|
})), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
|
|
100
186
|
className: contentCls,
|
|
101
187
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_index2.Menu, (0, _objectSpread2.default)((0, _objectSpread2.default)({}, props), {}, {
|
|
102
|
-
dataSource:
|
|
103
|
-
menus
|
|
104
|
-
} : menus,
|
|
188
|
+
dataSource: menuDataSource,
|
|
105
189
|
notice: notice,
|
|
106
190
|
collapsed: collapsed,
|
|
107
|
-
onMenuClick:
|
|
191
|
+
onMenuClick: handleMenuClick,
|
|
108
192
|
onToggle: () => {
|
|
109
193
|
toggle();
|
|
110
194
|
onCollapsedChange && onCollapsedChange(!collapsed);
|
|
@@ -114,9 +198,7 @@ var ProLayout = props => {
|
|
|
114
198
|
style: (0, _objectSpread2.default)((0, _objectSpread2.default)({}, contentStyle), {}, {
|
|
115
199
|
marginTop: headerHeight + noticeHeight
|
|
116
200
|
}),
|
|
117
|
-
children:
|
|
118
|
-
children: children
|
|
119
|
-
})
|
|
201
|
+
children: renderContent()
|
|
120
202
|
})]
|
|
121
203
|
})]
|
|
122
204
|
});
|
|
@@ -145,4 +227,8 @@ ProLayout.defaultProps = {
|
|
|
145
227
|
ProLayout.ProCollapse = _components.ProCollapse;
|
|
146
228
|
ProLayout.ProFooter = _components.ProFooter;
|
|
147
229
|
ProLayout.ProHeader = _components.ProHeader;
|
|
230
|
+
ProLayout.useProLayoutTabs = _useProLayoutTabs.useProLayoutTabs;
|
|
231
|
+
ProLayout.useActiveTab = _useActiveTab.useActiveTab;
|
|
232
|
+
|
|
233
|
+
// 同时导出Hook供直接使用
|
|
148
234
|
var _default = exports.default = ProLayout;
|
|
@@ -94,7 +94,7 @@ type pureKey = boolean | {
|
|
|
94
94
|
topMenu?: boolean;
|
|
95
95
|
leftMenu?: boolean;
|
|
96
96
|
};
|
|
97
|
-
|
|
97
|
+
interface ProLayoutBaseProps {
|
|
98
98
|
/**
|
|
99
99
|
* @description 左侧logo
|
|
100
100
|
* @default -
|
|
@@ -237,6 +237,144 @@ export interface ProLayoutStatesType {
|
|
|
237
237
|
}
|
|
238
238
|
export type MenusProps = MenusType;
|
|
239
239
|
export type DataSourceProps = DataSourceType;
|
|
240
|
+
export interface TabItem {
|
|
241
|
+
/**
|
|
242
|
+
* @description 标签唯一标识
|
|
243
|
+
*/
|
|
244
|
+
id: string;
|
|
245
|
+
/**
|
|
246
|
+
* @description 组件标识码
|
|
247
|
+
*/
|
|
248
|
+
code: string;
|
|
249
|
+
/**
|
|
250
|
+
* @description 标签名称
|
|
251
|
+
*/
|
|
252
|
+
name: string;
|
|
253
|
+
/**
|
|
254
|
+
* @description 标签标题(废弃,保留兼容)
|
|
255
|
+
*/
|
|
256
|
+
title: string;
|
|
257
|
+
/**
|
|
258
|
+
* @description 标签关联路由
|
|
259
|
+
*/
|
|
260
|
+
url?: string;
|
|
261
|
+
/**
|
|
262
|
+
* @description 是否可关闭
|
|
263
|
+
*/
|
|
264
|
+
closable: boolean;
|
|
265
|
+
/**
|
|
266
|
+
* @description 关联菜单项
|
|
267
|
+
*/
|
|
268
|
+
menuItem?: MenusType;
|
|
269
|
+
/**
|
|
270
|
+
* @description 额外扩展数据
|
|
271
|
+
*/
|
|
272
|
+
extra?: Record<string, any>;
|
|
273
|
+
/**
|
|
274
|
+
* @description 图标
|
|
275
|
+
*/
|
|
276
|
+
icon?: ReactNode | string;
|
|
277
|
+
}
|
|
278
|
+
export interface TabsState {
|
|
279
|
+
tabsList: TabItem[];
|
|
280
|
+
activeKey: string;
|
|
281
|
+
activeTabInfo?: TabItem;
|
|
282
|
+
newTabIndex: number;
|
|
283
|
+
activeComponent?: string;
|
|
284
|
+
}
|
|
285
|
+
export type TabsStorageStrategy = 'localStorage' | 'sessionStorage';
|
|
286
|
+
/**
|
|
287
|
+
* @description 添加标签页的业务参数
|
|
288
|
+
*/
|
|
289
|
+
export interface AddTabParams {
|
|
290
|
+
/**
|
|
291
|
+
* @description 组件标识码,用于映射到具体的 React 组件
|
|
292
|
+
*/
|
|
293
|
+
code: string;
|
|
294
|
+
/**
|
|
295
|
+
* @description 标签页显示名称
|
|
296
|
+
*/
|
|
297
|
+
name: string;
|
|
298
|
+
/**
|
|
299
|
+
* @description 额外的业务数据
|
|
300
|
+
*/
|
|
301
|
+
extra?: Record<string, any>;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* @description 添加标签页的选项
|
|
305
|
+
*/
|
|
306
|
+
export interface AddTabOptions {
|
|
307
|
+
/**
|
|
308
|
+
* @description 是否强制创建新标签页(忽略已存在的相同标签页),默认 false
|
|
309
|
+
*/
|
|
310
|
+
forceNew?: boolean;
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* @description 获取标签页信息返回值
|
|
314
|
+
*/
|
|
315
|
+
export interface TabsInfoResult {
|
|
316
|
+
/** 标签页列表 */
|
|
317
|
+
tabsList: TabItem[];
|
|
318
|
+
/** 当前激活的标签页信息 */
|
|
319
|
+
activeTabInfo?: TabItem;
|
|
320
|
+
/** 当前激活的组件标识 */
|
|
321
|
+
activeComponent: string;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* @description ProLayout 标签页实例接口(类似 FormInstance)
|
|
325
|
+
*/
|
|
326
|
+
export interface ProLayoutTabsInstance {
|
|
327
|
+
/**
|
|
328
|
+
* @description 添加标签页
|
|
329
|
+
*/
|
|
330
|
+
addTab: (params: AddTabParams, options?: AddTabOptions) => void;
|
|
331
|
+
/**
|
|
332
|
+
* @description 删除标签页
|
|
333
|
+
*/
|
|
334
|
+
removeTab: (tabId: string) => void;
|
|
335
|
+
/**
|
|
336
|
+
* @description 获取标签页信息
|
|
337
|
+
*/
|
|
338
|
+
getTabInfo: () => TabsInfoResult;
|
|
339
|
+
}
|
|
340
|
+
export interface TabsConfig {
|
|
341
|
+
max?: number;
|
|
342
|
+
storage?: TabsStorageStrategy;
|
|
343
|
+
cacheKey?: string;
|
|
344
|
+
onTabChange?: (activeKey: string, activeTab: TabItem | undefined, allTabs: TabItem[]) => void;
|
|
345
|
+
/**
|
|
346
|
+
* @description 激活组件解析函数,根据 component 标识返回对应的 React 组件
|
|
347
|
+
*/
|
|
348
|
+
activeComponent?: (component: string) => React.ComponentType<any> | null;
|
|
349
|
+
/**
|
|
350
|
+
* @description 空状态组件,当没有标签页时显示
|
|
351
|
+
*/
|
|
352
|
+
empty?: ReactNode;
|
|
353
|
+
/**
|
|
354
|
+
* @description 自定义右键菜单项,会替换默认菜单项
|
|
355
|
+
*/
|
|
356
|
+
menuItems?: import('antd').MenuProps['items'];
|
|
357
|
+
/**
|
|
358
|
+
* @description 自定义菜单项点击回调
|
|
359
|
+
*/
|
|
360
|
+
tabMenuClick?: (params: {
|
|
361
|
+
key: string;
|
|
362
|
+
tab: TabItem;
|
|
363
|
+
tabs: TabItem[];
|
|
364
|
+
}) => void;
|
|
365
|
+
}
|
|
366
|
+
export type ProLayoutMode = 'normal' | 'tabs';
|
|
367
|
+
export interface ProLayoutTabsProps extends ProLayoutBaseProps {
|
|
368
|
+
mode: 'tabs';
|
|
369
|
+
tabs: TabsConfig;
|
|
370
|
+
}
|
|
371
|
+
export interface ProLayoutNormalProps extends ProLayoutBaseProps {
|
|
372
|
+
mode?: 'normal';
|
|
373
|
+
tabs?: never;
|
|
374
|
+
}
|
|
375
|
+
export type ProLayoutType = ProLayoutTabsProps | ProLayoutNormalProps;
|
|
240
376
|
export type ProLayoutProps = ProLayoutType;
|
|
241
377
|
export type ProLayoutStates = ProLayoutStatesType;
|
|
378
|
+
export declare const isTabsMode: (props: ProLayoutType) => props is ProLayoutTabsProps;
|
|
379
|
+
export declare const validateTabsProps: (mode?: ProLayoutMode, tabs?: TabsConfig) => void;
|
|
242
380
|
export {};
|