@zat-design/sisyphus-react 3.13.23 → 3.14.0-beta.1

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.
Files changed (67) hide show
  1. package/es/ProLayout/components/Layout/Menu/FoldMenu/index.js +8 -4
  2. package/es/ProLayout/components/Layout/Menu/OpenMenu/index.js +39 -28
  3. package/es/ProLayout/components/TabsManager/components/TabContextMenu.d.ts +7 -0
  4. package/es/ProLayout/components/TabsManager/components/TabContextMenu.js +96 -0
  5. package/es/ProLayout/components/TabsManager/components/TabItem.d.ts +26 -0
  6. package/es/ProLayout/components/TabsManager/components/TabItem.js +61 -0
  7. package/es/ProLayout/components/TabsManager/components/TabsContext.d.ts +6 -0
  8. package/es/ProLayout/components/TabsManager/components/TabsContext.js +5 -0
  9. package/es/ProLayout/components/TabsManager/hooks/useActiveTab.d.ts +6 -0
  10. package/es/ProLayout/components/TabsManager/hooks/useActiveTab.js +14 -0
  11. package/es/ProLayout/components/TabsManager/hooks/useProLayoutTabs.d.ts +18 -0
  12. package/es/ProLayout/components/TabsManager/hooks/useProLayoutTabs.js +26 -0
  13. package/es/ProLayout/components/TabsManager/hooks/useTabsCache.d.ts +31 -0
  14. package/es/ProLayout/components/TabsManager/hooks/useTabsCache.js +93 -0
  15. package/es/ProLayout/components/TabsManager/hooks/useTabsState.d.ts +5 -0
  16. package/es/ProLayout/components/TabsManager/hooks/useTabsState.js +357 -0
  17. package/es/ProLayout/components/TabsManager/index.d.ts +8 -0
  18. package/es/ProLayout/components/TabsManager/index.js +171 -0
  19. package/es/ProLayout/components/TabsManager/propTypes.d.ts +74 -0
  20. package/es/ProLayout/components/TabsManager/propTypes.js +16 -0
  21. package/es/ProLayout/components/TabsManager/style/index.less +179 -0
  22. package/es/ProLayout/components/TabsManager/utils/index.d.ts +38 -0
  23. package/es/ProLayout/components/TabsManager/utils/index.js +106 -0
  24. package/es/ProLayout/index.d.ts +10 -4
  25. package/es/ProLayout/index.js +82 -9
  26. package/es/ProLayout/propTypes.d.ts +139 -1
  27. package/es/ProLayout/propTypes.js +37 -1
  28. package/es/ProUpload/components/DragRender.d.ts +1 -0
  29. package/es/ProUpload/components/DragRender.js +5 -1
  30. package/es/ProUpload/index.js +4 -2
  31. package/es/ProUpload/propsType.d.ts +5 -0
  32. package/es/index.d.ts +2 -1
  33. package/es/index.js +1 -1
  34. package/lib/ProLayout/components/Layout/Menu/FoldMenu/index.js +8 -4
  35. package/lib/ProLayout/components/Layout/Menu/OpenMenu/index.js +39 -28
  36. package/lib/ProLayout/components/TabsManager/components/TabContextMenu.d.ts +7 -0
  37. package/lib/ProLayout/components/TabsManager/components/TabContextMenu.js +103 -0
  38. package/lib/ProLayout/components/TabsManager/components/TabItem.d.ts +26 -0
  39. package/lib/ProLayout/components/TabsManager/components/TabItem.js +67 -0
  40. package/lib/ProLayout/components/TabsManager/components/TabsContext.d.ts +6 -0
  41. package/lib/ProLayout/components/TabsManager/components/TabsContext.js +11 -0
  42. package/lib/ProLayout/components/TabsManager/hooks/useActiveTab.d.ts +6 -0
  43. package/lib/ProLayout/components/TabsManager/hooks/useActiveTab.js +20 -0
  44. package/lib/ProLayout/components/TabsManager/hooks/useProLayoutTabs.d.ts +18 -0
  45. package/lib/ProLayout/components/TabsManager/hooks/useProLayoutTabs.js +31 -0
  46. package/lib/ProLayout/components/TabsManager/hooks/useTabsCache.d.ts +31 -0
  47. package/lib/ProLayout/components/TabsManager/hooks/useTabsCache.js +101 -0
  48. package/lib/ProLayout/components/TabsManager/hooks/useTabsState.d.ts +5 -0
  49. package/lib/ProLayout/components/TabsManager/hooks/useTabsState.js +364 -0
  50. package/lib/ProLayout/components/TabsManager/index.d.ts +8 -0
  51. package/lib/ProLayout/components/TabsManager/index.js +175 -0
  52. package/lib/ProLayout/components/TabsManager/propTypes.d.ts +74 -0
  53. package/lib/ProLayout/components/TabsManager/propTypes.js +22 -0
  54. package/lib/ProLayout/components/TabsManager/style/index.less +179 -0
  55. package/lib/ProLayout/components/TabsManager/utils/index.d.ts +38 -0
  56. package/lib/ProLayout/components/TabsManager/utils/index.js +119 -0
  57. package/lib/ProLayout/index.d.ts +10 -4
  58. package/lib/ProLayout/index.js +94 -8
  59. package/lib/ProLayout/propTypes.d.ts +139 -1
  60. package/lib/ProLayout/propTypes.js +40 -1
  61. package/lib/ProUpload/components/DragRender.d.ts +1 -0
  62. package/lib/ProUpload/components/DragRender.js +5 -1
  63. package/lib/ProUpload/index.js +4 -2
  64. package/lib/ProUpload/propsType.d.ts +5 -0
  65. package/lib/index.d.ts +2 -1
  66. package/lib/index.js +9 -2
  67. 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;
@@ -1,10 +1,13 @@
1
1
  /// <reference types="react" />
2
- import type { ProLayoutType } from './propTypes';
3
- export declare const LayoutContext: import("react").Context<{
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: any) => void;
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;
@@ -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: Array.isArray(menus) ? {
103
- menus
104
- } : menus,
188
+ dataSource: menuDataSource,
105
189
  notice: notice,
106
190
  collapsed: collapsed,
107
- onMenuClick: 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: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
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
- export interface ProLayoutType {
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 {};