@zat-design/sisyphus-react 4.5.10-beta.1 → 4.5.10-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.
Files changed (266) hide show
  1. package/es/FormsProvider/index.js +14 -21
  2. package/es/ProAction/components/CheckModalContent/index.js +12 -26
  3. package/es/ProAction/index.js +79 -83
  4. package/es/ProAction/propsType.js +0 -1
  5. package/es/ProConfigProvider/index.js +63 -110
  6. package/es/ProConfigProvider/propsType.js +0 -1
  7. package/es/ProDownload/index.js +55 -65
  8. package/es/ProDownload/propsType.js +0 -1
  9. package/es/ProDownload/utils.js +61 -95
  10. package/es/ProDrawerForm/components/ProDrawer/index.js +83 -113
  11. package/es/ProDrawerForm/components/ProModal/index.js +77 -108
  12. package/es/ProDrawerForm/components/index.js +6 -2
  13. package/es/ProDrawerForm/hooks/useConfirmClose.js +20 -39
  14. package/es/ProDrawerForm/index.js +29 -38
  15. package/es/ProDrawerForm/propsType.js +0 -1
  16. package/es/ProDrawerForm/utils/index.js +18 -36
  17. package/es/ProEditLabel/components/RenderProForm.js +45 -49
  18. package/es/ProEditLabel/index.js +126 -163
  19. package/es/ProEditLabel/propsType.js +0 -1
  20. package/es/ProEditLabel/utils/index.js +5 -8
  21. package/es/ProEditTable/components/ActionButton/index.js +111 -119
  22. package/es/ProEditTable/components/RcTable/BaseTable.js +38 -51
  23. package/es/ProEditTable/components/RcTable/DraggableTable.js +97 -129
  24. package/es/ProEditTable/components/RcTable/index.js +6 -4
  25. package/es/ProEditTable/components/RenderField/ListChangedWrapper.js +77 -95
  26. package/es/ProEditTable/components/RenderField/index.js +490 -587
  27. package/es/ProEditTable/components/RenderField/propsType.js +0 -1
  28. package/es/ProEditTable/components/RenderField/tools.js +115 -112
  29. package/es/ProEditTable/components/RenderToolbar/index.js +47 -73
  30. package/es/ProEditTable/components/Summary/index.js +38 -64
  31. package/es/ProEditTable/components/Validator/index.js +46 -46
  32. package/es/ProEditTable/components/index.js +12 -5
  33. package/es/ProEditTable/index.js +456 -378
  34. package/es/ProEditTable/propsType.js +0 -1
  35. package/es/ProEditTable/utils/config.js +60 -122
  36. package/es/ProEditTable/utils/diffOriginal.js +45 -82
  37. package/es/ProEditTable/utils/getDefaultProps.js +19 -24
  38. package/es/ProEditTable/utils/index.js +150 -236
  39. package/es/ProEditTable/utils/tools.js +149 -286
  40. package/es/ProEditTable/utils/transform.js +25 -30
  41. package/es/ProEditTable/utils/useEditTableError.js +30 -43
  42. package/es/ProEditTable/utils/useShouldUpdateForTable.js +42 -72
  43. package/es/ProEditTable/utils/validateAll.js +87 -154
  44. package/es/ProEnum/components/Group.js +38 -30
  45. package/es/ProEnum/components/Tag.js +22 -26
  46. package/es/ProEnum/hooks/useEnum.js +48 -116
  47. package/es/ProEnum/hooks/useEnumRequest.js +128 -179
  48. package/es/ProEnum/hooks/useFrequentEnumRequest.js +40 -48
  49. package/es/ProEnum/index.js +162 -172
  50. package/es/ProEnum/propsType.js +0 -1
  51. package/es/ProEnum/utils/eventCenter.js +10 -12
  52. package/es/ProEnum/utils/frequentEnum.js +35 -92
  53. package/es/ProEnum/utils/getEnum.js +32 -90
  54. package/es/ProEnum/utils/getEnumLabel.js +44 -49
  55. package/es/ProEnum/utils/index.js +93 -207
  56. package/es/ProForm/components/Container.js +13 -28
  57. package/es/ProForm/components/FormFooter/index.js +36 -44
  58. package/es/ProForm/components/FormFooter/propsType.js +0 -1
  59. package/es/ProForm/components/base/Checkbox/index.js +32 -59
  60. package/es/ProForm/components/base/DatePicker/index.js +49 -71
  61. package/es/ProForm/components/base/Input/index.js +63 -97
  62. package/es/ProForm/components/base/Input/propsType.js +0 -1
  63. package/es/ProForm/components/base/InputNumber/index.js +118 -172
  64. package/es/ProForm/components/base/Radio/index.js +39 -52
  65. package/es/ProForm/components/base/RangePicker/index.js +109 -127
  66. package/es/ProForm/components/base/RangePicker/useDateRange.js +20 -17
  67. package/es/ProForm/components/base/Select/index.js +63 -89
  68. package/es/ProForm/components/base/Switch/index.js +27 -35
  69. package/es/ProForm/components/base/SwitchCheckbox/index.js +36 -54
  70. package/es/ProForm/components/base/TextArea/index.js +30 -41
  71. package/es/ProForm/components/base/TimePicker/index.js +27 -37
  72. package/es/ProForm/components/combination/Container/index.js +37 -47
  73. package/es/ProForm/components/combination/Container/propsType.js +0 -1
  74. package/es/ProForm/components/combination/FormList/components/ActionButton.js +165 -237
  75. package/es/ProForm/components/combination/FormList/components/BlockFields.js +98 -103
  76. package/es/ProForm/components/combination/FormList/components/Empty.js +27 -54
  77. package/es/ProForm/components/combination/FormList/components/LineFields.js +57 -54
  78. package/es/ProForm/components/combination/FormList/components/ToolbarButton.js +61 -109
  79. package/es/ProForm/components/combination/FormList/index.js +151 -161
  80. package/es/ProForm/components/combination/FormList/propsType.js +0 -1
  81. package/es/ProForm/components/combination/FormList/utils.js +22 -38
  82. package/es/ProForm/components/combination/Group/component/AddonWrapper/index.js +12 -28
  83. package/es/ProForm/components/combination/Group/component/ComRender.js +50 -111
  84. package/es/ProForm/components/combination/Group/component/FlexibleGroup.js +105 -206
  85. package/es/ProForm/components/combination/Group/hooks/index.js +68 -128
  86. package/es/ProForm/components/combination/Group/index.js +87 -126
  87. package/es/ProForm/components/combination/Group/propsType.js +0 -1
  88. package/es/ProForm/components/combination/Group/utils/index.js +124 -239
  89. package/es/ProForm/components/combination/ProCascader/index.js +156 -199
  90. package/es/ProForm/components/combination/ProCascader/propsType.js +0 -1
  91. package/es/ProForm/components/combination/ProCascader/utils/index.js +12 -21
  92. package/es/ProForm/components/combination/ProModalSelect/hooks/useRequestList.js +63 -75
  93. package/es/ProForm/components/combination/ProModalSelect/index.js +290 -348
  94. package/es/ProForm/components/combination/ProModalSelect/propsType.js +0 -1
  95. package/es/ProForm/components/combination/ProModalSelect/utils/index.js +32 -39
  96. package/es/ProForm/components/combination/ProNumberRange/index.js +100 -156
  97. package/es/ProForm/components/combination/ProNumberRange/propsType.js +0 -1
  98. package/es/ProForm/components/combination/ProRangeLimit/index.js +104 -115
  99. package/es/ProForm/components/combination/ProRangeLimit/propsType.js +0 -1
  100. package/es/ProForm/components/combination/ProTimeLimit/hooks/useControlled.js +16 -16
  101. package/es/ProForm/components/combination/ProTimeLimit/index.js +75 -109
  102. package/es/ProForm/components/index.js +56 -34
  103. package/es/ProForm/components/render/ChangedWrapper.js +85 -94
  104. package/es/ProForm/components/render/ConfirmWrapper.js +27 -39
  105. package/es/ProForm/components/render/CustomComponentViewWrapper.js +65 -82
  106. package/es/ProForm/components/render/Render.js +223 -329
  107. package/es/ProForm/components/render/RenderFields.js +76 -113
  108. package/es/ProForm/components/render/propsType.js +0 -1
  109. package/es/ProForm/hooks/useControlled.js +8 -10
  110. package/es/ProForm/hooks/useDeepCompareMemo.js +11 -11
  111. package/es/ProForm/hooks/useFieldProps.js +8 -4
  112. package/es/ProForm/hooks/useForm.js +50 -110
  113. package/es/ProForm/hooks/useRules.js +17 -33
  114. package/es/ProForm/hooks/useShouldUpdate.js +77 -152
  115. package/es/ProForm/hooks/useWatch.js +58 -129
  116. package/es/ProForm/index.js +157 -194
  117. package/es/ProForm/propsType.js +15 -7
  118. package/es/ProForm/utils/buildFormItemProps.js +51 -58
  119. package/es/ProForm/utils/diffOriginal.js +43 -73
  120. package/es/ProForm/utils/getDefaultProps.js +18 -24
  121. package/es/ProForm/utils/index.js +159 -234
  122. package/es/ProForm/utils/processDependencies.js +21 -60
  123. package/es/ProForm/utils/reactiveValues.js +20 -34
  124. package/es/ProForm/utils/rulesCreator.js +42 -40
  125. package/es/ProForm/utils/transformNames.js +10 -13
  126. package/es/ProForm/utils/transformValue.js +16 -29
  127. package/es/ProForm/utils/valueType.js +96 -178
  128. package/es/ProIcon/config/index.js +340 -274
  129. package/es/ProIcon/index.js +135 -209
  130. package/es/ProIcon/propsTypes.js +0 -1
  131. package/es/ProIcon/utils/index.js +24 -39
  132. package/es/ProLayout/components/Layout/Header/index.js +108 -141
  133. package/es/ProLayout/components/Layout/Menu/FoldMenu/index.js +134 -190
  134. package/es/ProLayout/components/Layout/Menu/OpenMenu/index.js +111 -137
  135. package/es/ProLayout/components/Layout/Menu/OpenMenu/propsType.js +0 -1
  136. package/es/ProLayout/components/Layout/Menu/SideMenu/index.js +23 -31
  137. package/es/ProLayout/components/Layout/Menu/index.js +92 -89
  138. package/es/ProLayout/components/Layout/Notice/index.js +13 -27
  139. package/es/ProLayout/components/Layout/index.js +8 -3
  140. package/es/ProLayout/components/ProCollapse/PropTypes.js +0 -1
  141. package/es/ProLayout/components/ProCollapse/index.js +89 -111
  142. package/es/ProLayout/components/ProFooter/PropTypes.js +0 -1
  143. package/es/ProLayout/components/ProFooter/index.js +27 -25
  144. package/es/ProLayout/components/ProHeader/PropTypes.js +0 -1
  145. package/es/ProLayout/components/ProHeader/components/Copy/index.js +23 -21
  146. package/es/ProLayout/components/ProHeader/components/Describe/index.js +67 -86
  147. package/es/ProLayout/components/ProHeader/components/ProBackBtn/index.js +18 -21
  148. package/es/ProLayout/components/ProHeader/components/ProBackBtn/propsType.js +0 -1
  149. package/es/ProLayout/components/ProHeader/components/index.js +6 -2
  150. package/es/ProLayout/components/ProHeader/index.js +216 -356
  151. package/es/ProLayout/components/ProHeader/utils/index.js +19 -26
  152. package/es/ProLayout/components/TabsManager/components/TabContextMenu.js +92 -85
  153. package/es/ProLayout/components/TabsManager/components/TabItem.js +53 -64
  154. package/es/ProLayout/components/TabsManager/components/TabsContext.js +5 -5
  155. package/es/ProLayout/components/TabsManager/components/TabsHeader.js +42 -52
  156. package/es/ProLayout/components/TabsManager/hooks/useActiveTab.js +8 -9
  157. package/es/ProLayout/components/TabsManager/hooks/useIframeRoute.js +19 -32
  158. package/es/ProLayout/components/TabsManager/hooks/useProLayoutTabs.js +6 -20
  159. package/es/ProLayout/components/TabsManager/hooks/useTabsCache.js +25 -42
  160. package/es/ProLayout/components/TabsManager/hooks/useTabsState.js +290 -408
  161. package/es/ProLayout/components/TabsManager/hooks/useTabsUrlSync.js +132 -95
  162. package/es/ProLayout/components/TabsManager/index.js +406 -390
  163. package/es/ProLayout/components/TabsManager/propTypes.js +7 -15
  164. package/es/ProLayout/components/TabsManager/utils/historyObserver.js +26 -23
  165. package/es/ProLayout/components/TabsManager/utils/index.js +127 -184
  166. package/es/ProLayout/components/index.js +8 -3
  167. package/es/ProLayout/index.js +171 -229
  168. package/es/ProLayout/propTypes.js +12 -52
  169. package/es/ProLayout/utils/index.js +48 -128
  170. package/es/ProSelect/components/AdaptiveTooltip.js +26 -25
  171. package/es/ProSelect/index.js +184 -229
  172. package/es/ProSelect/propsType.js +0 -1
  173. package/es/ProSelect/utils/index.js +100 -146
  174. package/es/ProStep/components/Anchor/index.js +71 -82
  175. package/es/ProStep/components/Item/index.js +49 -56
  176. package/es/ProStep/components/LazyLoad/index.js +23 -29
  177. package/es/ProStep/components/Listener/index.js +20 -33
  178. package/es/ProStep/components/Step/index.js +31 -38
  179. package/es/ProStep/constants.js +4 -1
  180. package/es/ProStep/index.js +166 -153
  181. package/es/ProStep/propsType.js +0 -1
  182. package/es/ProStep/utils/index.js +29 -55
  183. package/es/ProStepTab/index.js +83 -138
  184. package/es/ProStepTab/propsType.js +0 -1
  185. package/es/ProTable/components/EditableCell/EditIcon.js +10 -14
  186. package/es/ProTable/components/EditableCell/index.js +37 -71
  187. package/es/ProTable/components/EditableCell/propsType.js +0 -1
  188. package/es/ProTable/components/FormatColumn/index.js +209 -340
  189. package/es/ProTable/components/FormatColumn/propsType.js +0 -1
  190. package/es/ProTable/components/RcTable/components/BaseTable/index.js +35 -39
  191. package/es/ProTable/components/RcTable/components/DraggableTable/components/DndWrapper/index.js +80 -107
  192. package/es/ProTable/components/RcTable/components/DraggableTable/components/DndWrapper/utils/index.js +54 -48
  193. package/es/ProTable/components/RcTable/components/DraggableTable/components/DndWrapper/utils/propsType.js +0 -1
  194. package/es/ProTable/components/RcTable/components/DraggableTable/index.js +47 -54
  195. package/es/ProTable/components/RcTable/index.js +6 -4
  196. package/es/ProTable/components/RenderColumn/index.js +158 -186
  197. package/es/ProTable/components/RenderEmptyText/index.js +12 -21
  198. package/es/ProTable/components/RenderFooter/index.js +15 -15
  199. package/es/ProTable/components/RenderSummary/index.js +33 -50
  200. package/es/ProTable/components/RenderTableHeader/index.js +44 -46
  201. package/es/ProTable/components/RenderTabs/index.js +47 -51
  202. package/es/ProTable/components/TableResizable/index.js +56 -72
  203. package/es/ProTable/components/TooltipTitle/index.js +13 -21
  204. package/es/ProTable/components/index.js +16 -36
  205. package/es/ProTable/hooks/useAntdTable.js +185 -219
  206. package/es/ProTable/index.js +232 -249
  207. package/es/ProTable/propsType.js +0 -1
  208. package/es/ProTable/utils/columnStorage.js +63 -88
  209. package/es/ProTable/utils/index.js +57 -90
  210. package/es/ProTabs/components/Card/index.js +20 -48
  211. package/es/ProTabs/components/index.js +4 -1
  212. package/es/ProTabs/index.js +39 -56
  213. package/es/ProTabs/propType.js +0 -1
  214. package/es/ProThemeTools/component/ProTools/index.js +106 -158
  215. package/es/ProThemeTools/component/index.js +4 -1
  216. package/es/ProThemeTools/context/ThemeContext.js +67 -146
  217. package/es/ProThemeTools/index.js +103 -156
  218. package/es/ProThemeTools/propsType.js +0 -1
  219. package/es/ProThemeTools/utils/index.js +60 -109
  220. package/es/ProTooltip/index.js +132 -165
  221. package/es/ProTooltip/propsType.js +0 -1
  222. package/es/ProTree/components/AdaptiveTooltip.js +15 -17
  223. package/es/ProTree/components/CloseIcon.js +18 -26
  224. package/es/ProTree/components/List.js +28 -47
  225. package/es/ProTree/components/ProTree.js +152 -211
  226. package/es/ProTree/components/ProTreeSelect/index.js +254 -458
  227. package/es/ProTree/components/ProTreeSelect/propsType.js +0 -1
  228. package/es/ProTree/components/SearchTitle.js +23 -42
  229. package/es/ProTree/components/Tree.js +147 -195
  230. package/es/ProTree/components/index.js +10 -5
  231. package/es/ProTree/index.js +12 -16
  232. package/es/ProTree/propsType.js +0 -1
  233. package/es/ProTree/utils.js +46 -118
  234. package/es/ProTreeModal/components/Cascader.js +56 -64
  235. package/es/ProTreeModal/components/CloseIcon.js +18 -26
  236. package/es/ProTreeModal/components/List.js +114 -180
  237. package/es/ProTreeModal/components/SearchTitle.js +15 -18
  238. package/es/ProTreeModal/components/SortableItem.js +29 -58
  239. package/es/ProTreeModal/components/Tree.js +99 -113
  240. package/es/ProTreeModal/components/Trigger.js +87 -121
  241. package/es/ProTreeModal/components/index.js +14 -6
  242. package/es/ProTreeModal/index.js +397 -435
  243. package/es/ProTreeModal/propsType.js +0 -1
  244. package/es/ProTreeModal/utils.js +52 -95
  245. package/es/ProUpload/components/ButtonRender.js +44 -54
  246. package/es/ProUpload/components/DragRender.js +94 -134
  247. package/es/ProUpload/components/DraggableUploadListItem.js +12 -25
  248. package/es/ProUpload/components/Example.js +27 -31
  249. package/es/ProUpload/components/FileItem.js +69 -163
  250. package/es/ProUpload/components/ImageRender.js +134 -170
  251. package/es/ProUpload/index.js +68 -100
  252. package/es/ProUpload/propsType.js +0 -1
  253. package/es/ProUpload/uitls.js +8 -4
  254. package/es/ProUtils/utils/index.js +17 -13
  255. package/es/ProViewer/index.js +154 -175
  256. package/es/ProViewer/propsType.js +0 -5
  257. package/es/ProWaterMark/index.js +9 -16
  258. package/es/ProWaterMark/propsType.js +0 -1
  259. package/es/hooks/useDraggableRow.js +25 -53
  260. package/es/index.js +57 -77
  261. package/es/locale/en_US.js +153 -142
  262. package/es/locale/index.js +23 -36
  263. package/es/locale/zh_CN.js +145 -142
  264. package/es/tokens.js +84 -83
  265. package/es/utils/index.js +24 -51
  266. package/package.json +4 -3
