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