@@ -1,315 +1,247 @@
1
- import { useState, useCallback, useEffect, useRef } from 'react';
2
- import { message } from 'antd';
1
+ import { useState, useCallback, useEffect, useRef } from "react";
2
+ import { message } from "antd";
3
3
  import { DEFAULT_TABS_CONFIG } from "../propTypes";
4
4
  import { useTabsCache } from "./useTabsCache";
5
5
  import locale, { formatMessage } from "../../../../locale";
6
- import { createTabFromMenu, generateTabId, shouldOpenExternal, handleExternalOpen, checkTabLimit, getRightTabs, flattenMenuData, canOpenAsTab, getMenuRoute, findExistingTab, normalizeTabUrl, isSafeExternalUrl, isSafeHttpUrl, resolveTabMenuItem, derivePinned, getPinnedBoundary, pinTab as pinTabInList, unpinTab as unpinTabInList, reorderWithPinConstraint } from "../utils";
7
-
8
- /**
9
- * 标签页状态管理Hook
10
- */
11
- export const useTabsState = options => {
12
- const {
13
- initialState = {},
14
- config,
15
- dataSource,
16
- cacheEnabled = true
17
- } = options;
18
-
19
- // 合并默认配置
20
- const finalConfig = {
21
- ...DEFAULT_TABS_CONFIG,
22
- ...config
23
- };
24
- const urlSyncEnabled = finalConfig.urlSync === true || typeof finalConfig.urlSync === 'object' && finalConfig.urlSync !== null;
25
-
26
- // 初始化状态
6
+ import {
7
+ createTabFromMenu,
8
+ generateTabId,
9
+ shouldOpenExternal,
10
+ handleExternalOpen,
11
+ checkTabLimit,
12
+ getRightTabs,
13
+ flattenMenuData,
14
+ canOpenAsTab,
15
+ getMenuRoute,
16
+ findExistingTab,
17
+ normalizeTabUrl,
18
+ isSafeExternalUrl,
19
+ isSafeHttpUrl,
20
+ resolveTabMenuItem,
21
+ derivePinned,
22
+ getPinnedBoundary,
23
+ pinTab as pinTabInList,
24
+ unpinTab as unpinTabInList,
25
+ reorderWithPinConstraint
26
+ } from "../utils";
27
+ const useTabsState = (options) => {
28
+ const { initialState = {}, config, dataSource, cacheEnabled = true } = options;
29
+ const finalConfig = { ...DEFAULT_TABS_CONFIG, ...config };
30
+ const urlSyncEnabled = finalConfig.urlSync === true || typeof finalConfig.urlSync === "object" && finalConfig.urlSync !== null;
27
31
  const [state, setState] = useState(() => ({
28
32
  tabsList: [],
29
- activeKey: '',
30
- activeTabInfo: undefined,
33
+ activeKey: "",
34
+ activeTabInfo: void 0,
31
35
  newTabIndex: 0,
32
- activeComponent: '',
36
+ activeComponent: "",
33
37
  ...initialState
34
38
  }));
35
-
36
- // 缓存管理
37
- const {
38
- saveToCache,
39
- restoreFromCache,
40
- clearCache
41
- } = useTabsCache({
39
+ const { saveToCache, restoreFromCache, clearCache } = useTabsCache({
42
40
  cacheKey: finalConfig.cacheKey,
43
41
  storage: finalConfig.storage,
44
42
  enabled: cacheEnabled
45
43
  });
46
-
47
- // 初始化标记,确保只在初始化后保存缓存
48
44
  const [isInitialized, setIsInitialized] = useState(false);
49
-
50
- // 从缓存恢复状态
51
45
  const hasRestoredCacheRef = useRef(false);
52
46
  useEffect(() => {
53
- if (hasRestoredCacheRef.current) return;
47
+ var _a, _b;
48
+ if (hasRestoredCacheRef.current)
49
+ return;
54
50
  hasRestoredCacheRef.current = true;
55
51
  const cachedState = restoreFromCache();
56
52
  if (cachedState && cachedState.tabsList && cachedState.tabsList.length > 0) {
57
- // 兼容旧缓存:如果缓存中有 activeTab 但没有 activeTabInfo,进行迁移
58
- const restoredState = {
59
- ...cachedState
60
- };
61
- if ('activeTab' in restoredState && !restoredState.activeTabInfo) {
53
+ const restoredState = { ...cachedState };
54
+ if ("activeTab" in restoredState && !restoredState.activeTabInfo) {
62
55
  restoredState.activeTabInfo = restoredState.activeTab;
63
56
  delete restoredState.activeTab;
64
57
  }
65
-
66
- // 兼容旧缓存:Ant Tabs 的 onChange 始终返回字符串 key;旧版本可能保存数字 id,
67
- // 若不归一化,严格比较会导致恢复后的标签无法切换。
68
- restoredState.tabsList = restoredState.tabsList.map(tab => ({
58
+ restoredState.tabsList = restoredState.tabsList.map((tab) => ({
69
59
  ...tab,
70
60
  id: String(tab.id),
71
- pinned: tab.pinned === undefined ? derivePinned(tab) : tab.pinned
61
+ pinned: tab.pinned === void 0 ? derivePinned(tab) : tab.pinned
72
62
  }));
73
- restoredState.activeKey = restoredState.activeKey === undefined || restoredState.activeKey === null ? '' : String(restoredState.activeKey);
63
+ restoredState.activeKey = restoredState.activeKey === void 0 || restoredState.activeKey === null ? "" : String(restoredState.activeKey);
74
64
  if (urlSyncEnabled) {
75
- const retainedTabByUrl = new Map();
76
- const retainedIdByOriginalId = new Map();
77
- restoredState.tabsList.forEach(tab => {
65
+ const retainedTabByUrl = /* @__PURE__ */ new Map();
66
+ const retainedIdByOriginalId = /* @__PURE__ */ new Map();
67
+ restoredState.tabsList.forEach((tab) => {
78
68
  const normalizedUrl = normalizeTabUrl(tab.url);
79
- if (!normalizedUrl) return;
69
+ if (!normalizedUrl)
70
+ return;
80
71
  const retainedTab = retainedTabByUrl.get(normalizedUrl);
81
72
  if (retainedTab) {
82
73
  retainedIdByOriginalId.set(tab.id, retainedTab.id);
83
74
  return;
84
75
  }
85
- const normalizedTab = {
86
- ...tab,
87
- url: normalizedUrl
88
- };
76
+ const normalizedTab = { ...tab, url: normalizedUrl };
89
77
  retainedTabByUrl.set(normalizedUrl, normalizedTab);
90
78
  retainedIdByOriginalId.set(tab.id, normalizedTab.id);
91
79
  });
92
80
  restoredState.tabsList = Array.from(retainedTabByUrl.values());
93
- restoredState.activeKey = retainedIdByOriginalId.get(restoredState.activeKey) || restoredState.tabsList[0]?.id || '';
81
+ restoredState.activeKey = retainedIdByOriginalId.get(restoredState.activeKey) || ((_a = restoredState.tabsList[0]) == null ? void 0 : _a.id) || "";
94
82
  }
95
- restoredState.activeTabInfo = restoredState.tabsList.find(tab => tab.id === restoredState.activeKey);
96
- restoredState.activeComponent = restoredState.activeTabInfo ? restoredState.activeTabInfo.menuItem?.code || restoredState.activeTabInfo.id : '';
83
+ restoredState.activeTabInfo = restoredState.tabsList.find(
84
+ (tab) => tab.id === restoredState.activeKey
85
+ );
86
+ restoredState.activeComponent = restoredState.activeTabInfo ? ((_b = restoredState.activeTabInfo.menuItem) == null ? void 0 : _b.code) || restoredState.activeTabInfo.id : "";
97
87
  setState(restoredState);
98
88
  }
99
89
  setIsInitialized(true);
100
90
  }, [restoreFromCache, urlSyncEnabled]);
101
- const lastActiveKeyRef = useRef('');
91
+ const lastActiveKeyRef = useRef("");
102
92
  const shouldSkipSaveRef = useRef(false);
103
93
  const initialTabsAppliedRef = useRef(false);
104
-
105
- // 保存状态到缓存
106
94
  useEffect(() => {
107
- if (!isInitialized) return;
108
-
109
- // 如果标记了跳过保存(清空缓存后),则跳过本次保存
95
+ if (!isInitialized)
96
+ return;
110
97
  if (shouldSkipSaveRef.current) {
111
98
  shouldSkipSaveRef.current = false;
112
99
  return;
113
100
  }
114
-
115
- // 处理 onTabChange 调用 - 支持空状态和正常切换
116
101
  if (finalConfig.onTabChange && lastActiveKeyRef.current !== state.activeKey) {
117
102
  lastActiveKeyRef.current = state.activeKey;
118
103
  if (state.activeKey) {
119
- // 正常的标签页切换
120
- const activeTab = state.tabsList.find(tab => tab.id === state.activeKey);
104
+ const activeTab = state.tabsList.find((tab) => tab.id === state.activeKey);
121
105
  if (activeTab) {
122
106
  finalConfig.onTabChange(state.activeKey, activeTab, state.tabsList);
123
107
  }
124
108
  } else {
125
- // 空状态 - 所有标签页都被关闭
126
- finalConfig.onTabChange('', undefined, state.tabsList);
109
+ finalConfig.onTabChange("", void 0, state.tabsList);
127
110
  }
128
111
  }
129
-
130
- // 如果 tabsList 为空且 activeKey 为空,说明是清空状态,不保存缓存
131
112
  if (state.tabsList.length === 0 && !state.activeKey) {
132
113
  return;
133
114
  }
134
-
135
- // 保存状态到缓存
136
115
  saveToCache(state);
137
116
  }, [state, saveToCache, finalConfig, isInitialized]);
138
-
139
- /**
140
- * 检查是否可以添加标签页(用于在菜单点击时判断是否应该激活菜单)
141
- */
142
- const canAddTab = useCallback((menuItem, options) => {
143
- const {
144
- forceNew = false
145
- } = options || {};
146
-
147
- // 非叶子节点默认不入签,仅根节点特例可入签
148
- if (!canOpenAsTab(menuItem)) {
149
- return false;
150
- }
151
-
152
- // 检查是否需要外部跳转
153
- if (shouldOpenExternal(menuItem)) {
154
- return false;
155
- }
156
-
157
- // URL 同步模式下完整 URL 始终唯一,forceNew 不能绕过身份匹配。
158
- if (urlSyncEnabled || !forceNew) {
159
- const existingTab = findExistingTab(state.tabsList, menuItem, {
160
- urlSync: urlSyncEnabled
161
- });
162
- if (existingTab) {
163
- // 如果已存在,可以添加(会切换到已存在的标签页)
164
- return true;
117
+ const canAddTab = useCallback(
118
+ (menuItem, options2) => {
119
+ const { forceNew = false } = options2 || {};
120
+ if (!canOpenAsTab(menuItem)) {
121
+ return false;
165
122
  }
166
- }
167
-
168
- // 检查是否超出限制(只有在需要创建新标签页时才检查)
169
- if (checkTabLimit(state.tabsList, finalConfig.max)) {
170
- // 达到最大值时,不能添加新标签页
171
- return false;
172
- }
173
- return true;
174
- }, [state.tabsList, finalConfig, urlSyncEnabled]);
175
-
176
- /**
177
- * 添加标签页
178
- */
179
- const addTab = useCallback((menuItem, options) => {
180
- const {
181
- forceNew = false,
182
- silent = false
183
- } = options || {};
184
- setState(prevState => {
185
- if (!canOpenAsTab(menuItem)) return prevState;
186
123
  if (shouldOpenExternal(menuItem)) {
187
- const externalUrl = getMenuRoute(menuItem);
188
- if (!urlSyncEnabled || isSafeHttpUrl(externalUrl)) {
189
- handleExternalOpen(menuItem, urlSyncEnabled);
190
- }
191
- return prevState;
124
+ return false;
192
125
  }
193
- const rawUrl = getMenuRoute(menuItem);
194
- const normalizedUrl = urlSyncEnabled ? normalizeTabUrl(rawUrl) : undefined;
195
- if (urlSyncEnabled && rawUrl && !normalizedUrl) {
196
- if (isSafeExternalUrl(rawUrl)) {
197
- handleExternalOpen(menuItem, true);
126
+ if (urlSyncEnabled || !forceNew) {
127
+ const existingTab = findExistingTab(state.tabsList, menuItem, {
128
+ urlSync: urlSyncEnabled
129
+ });
130
+ if (existingTab) {
131
+ return true;
198
132
  }
199
- return prevState;
200
133
  }
201
- const resolvedMenuItem = normalizedUrl ? {
202
- ...menuItem,
203
- url: normalizedUrl,
204
- redirectUrl: undefined
205
- } : menuItem;
206
-
207
- // 非强制新建时,查找已存在的标签页并切换
208
- const existingTab = urlSyncEnabled || !forceNew ? findExistingTab(prevState.tabsList, resolvedMenuItem, {
209
- urlSync: urlSyncEnabled
210
- }) : undefined;
211
- if (existingTab) {
212
- // 若来源菜单明确标记 closable: false 而已有 tab 未继承,则修正
213
- const correctedTab = resolvedMenuItem.closable === false && existingTab.closable !== false ? {
214
- ...existingTab,
215
- closable: false
216
- } : existingTab;
217
- const updatedTabsList = correctedTab !== existingTab ? prevState.tabsList.map(t => t.id === existingTab.id ? correctedTab : t) : prevState.tabsList;
134
+ if (checkTabLimit(state.tabsList, finalConfig.max)) {
135
+ return false;
136
+ }
137
+ return true;
138
+ },
139
+ [state.tabsList, finalConfig, urlSyncEnabled]
140
+ );
141
+ const addTab = useCallback(
142
+ (menuItem, options2) => {
143
+ const { forceNew = false, silent = false } = options2 || {};
144
+ setState((prevState) => {
145
+ var _a;
146
+ if (!canOpenAsTab(menuItem))
147
+ return prevState;
148
+ if (shouldOpenExternal(menuItem)) {
149
+ const externalUrl = getMenuRoute(menuItem);
150
+ if (!urlSyncEnabled || isSafeHttpUrl(externalUrl)) {
151
+ handleExternalOpen(menuItem, urlSyncEnabled);
152
+ }
153
+ return prevState;
154
+ }
155
+ const rawUrl = getMenuRoute(menuItem);
156
+ const normalizedUrl = urlSyncEnabled ? normalizeTabUrl(rawUrl) : void 0;
157
+ if (urlSyncEnabled && rawUrl && !normalizedUrl) {
158
+ if (isSafeExternalUrl(rawUrl)) {
159
+ handleExternalOpen(menuItem, true);
160
+ }
161
+ return prevState;
162
+ }
163
+ const resolvedMenuItem = normalizedUrl ? { ...menuItem, url: normalizedUrl, redirectUrl: void 0 } : menuItem;
164
+ const existingTab = urlSyncEnabled || !forceNew ? findExistingTab(prevState.tabsList, resolvedMenuItem, { urlSync: urlSyncEnabled }) : void 0;
165
+ if (existingTab) {
166
+ const correctedTab = resolvedMenuItem.closable === false && existingTab.closable !== false ? { ...existingTab, closable: false } : existingTab;
167
+ const updatedTabsList = correctedTab !== existingTab ? prevState.tabsList.map((t) => t.id === existingTab.id ? correctedTab : t) : prevState.tabsList;
168
+ return {
169
+ ...prevState,
170
+ tabsList: updatedTabsList,
171
+ activeKey: existingTab.id,
172
+ activeTabInfo: correctedTab,
173
+ activeComponent: ((_a = existingTab.menuItem) == null ? void 0 : _a.code) || existingTab.id
174
+ };
175
+ }
176
+ if (checkTabLimit(prevState.tabsList, finalConfig.max)) {
177
+ message.info(
178
+ formatMessage(locale.ProLayout.tabMaxLimitMessage, { max: finalConfig.max })
179
+ );
180
+ return prevState;
181
+ }
182
+ const existingIds = prevState.tabsList.map((tab) => tab.id);
183
+ const tabId = generateTabId(resolvedMenuItem, existingIds);
184
+ const newTab = createTabFromMenu(resolvedMenuItem, prevState.newTabIndex);
185
+ newTab.id = tabId;
186
+ const pinnedBoundary = getPinnedBoundary(prevState.tabsList);
187
+ const nextTabsList = derivePinned(newTab) ? [
188
+ ...prevState.tabsList.slice(0, pinnedBoundary),
189
+ newTab,
190
+ ...prevState.tabsList.slice(pinnedBoundary)
191
+ ] : [...prevState.tabsList, newTab];
192
+ const shouldActivate = !silent || prevState.activeKey === "";
218
193
  return {
219
194
  ...prevState,
220
- tabsList: updatedTabsList,
221
- activeKey: existingTab.id,
222
- activeTabInfo: correctedTab,
223
- activeComponent: existingTab.menuItem?.code || existingTab.id
195
+ tabsList: nextTabsList,
196
+ activeKey: shouldActivate ? tabId : prevState.activeKey,
197
+ activeTabInfo: shouldActivate ? newTab : prevState.activeTabInfo,
198
+ newTabIndex: prevState.newTabIndex + 1,
199
+ activeComponent: shouldActivate ? resolvedMenuItem.code || tabId : prevState.activeComponent
224
200
  };
225
- }
226
- if (checkTabLimit(prevState.tabsList, finalConfig.max)) {
227
- message.info(formatMessage(locale.ProLayout.tabMaxLimitMessage, {
228
- max: finalConfig.max
229
- }));
230
- return prevState;
231
- }
232
- const existingIds = prevState.tabsList.map(tab => tab.id);
233
- const tabId = generateTabId(resolvedMenuItem, existingIds);
234
- const newTab = createTabFromMenu(resolvedMenuItem, prevState.newTabIndex);
235
- newTab.id = tabId;
236
- const pinnedBoundary = getPinnedBoundary(prevState.tabsList);
237
- const nextTabsList = derivePinned(newTab) ? [...prevState.tabsList.slice(0, pinnedBoundary), newTab, ...prevState.tabsList.slice(pinnedBoundary)] : [...prevState.tabsList, newTab];
238
-
239
- // silent=true 时,若已有 active 则保留;无 active(首次进入)仍激活以保留默认行为
240
- const shouldActivate = !silent || prevState.activeKey === '';
241
- return {
242
- ...prevState,
243
- tabsList: nextTabsList,
244
- activeKey: shouldActivate ? tabId : prevState.activeKey,
245
- activeTabInfo: shouldActivate ? newTab : prevState.activeTabInfo,
246
- newTabIndex: prevState.newTabIndex + 1,
247
- activeComponent: shouldActivate ? resolvedMenuItem.code || tabId : prevState.activeComponent
248
- };
249
- });
250
- }, [finalConfig, urlSyncEnabled]);
251
-
252
- // 普通初始标签只在当前 TabsManager 挂载周期应用一次。
253
- // 缓存恢复已有标签时只消费默认值;closeAll 后 ref 保持 true,避免再次补签。
201
+ });
202
+ },
203
+ [finalConfig, urlSyncEnabled]
204
+ );
254
205
  useEffect(() => {
255
206
  const initialTabs = finalConfig.initialTabs;
256
207
  if (!isInitialized || !cacheEnabled || initialTabsAppliedRef.current || !initialTabs || initialTabs.length === 0) {
257
208
  return;
258
209
  }
259
210
  initialTabsAppliedRef.current = true;
260
- if (state.tabsList.length > 0) return;
261
- const sourceMenus = Array.isArray(dataSource?.menus) ? dataSource.menus : [];
262
- initialTabs.forEach(params => {
263
- addTab(resolveTabMenuItem(params, sourceMenus), {
264
- silent: true
265
- });
211
+ if (state.tabsList.length > 0)
212
+ return;
213
+ const sourceMenus = Array.isArray(dataSource == null ? void 0 : dataSource.menus) ? dataSource.menus : [];
214
+ initialTabs.forEach((params) => {
215
+ addTab(resolveTabMenuItem(params, sourceMenus), { silent: true });
266
216
  });
267
- }, [isInitialized, cacheEnabled, finalConfig.initialTabs, dataSource, state.tabsList.length, addTab]);
268
-
269
- /**
270
- * 更新已存在标签页的展示信息(保持 tab.id 不变 → 子组件不会 unmount)
271
- * - 仅允许更新 name / icon / extra / closable
272
- * - extra 为替换语义(直接覆盖原 extra)
273
- * - tabId 不存在时 no-op
274
- */
217
+ }, [
218
+ isInitialized,
219
+ cacheEnabled,
220
+ finalConfig.initialTabs,
221
+ dataSource,
222
+ state.tabsList.length,
223
+ addTab
224
+ ]);
275
225
  const updateTab = useCallback((tabId, updates) => {
276
- setState(prevState => {
277
- const targetIndex = prevState.tabsList.findIndex(tab => tab.id === tabId);
278
- if (targetIndex === -1) return prevState;
226
+ setState((prevState) => {
227
+ const targetIndex = prevState.tabsList.findIndex((tab) => tab.id === tabId);
228
+ if (targetIndex === -1)
229
+ return prevState;
279
230
  const target = prevState.tabsList[targetIndex];
280
231
  const nextMenuItem = target.menuItem ? {
281
232
  ...target.menuItem,
282
- ...(updates.name !== undefined && {
283
- name: updates.name
284
- }),
285
- ...(updates.icon !== undefined && {
286
- icon: updates.icon
287
- }),
288
- ...(updates.extra !== undefined && {
289
- extra: updates.extra
290
- }),
291
- ...(updates.closable !== undefined && {
292
- closable: updates.closable
293
- }),
294
- ...(updates.pinned !== undefined && {
295
- pinned: updates.pinned
296
- })
233
+ ...updates.name !== void 0 && { name: updates.name },
234
+ ...updates.icon !== void 0 && { icon: updates.icon },
235
+ ...updates.extra !== void 0 && { extra: updates.extra },
236
+ ...updates.closable !== void 0 && { closable: updates.closable },
237
+ ...updates.pinned !== void 0 && { pinned: updates.pinned }
297
238
  } : target.menuItem;
298
239
  const nextTab = {
299
240
  ...target,
300
- ...(updates.name !== undefined && {
301
- name: updates.name,
302
- title: updates.name
303
- }),
304
- ...(updates.icon !== undefined && {
305
- icon: updates.icon
306
- }),
307
- ...(updates.closable !== undefined && {
308
- closable: updates.closable
309
- }),
310
- ...(updates.pinned !== undefined && {
311
- pinned: updates.pinned
312
- }),
241
+ ...updates.name !== void 0 && { name: updates.name, title: updates.name },
242
+ ...updates.icon !== void 0 && { icon: updates.icon },
243
+ ...updates.closable !== void 0 && { closable: updates.closable },
244
+ ...updates.pinned !== void 0 && { pinned: updates.pinned },
313
245
  menuItem: nextMenuItem
314
246
  };
315
247
  const newTabsList = [...prevState.tabsList];
@@ -321,105 +253,89 @@ export const useTabsState = options => {
321
253
  };
322
254
  });
323
255
  }, []);
324
-
325
- /**
326
- * 移除标签页
327
- */
328
- const removeTab = useCallback(tabId => {
329
- setState(prevState => {
330
- const tabToRemove = prevState.tabsList.find(tab => tab.id === tabId);
331
- if (!tabToRemove || !tabToRemove.closable) {
332
- return prevState;
333
- }
334
- const newTabs = prevState.tabsList.filter(tab => tab.id !== tabId);
335
- let newActiveKey = prevState.activeKey;
336
- let newActiveTabInfo = prevState.activeTabInfo;
337
- let newActiveComponent = prevState.activeComponent;
338
-
339
- // 如果移除的是当前活跃标签页,需要选择新的活跃标签页
340
- if (prevState.activeKey === tabId && newTabs.length > 0) {
341
- const currentIndex = prevState.tabsList.findIndex(tab => tab.id === tabId);
342
- const newActiveIndex = Math.min(currentIndex, newTabs.length - 1);
343
- newActiveTabInfo = newTabs[newActiveIndex];
344
- newActiveKey = newActiveTabInfo.id;
345
- newActiveComponent = newActiveTabInfo.menuItem?.code || newActiveTabInfo.id;
346
- } else if (prevState.activeKey === tabId) {
347
- // 如果删除后没有标签页了
348
- newActiveKey = '';
349
- newActiveTabInfo = undefined;
350
- newActiveComponent = '';
351
- }
352
-
353
- // 如果删除后没有标签页了,清空缓存
354
- if (newTabs.length === 0) {
355
- // 标记跳过下次保存,避免清空后又被重新保存
356
- shouldSkipSaveRef.current = true;
357
- clearCache();
358
-
359
- // 直接调用 onTabChange,因为 useEffect 会被跳过
360
- if (finalConfig.onTabChange) {
361
- setTimeout(() => {
362
- finalConfig.onTabChange('', undefined, []);
363
- }, 0);
256
+ const removeTab = useCallback(
257
+ (tabId) => {
258
+ setState((prevState) => {
259
+ var _a;
260
+ const tabToRemove = prevState.tabsList.find((tab) => tab.id === tabId);
261
+ if (!tabToRemove || !tabToRemove.closable) {
262
+ return prevState;
364
263
  }
365
- }
366
- return {
367
- ...prevState,
368
- tabsList: newTabs,
369
- activeKey: newActiveKey,
370
- activeTabInfo: newActiveTabInfo,
371
- activeComponent: newActiveComponent
372
- };
373
- });
374
- }, [clearCache, finalConfig]);
375
-
376
- /**
377
- * 切换标签页
378
- */
379
- const switchTab = useCallback(tabId => {
380
- setState(prevState => {
381
- const targetTab = prevState.tabsList.find(tab => tab.id === tabId);
382
- if (!targetTab) return prevState;
264
+ const newTabs = prevState.tabsList.filter((tab) => tab.id !== tabId);
265
+ let newActiveKey = prevState.activeKey;
266
+ let newActiveTabInfo = prevState.activeTabInfo;
267
+ let newActiveComponent = prevState.activeComponent;
268
+ if (prevState.activeKey === tabId && newTabs.length > 0) {
269
+ const currentIndex = prevState.tabsList.findIndex((tab) => tab.id === tabId);
270
+ const newActiveIndex = Math.min(currentIndex, newTabs.length - 1);
271
+ newActiveTabInfo = newTabs[newActiveIndex];
272
+ newActiveKey = newActiveTabInfo.id;
273
+ newActiveComponent = ((_a = newActiveTabInfo.menuItem) == null ? void 0 : _a.code) || newActiveTabInfo.id;
274
+ } else if (prevState.activeKey === tabId) {
275
+ newActiveKey = "";
276
+ newActiveTabInfo = void 0;
277
+ newActiveComponent = "";
278
+ }
279
+ if (newTabs.length === 0) {
280
+ shouldSkipSaveRef.current = true;
281
+ clearCache();
282
+ if (finalConfig.onTabChange) {
283
+ setTimeout(() => {
284
+ finalConfig.onTabChange("", void 0, []);
285
+ }, 0);
286
+ }
287
+ }
288
+ return {
289
+ ...prevState,
290
+ tabsList: newTabs,
291
+ activeKey: newActiveKey,
292
+ activeTabInfo: newActiveTabInfo,
293
+ activeComponent: newActiveComponent
294
+ };
295
+ });
296
+ },
297
+ [clearCache, finalConfig]
298
+ );
299
+ const switchTab = useCallback((tabId) => {
300
+ setState((prevState) => {
301
+ var _a;
302
+ const targetTab = prevState.tabsList.find((tab) => tab.id === tabId);
303
+ if (!targetTab)
304
+ return prevState;
383
305
  const newState = {
384
306
  ...prevState,
385
307
  activeKey: tabId,
386
308
  activeTabInfo: targetTab,
387
- activeComponent: targetTab.menuItem?.code || tabId
309
+ activeComponent: ((_a = targetTab.menuItem) == null ? void 0 : _a.code) || tabId
388
310
  };
389
311
  return newState;
390
312
  });
391
313
  }, []);
392
-
393
- /**
394
- * Router blocker 拒绝 URL 导航时,将激活状态还原到上一个已提交页签。
395
- * 首次打开页签就被拦截时,同时移除未提交的新页签。
396
- */
397
- const rollbackTabActivation = useCallback((previousTabId, attemptedTabId, removeAttemptedTab) => {
398
- setState(prevState => {
399
- if (prevState.activeKey !== attemptedTabId) return prevState;
400
- const nextTabsList = removeAttemptedTab ? prevState.tabsList.filter(tab => tab.id !== attemptedTabId) : prevState.tabsList;
401
- const previousTab = nextTabsList.find(tab => tab.id === previousTabId);
402
- return {
403
- ...prevState,
404
- tabsList: nextTabsList,
405
- activeKey: previousTab?.id || '',
406
- activeTabInfo: previousTab,
407
- activeComponent: previousTab ? previousTab.menuItem?.code || previousTab.id : ''
408
- };
409
- });
410
- }, []);
411
-
412
- /**
413
- * 更新页签当前 URL,保持 tab.id 和 menuItem 的菜单基础路由不变。
414
- */
314
+ const rollbackTabActivation = useCallback(
315
+ (previousTabId, attemptedTabId, removeAttemptedTab) => {
316
+ setState((prevState) => {
317
+ var _a;
318
+ if (prevState.activeKey !== attemptedTabId)
319
+ return prevState;
320
+ const nextTabsList = removeAttemptedTab ? prevState.tabsList.filter((tab) => tab.id !== attemptedTabId) : prevState.tabsList;
321
+ const previousTab = nextTabsList.find((tab) => tab.id === previousTabId);
322
+ return {
323
+ ...prevState,
324
+ tabsList: nextTabsList,
325
+ activeKey: (previousTab == null ? void 0 : previousTab.id) || "",
326
+ activeTabInfo: previousTab,
327
+ activeComponent: previousTab ? ((_a = previousTab.menuItem) == null ? void 0 : _a.code) || previousTab.id : ""
328
+ };
329
+ });
330
+ },
331
+ []
332
+ );
415
333
  const updateTabUrl = useCallback((tabId, url) => {
416
- setState(prevState => {
417
- const targetIndex = prevState.tabsList.findIndex(tab => tab.id === tabId);
418
- if (targetIndex === -1 || prevState.tabsList[targetIndex].url === url) return prevState;
419
- const nextTab = {
420
- ...prevState.tabsList[targetIndex],
421
- url
422
- };
334
+ setState((prevState) => {
335
+ const targetIndex = prevState.tabsList.findIndex((tab) => tab.id === tabId);
336
+ if (targetIndex === -1 || prevState.tabsList[targetIndex].url === url)
337
+ return prevState;
338
+ const nextTab = { ...prevState.tabsList[targetIndex], url };
423
339
  const nextTabsList = [...prevState.tabsList];
424
340
  nextTabsList[targetIndex] = nextTab;
425
341
  return {
@@ -429,150 +345,113 @@ export const useTabsState = options => {
429
345
  };
430
346
  });
431
347
  }, []);
432
-
433
- /**
434
- * 关闭其他标签页
435
- */
436
- const closeOtherTabs = useCallback(currentTabId => {
437
- setState(prevState => {
438
- const currentTab = prevState.tabsList.find(tab => tab.id === currentTabId);
439
- if (!currentTab) return prevState;
440
-
441
- // 只保留当前标签页和不可关闭的标签页
442
- const newTabs = prevState.tabsList.filter(tab => tab.id === currentTabId || !tab.closable);
348
+ const closeOtherTabs = useCallback((currentTabId) => {
349
+ setState((prevState) => {
350
+ var _a;
351
+ const currentTab = prevState.tabsList.find((tab) => tab.id === currentTabId);
352
+ if (!currentTab)
353
+ return prevState;
354
+ const newTabs = prevState.tabsList.filter((tab) => tab.id === currentTabId || !tab.closable);
443
355
  return {
444
356
  ...prevState,
445
357
  tabsList: newTabs,
446
358
  activeKey: currentTabId,
447
359
  activeTabInfo: currentTab,
448
- activeComponent: currentTab.menuItem?.code || currentTabId
360
+ activeComponent: ((_a = currentTab.menuItem) == null ? void 0 : _a.code) || currentTabId
449
361
  };
450
362
  });
451
363
  }, []);
452
-
453
- /**
454
- * 关闭右侧标签页
455
- */
456
- const closeRightTabs = useCallback(currentTabId => {
457
- setState(prevState => {
364
+ const closeRightTabs = useCallback((currentTabId) => {
365
+ setState((prevState) => {
458
366
  const rightTabs = getRightTabs(prevState.tabsList, currentTabId);
459
- const tabsToKeep = prevState.tabsList.filter(tab => !rightTabs.includes(tab) || !tab.closable);
367
+ const tabsToKeep = prevState.tabsList.filter(
368
+ (tab) => !rightTabs.includes(tab) || !tab.closable
369
+ );
460
370
  return {
461
371
  ...prevState,
462
372
  tabsList: tabsToKeep
463
373
  };
464
374
  });
465
375
  }, []);
466
-
467
- /**
468
- * 关闭全部标签页
469
- */
470
376
  const closeAllTabs = useCallback(() => {
471
- setState(prevState => {
472
- // 只保留不可关闭的标签页
473
- const newTabs = prevState.tabsList.filter(tab => !tab.closable);
474
- let newActiveKey = '';
475
- let newActiveComponent = '';
377
+ setState((prevState) => {
378
+ var _a;
379
+ const newTabs = prevState.tabsList.filter((tab) => !tab.closable);
380
+ let newActiveKey = "";
381
+ let newActiveComponent = "";
476
382
  if (newTabs.length > 0) {
477
383
  const firstTab = newTabs[0];
478
384
  newActiveKey = firstTab.id;
479
- newActiveComponent = firstTab.menuItem?.code || firstTab.id;
385
+ newActiveComponent = ((_a = firstTab.menuItem) == null ? void 0 : _a.code) || firstTab.id;
480
386
  }
481
-
482
- // 关闭全部标签页时,清空缓存
483
- // 标记跳过下次保存,避免清空后又被重新保存
484
387
  shouldSkipSaveRef.current = true;
485
388
  clearCache();
486
-
487
- // 直接调用 onTabChange(useEffect 因 shouldSkipSaveRef 会跳过)
488
389
  if (finalConfig.onTabChange) {
489
- const firstTab = newTabs.length > 0 ? newTabs[0] : undefined;
390
+ const firstTab = newTabs.length > 0 ? newTabs[0] : void 0;
490
391
  setTimeout(() => {
491
- finalConfig.onTabChange(firstTab?.id ?? '', firstTab, newTabs);
392
+ finalConfig.onTabChange((firstTab == null ? void 0 : firstTab.id) ?? "", firstTab, newTabs);
492
393
  }, 0);
493
394
  }
494
395
  return {
495
396
  ...prevState,
496
397
  tabsList: newTabs,
497
398
  activeKey: newActiveKey,
498
- activeTabInfo: newTabs.length > 0 ? newTabs[0] : undefined,
399
+ activeTabInfo: newTabs.length > 0 ? newTabs[0] : void 0,
499
400
  activeComponent: newActiveComponent
500
401
  };
501
402
  });
502
403
  }, [clearCache, finalConfig]);
503
-
504
- /**
505
- * 重排标签页顺序(拖拽结束后调用)
506
- * 应用固定分区约束:普通标签不可拖入固定区、固定标签不可拖出固定区
507
- */
508
404
  const reorderTabs = useCallback((activeId, overId) => {
509
- setState(prevState => {
405
+ setState((prevState) => {
510
406
  const nextTabsList = reorderWithPinConstraint(prevState.tabsList, activeId, overId);
511
- if (nextTabsList === prevState.tabsList) return prevState;
512
- return {
513
- ...prevState,
514
- tabsList: nextTabsList
515
- };
407
+ if (nextTabsList === prevState.tabsList)
408
+ return prevState;
409
+ return { ...prevState, tabsList: nextTabsList };
516
410
  });
517
411
  }, []);
518
-
519
- /**
520
- * 固定标签页:设为 pinned/不可关闭并移动到固定区末尾
521
- */
522
- const pinTab = useCallback(tabId => {
523
- setState(prevState => {
412
+ const pinTab = useCallback((tabId) => {
413
+ setState((prevState) => {
524
414
  const nextTabsList = pinTabInList(prevState.tabsList, tabId);
525
- if (nextTabsList === prevState.tabsList) return prevState;
526
- const nextActiveTabInfo = prevState.activeKey === tabId ? nextTabsList.find(tab => tab.id === tabId) : prevState.activeTabInfo;
527
- return {
528
- ...prevState,
529
- tabsList: nextTabsList,
530
- activeTabInfo: nextActiveTabInfo
531
- };
415
+ if (nextTabsList === prevState.tabsList)
416
+ return prevState;
417
+ const nextActiveTabInfo = prevState.activeKey === tabId ? nextTabsList.find((tab) => tab.id === tabId) : prevState.activeTabInfo;
418
+ return { ...prevState, tabsList: nextTabsList, activeTabInfo: nextActiveTabInfo };
532
419
  });
533
420
  }, []);
534
-
535
- /**
536
- * 取消固定标签页:设为可关闭并移动到普通区最前
537
- */
538
- const unpinTab = useCallback(tabId => {
539
- setState(prevState => {
421
+ const unpinTab = useCallback((tabId) => {
422
+ setState((prevState) => {
540
423
  const nextTabsList = unpinTabInList(prevState.tabsList, tabId);
541
- if (nextTabsList === prevState.tabsList) return prevState;
542
- const nextActiveTabInfo = prevState.activeKey === tabId ? nextTabsList.find(tab => tab.id === tabId) : prevState.activeTabInfo;
543
- return {
544
- ...prevState,
545
- tabsList: nextTabsList,
546
- activeTabInfo: nextActiveTabInfo
547
- };
424
+ if (nextTabsList === prevState.tabsList)
425
+ return prevState;
426
+ const nextActiveTabInfo = prevState.activeKey === tabId ? nextTabsList.find((tab) => tab.id === tabId) : prevState.activeTabInfo;
427
+ return { ...prevState, tabsList: nextTabsList, activeTabInfo: nextActiveTabInfo };
548
428
  });
549
429
  }, []);
550
-
551
- /**
552
- * 重置状态
553
- */
554
430
  const resetTabs = useCallback(() => {
555
431
  setState({
556
432
  tabsList: [],
557
- activeKey: '',
433
+ activeKey: "",
558
434
  newTabIndex: 0,
559
- activeComponent: ''
435
+ activeComponent: ""
560
436
  });
561
437
  }, []);
562
-
563
- // URL 不同步模式保留旧有的 pathname -> Tabs 初始匹配,但不写回 URL。
564
438
  useEffect(() => {
565
- if (urlSyncEnabled) return;
566
- if (!dataSource || !('menus' in dataSource)) return;
439
+ if (urlSyncEnabled)
440
+ return;
441
+ if (!dataSource || !("menus" in dataSource))
442
+ return;
567
443
  const currentPath = window.location.pathname;
568
- const activeTab = state.tabsList.find(tab => tab.id === state.activeKey);
569
- if (activeTab && activeTab.url === currentPath) return;
444
+ const activeTab = state.tabsList.find((tab) => tab.id === state.activeKey);
445
+ if (activeTab && activeTab.url === currentPath)
446
+ return;
570
447
  const flatMenus = flattenMenuData(dataSource.menus || []);
571
- const targetMenu = flatMenus.find(item => getMenuRoute(item) === currentPath);
572
- if (!targetMenu || !canOpenAsTab(targetMenu)) return;
448
+ const targetMenu = flatMenus.find((item) => getMenuRoute(item) === currentPath);
449
+ if (!targetMenu || !canOpenAsTab(targetMenu))
450
+ return;
573
451
  const existingTab = findExistingTab(state.tabsList, targetMenu);
574
452
  if (existingTab) {
575
- if (state.activeKey !== existingTab.id) switchTab(existingTab.id);
453
+ if (state.activeKey !== existingTab.id)
454
+ switchTab(existingTab.id);
576
455
  return;
577
456
  }
578
457
  addTab(targetMenu);
@@ -595,4 +474,7 @@ export const useTabsState = options => {
595
474
  pinTab,
596
475
  unpinTab
597
476
  };
598
- };
477
+ };
478
+ export {
479
+ useTabsState
480
+ };