@zat-design/sisyphus-react 4.0.13 → 4.0.14

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 (41) hide show
  1. package/dist/index.esm.css +1 -1
  2. package/dist/less.esm.css +1 -1
  3. package/es/ProEditLabel/index.js +81 -31
  4. package/es/ProEditLabel/propsType.d.ts +4 -4
  5. package/es/ProForm/components/combination/Group/utils/index.d.ts +17 -17
  6. package/es/ProLayout/components/Layout/Menu/FoldMenu/index.js +42 -9
  7. package/es/ProLayout/components/Layout/Menu/OpenMenu/index.js +9 -8
  8. package/es/ProLayout/components/TabsManager/components/TabItem.js +9 -1
  9. package/es/ProLayout/components/TabsManager/hooks/useTabsState.js +52 -7
  10. package/es/ProLayout/components/TabsManager/index.js +52 -16
  11. package/es/ProLayout/components/TabsManager/propTypes.d.ts +2 -0
  12. package/es/ProLayout/components/TabsManager/style/index.less +115 -3
  13. package/es/ProLayout/index.js +30 -16
  14. package/es/ProLayout/propTypes.d.ts +3 -3
  15. package/es/ProLayout/utils/index.js +85 -21
  16. package/es/ProTable/style/index.less +19 -3
  17. package/es/ProWaterMark/propsType.d.ts +3 -61
  18. package/es/locale/en_US.d.ts +1 -0
  19. package/es/locale/en_US.js +2 -1
  20. package/es/locale/zh_CN.d.ts +1 -0
  21. package/es/locale/zh_CN.js +2 -1
  22. package/lib/ProEditLabel/index.js +81 -31
  23. package/lib/ProEditLabel/propsType.d.ts +4 -4
  24. package/lib/ProForm/components/combination/Group/utils/index.d.ts +17 -17
  25. package/lib/ProLayout/components/Layout/Menu/FoldMenu/index.js +42 -9
  26. package/lib/ProLayout/components/Layout/Menu/OpenMenu/index.js +9 -8
  27. package/lib/ProLayout/components/TabsManager/components/TabItem.js +9 -1
  28. package/lib/ProLayout/components/TabsManager/hooks/useTabsState.js +54 -7
  29. package/lib/ProLayout/components/TabsManager/index.js +52 -16
  30. package/lib/ProLayout/components/TabsManager/propTypes.d.ts +2 -0
  31. package/lib/ProLayout/components/TabsManager/style/index.less +115 -3
  32. package/lib/ProLayout/index.js +30 -16
  33. package/lib/ProLayout/propTypes.d.ts +3 -3
  34. package/lib/ProLayout/utils/index.js +85 -21
  35. package/lib/ProTable/style/index.less +19 -3
  36. package/lib/ProWaterMark/propsType.d.ts +3 -61
  37. package/lib/locale/en_US.d.ts +1 -0
  38. package/lib/locale/en_US.js +2 -1
  39. package/lib/locale/zh_CN.d.ts +1 -0
  40. package/lib/locale/zh_CN.js +2 -1
  41. package/package.json +1 -1
@@ -67,6 +67,11 @@ var ProEditLabel = _ref => {
67
67
  _Form$useForm4 = _slicedToArray(_Form$useForm3, 1),
68
68
  viewForm = _Form$useForm4[0];
69
69
  var inputRef = useRef(null);
70
+
71
+ // 类型断言:antd FormInstance 确实有这些方法(setFieldsValue, validateFields等)
72
+ // 使用类型断言解决 TypeScript 类型检查问题
73
+ var formInstance = form;
74
+ var viewFormInstance = viewForm;
70
75
  var onPress = e => {
71
76
  var element = e.target;
72
77
  if (e.key === 'Enter') {
@@ -82,9 +87,16 @@ var ProEditLabel = _ref => {
82
87
  if (mode === 'popup') {
83
88
  // 兼容老写法
84
89
  if (!popupProps.columns) {
85
- form.setFieldValue((popupProps === null || popupProps === void 0 ? void 0 : popupProps.type) || 'Input', confirmValue);
90
+ if (!(popupProps !== null && popupProps !== void 0 && popupProps.type)) {
91
+ console.warn('ProEditLabel: popupProps.type is required when using old API (without columns)');
92
+ return;
93
+ }
94
+ formInstance.setFieldsValue({
95
+ [popupProps.type]: confirmValue
96
+ });
86
97
  } else {
87
- form.setFieldsValue(confirmValue || {});
98
+ var matchedValue = matchFormValue(confirmValue, popupProps.columns);
99
+ formInstance.setFieldsValue(matchedValue || {});
88
100
  }
89
101
  // 弹窗同步最新value数据,解决Popconfirm空白处关闭数据不同步问题
90
102
  setState({
@@ -112,13 +124,21 @@ var ProEditLabel = _ref => {
112
124
  if (mode === 'popup' && props.value) {
113
125
  // 兼容老写法
114
126
  if (!popupProps.columns) {
115
- form.setFieldValue((popupProps === null || popupProps === void 0 ? void 0 : popupProps.type) || 'Input', props.value);
127
+ if (!(popupProps !== null && popupProps !== void 0 && popupProps.type)) {
128
+ console.warn('ProEditLabel: popupProps.type is required when using old API (without columns)');
129
+ return;
130
+ }
131
+ formInstance.setFieldsValue({
132
+ [popupProps.type]: props.value
133
+ });
116
134
  // 文本模式初始化赋值
117
- viewForm.setFieldValue((popupProps === null || popupProps === void 0 ? void 0 : popupProps.type) || 'Input', props.value);
135
+ viewFormInstance.setFieldsValue({
136
+ [popupProps.type]: props.value
137
+ });
118
138
  } else {
119
- form.setFieldsValue(matchFormValue(props.value, popupProps.columns) || {});
139
+ formInstance.setFieldsValue(matchFormValue(props.value, popupProps.columns) || {});
120
140
  // 文本模式初始化赋值
121
- viewForm.setFieldsValue(matchFormValue(props.value, popupProps.columns) || {});
141
+ viewFormInstance.setFieldsValue(matchFormValue(props.value, popupProps.columns) || {});
122
142
  }
123
143
  }
124
144
  }, [props.value, mode]);
@@ -129,9 +149,15 @@ var ProEditLabel = _ref => {
129
149
  if (mode === 'popup' && confirmValue !== props.value) {
130
150
  // 兼容老写法
131
151
  if (!popupProps.columns) {
132
- viewForm.setFieldValue((popupProps === null || popupProps === void 0 ? void 0 : popupProps.type) || 'Input', confirmValue);
152
+ if (!(popupProps !== null && popupProps !== void 0 && popupProps.type)) {
153
+ console.warn('ProEditLabel: popupProps.type is required when using old API (without columns)');
154
+ return;
155
+ }
156
+ viewFormInstance.setFieldsValue({
157
+ [popupProps.type]: confirmValue
158
+ });
133
159
  } else {
134
- viewForm.setFieldsValue(matchFormValue(confirmValue, popupProps.columns) || {});
160
+ viewFormInstance.setFieldsValue(matchFormValue(confirmValue, popupProps.columns) || {});
135
161
  }
136
162
  }
137
163
  }, [confirmValue, mode]);
@@ -150,53 +176,71 @@ var ProEditLabel = _ref => {
150
176
  */
151
177
  var onConfirmHandle = /*#__PURE__*/function () {
152
178
  var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
153
- var res, value;
179
+ var res, value, fieldName;
154
180
  return _regeneratorRuntime().wrap(function _callee$(_context) {
155
181
  while (1) switch (_context.prev = _context.next) {
156
182
  case 0:
157
183
  _context.next = 2;
158
- return form.validateFields();
184
+ return formInstance.validateFields();
159
185
  case 2:
160
186
  res = _context.sent;
161
- // 兼容老写法
162
- if (!popupProps.columns) {
163
- value = res[(popupProps === null || popupProps === void 0 ? void 0 : popupProps.type) || 'Input'];
187
+ if (popupProps.columns) {
188
+ _context.next = 10;
189
+ break;
190
+ }
191
+ if (popupProps !== null && popupProps !== void 0 && popupProps.type) {
192
+ _context.next = 7;
193
+ break;
164
194
  }
165
- value = res;
166
- _context.prev = 5;
195
+ console.warn('ProEditLabel: popupProps.type is required when using old API (without columns)');
196
+ return _context.abrupt("return", Promise.reject(new Error('popupProps.type is required')));
197
+ case 7:
198
+ value = res[popupProps.type];
199
+ _context.next = 11;
200
+ break;
201
+ case 10:
202
+ // 新写法:如果只有一个字段,提取单个值;否则使用整个对象
203
+ if (popupProps.columns.length === 1) {
204
+ fieldName = popupProps.columns[0].name || popupProps.columns[0].type;
205
+ value = res[fieldName];
206
+ } else {
207
+ value = res;
208
+ }
209
+ case 11:
210
+ _context.prev = 11;
167
211
  _context.t0 = onFinish;
168
212
  if (!_context.t0) {
169
- _context.next = 10;
213
+ _context.next = 16;
170
214
  break;
171
215
  }
172
- _context.next = 10;
216
+ _context.next = 16;
173
217
  return onFinish(value);
174
- case 10:
218
+ case 16:
175
219
  _context.t1 = onConfirm;
176
220
  if (!_context.t1) {
177
- _context.next = 14;
221
+ _context.next = 20;
178
222
  break;
179
223
  }
180
- _context.next = 14;
224
+ _context.next = 20;
181
225
  return onConfirm(value);
182
- case 14:
183
- _context.next = 16;
226
+ case 20:
227
+ _context.next = 22;
184
228
  return setState({
185
229
  confirmValue: value,
186
230
  popValue: value
187
231
  });
188
- case 16:
189
- _context.next = 21;
232
+ case 22:
233
+ _context.next = 27;
190
234
  break;
191
- case 18:
192
- _context.prev = 18;
193
- _context.t2 = _context["catch"](5);
235
+ case 24:
236
+ _context.prev = 24;
237
+ _context.t2 = _context["catch"](11);
194
238
  return _context.abrupt("return", Promise.reject());
195
- case 21:
239
+ case 27:
196
240
  case "end":
197
241
  return _context.stop();
198
242
  }
199
- }, _callee, null, [[5, 18]]);
243
+ }, _callee, null, [[11, 24]]);
200
244
  }));
201
245
  return function onConfirmHandle() {
202
246
  return _ref2.apply(this, arguments);
@@ -209,9 +253,15 @@ var ProEditLabel = _ref => {
209
253
  var onCancelHandle = () => {
210
254
  // 兼容老写法
211
255
  if (!popupProps.columns) {
212
- form.setFieldValue((popupProps === null || popupProps === void 0 ? void 0 : popupProps.type) || 'Input', props.value);
256
+ if (!(popupProps !== null && popupProps !== void 0 && popupProps.type)) {
257
+ console.warn('ProEditLabel: popupProps.type is required when using old API (without columns)');
258
+ return;
259
+ }
260
+ formInstance.setFieldsValue({
261
+ [popupProps.type]: props.value
262
+ });
213
263
  } else {
214
- form.setFieldsValue(matchFormValue(props.value, popupProps.columns) || {});
264
+ formInstance.setFieldsValue(matchFormValue(props.value, popupProps.columns) || {});
215
265
  }
216
266
  setState({
217
267
  popValue: props.value
@@ -2,7 +2,7 @@ import { InputProps } from 'antd/es/input';
2
2
  import { PopconfirmProps } from 'antd/es/popconfirm';
3
3
  import { FormInstance } from 'antd/es/form';
4
4
  import React from 'react';
5
- import type { ProFormColumnType } from '../index';
5
+ import type { ProFormColumnType } from '../ProForm/propsType';
6
6
  export interface ContainerType {
7
7
  /**
8
8
  * @description 触发方式
@@ -77,13 +77,13 @@ export interface PopupType {
77
77
  * @description 列配置
78
78
  * @default -
79
79
  */
80
- columns?: ProFormColumnType;
80
+ columns?: ProFormColumnType[];
81
81
  /**
82
82
  * @description 允许扩展字段
83
83
  */
84
84
  [key: string]: any;
85
85
  }
86
- export interface LabelType extends InputProps {
86
+ export interface LabelType extends Omit<InputProps, 'onChange'> {
87
87
  /**
88
88
  * @description 是否打开
89
89
  * @default false
@@ -98,7 +98,7 @@ export interface LabelType extends InputProps {
98
98
  * @description 值变化回调
99
99
  * @default -
100
100
  */
101
- onChange?: (value: React.ChangeEvent<HTMLInputElement>) => void;
101
+ onChange?: (value: any) => void;
102
102
  /**
103
103
  * @description 是否可编辑
104
104
  * @default false
@@ -76,34 +76,35 @@ export declare const useFormItemProps: (column: FlexibleGroupColumnType, context
76
76
  show?: boolean | ReactiveFunction<any, boolean>;
77
77
  component?: React.ReactNode | ReactiveFunction<any, React.ReactNode>;
78
78
  children?: React.ReactNode | ((form: FormInstance<any>) => React.ReactNode);
79
- isView?: boolean;
80
- id?: string;
81
- prefixCls?: string;
82
- className?: string;
83
79
  style?: React.CSSProperties;
80
+ className?: string;
84
81
  rootClassName?: string;
82
+ trim?: boolean;
83
+ normalize?: (value: any, prevValue: any, allValues: import("@rc-component/form/lib/interface").Store) => any;
85
84
  hidden?: boolean;
85
+ layout?: import("antd/es/form/Form").FormItemLayout;
86
+ help?: React.ReactNode;
87
+ vertical?: boolean;
88
+ preserve?: boolean;
89
+ id?: string;
86
90
  onReset?: () => void;
91
+ prefixCls?: string;
92
+ htmlFor?: string;
93
+ trigger?: string;
87
94
  status?: "" | "warning" | "error" | "success" | "validating";
88
- vertical?: boolean;
89
- validateTrigger?: string | false | string[];
90
- getValueProps?: ((value: any) => Record<string, unknown>) & ((value: any) => Record<string, unknown>);
91
- desensitization?: [number, number] | ReactiveFunction<any, [number, number]>;
92
- valueType?: import("../../../render/propsType").ProFormValueType;
95
+ isView?: boolean;
93
96
  colon?: boolean;
94
- htmlFor?: string;
95
97
  labelAlign?: import("antd/es/form/interface").FormLabelAlign;
96
98
  labelCol?: import("antd").ColProps;
97
99
  getValueFromEvent?: (...args: import("@rc-component/form/lib/interface").EventArgs) => any;
98
- normalize?: (value: any, prevValue: any, allValues: import("@rc-component/form/lib/interface").Store) => any;
99
100
  shouldUpdate?: import("@rc-component/form/lib/Field").ShouldUpdate<any>;
100
- trigger?: string;
101
+ validateTrigger?: string | false | string[];
101
102
  validateDebounce?: number;
102
103
  valuePropName?: string;
104
+ getValueProps?: ((value: any) => Record<string, unknown>) & ((value: any) => Record<string, unknown>);
103
105
  messageVariables?: Record<string, string>;
104
106
  initialValue?: any;
105
107
  onMetaChange?: (meta: import("@rc-component/form/lib/Field").MetaEvent) => void;
106
- preserve?: boolean;
107
108
  isListField?: boolean;
108
109
  isList?: boolean;
109
110
  noStyle?: boolean;
@@ -111,10 +112,9 @@ export declare const useFormItemProps: (column: FlexibleGroupColumnType, context
111
112
  icons: import("antd/es/form/FormItem").FeedbackIcons;
112
113
  };
113
114
  validateStatus?: "" | "warning" | "error" | "success" | "validating";
114
- layout?: import("antd/es/form/Form").FormItemLayout;
115
115
  wrapperCol?: import("antd").ColProps;
116
- help?: React.ReactNode;
117
116
  fieldId?: string;
117
+ valueType?: import("../../../render/propsType").ProFormValueType;
118
118
  switchValue?: [any, any];
119
119
  viewRender?: (value: any, record: any, { form, index, namePath, }: {
120
120
  [key: string]: any;
@@ -122,11 +122,11 @@ export declare const useFormItemProps: (column: FlexibleGroupColumnType, context
122
122
  index?: number;
123
123
  }) => string | React.ReactElement<any, any>;
124
124
  viewType?: import("../../../render/propsType").ViewType;
125
- trim?: boolean;
126
125
  upperCase?: boolean;
127
126
  toISOString?: boolean;
128
127
  toCSTString?: boolean;
129
128
  clearNotShow?: boolean;
129
+ desensitization?: [number, number] | ReactiveFunction<any, [number, number]>;
130
130
  name: any;
131
131
  dependencies: any[];
132
132
  tooltip: string | {
@@ -141,7 +141,7 @@ export declare const useFormItemProps: (column: FlexibleGroupColumnType, context
141
141
  * 创建组件属性
142
142
  */
143
143
  export declare const createComponentProps: (column: FlexibleGroupColumnType, formItemProps: any) => {
144
- componentProps: import("lodash").Omit<any, "precision" | "format" | "valueType" | "switchValue" | "dependNames" | "toISOString" | "toCSTString" | "clearNotShow">;
144
+ componentProps: import("lodash").Omit<any, "format" | "valueType" | "switchValue" | "dependNames" | "toISOString" | "toCSTString" | "clearNotShow" | "precision">;
145
145
  formItemTransform: {
146
146
  getValueProps: any;
147
147
  normalize: any;
@@ -108,13 +108,25 @@ var FoldMenu = props => {
108
108
  var menuItem = findMenuItemByKey(menus, String(id));
109
109
  var menuKeyPath = menuItem !== null && menuItem !== void 0 && menuItem.keyIdPath ? menuItem.keyIdPath.map(id => String(id)) : [String(id)];
110
110
 
111
- // 调用用户传入的onMenuClick回调
111
+ // 调用用户传入的onMenuClick回调,获取返回值(是否应该激活菜单)
112
+ var shouldActivate = true;
112
113
  if (onMenuClick) {
113
- onMenuClick({
114
+ var result = onMenuClick({
114
115
  item: menuItem,
115
116
  key: String(id),
116
117
  keyPath: menuKeyPath
117
118
  });
119
+ // 如果返回 false,表示不应该激活菜单
120
+ if (result === false) {
121
+ shouldActivate = false;
122
+ }
123
+ }
124
+
125
+ // 只有在 shouldActivate 为 true 时才设置选中状态
126
+ if (shouldActivate) {
127
+ onSelected({
128
+ selectedPath: toPath
129
+ });
118
130
  }
119
131
  },
120
132
  children: LiNode
@@ -128,17 +140,26 @@ var FoldMenu = props => {
128
140
  var menuItem = findMenuItemByKey(menus, String(id));
129
141
  var menuKeyPath = menuItem !== null && menuItem !== void 0 && menuItem.keyIdPath ? menuItem.keyIdPath.map(id => String(id)) : [String(id)];
130
142
 
131
- // 调用用户传入的onMenuClick回调
143
+ // 调用用户传入的onMenuClick回调,获取返回值(是否应该激活菜单)
144
+ var shouldActivate = true;
132
145
  if (onMenuClick) {
133
- onMenuClick({
146
+ var result = onMenuClick({
134
147
  item: menuItem,
135
148
  key: String(id),
136
149
  keyPath: menuKeyPath
137
150
  });
151
+ // 如果返回 false,表示不应该激活菜单
152
+ if (result === false) {
153
+ shouldActivate = false;
154
+ }
155
+ }
156
+
157
+ // 只有在 shouldActivate 为 true 时才设置选中状态
158
+ if (shouldActivate) {
159
+ onSelected({
160
+ selectedPath: toPath
161
+ });
138
162
  }
139
- onSelected({
140
- selectedPath: toPath
141
- });
142
163
  },
143
164
  children: /*#__PURE__*/_jsx(Link, {
144
165
  to: toPath,
@@ -151,13 +172,25 @@ var FoldMenu = props => {
151
172
  var menuItem = findMenuItemByKey(menus, String(id));
152
173
  var menuKeyPath = menuItem !== null && menuItem !== void 0 && menuItem.keyIdPath ? menuItem.keyIdPath.map(id => String(id)) : [String(id)];
153
174
 
154
- // 调用用户传入的onMenuClick回调
175
+ // 调用用户传入的onMenuClick回调,获取返回值(是否应该激活菜单)
176
+ var shouldActivate = true;
155
177
  if (onMenuClick) {
156
- onMenuClick({
178
+ var result = onMenuClick({
157
179
  item: menuItem,
158
180
  key: String(id),
159
181
  keyPath: menuKeyPath
160
182
  });
183
+ // 如果返回 false,表示不应该激活菜单
184
+ if (result === false) {
185
+ shouldActivate = false;
186
+ }
187
+ }
188
+
189
+ // 只有在 shouldActivate 为 true 时才设置选中状态
190
+ if (shouldActivate) {
191
+ onSelected({
192
+ selectedPath: toPath
193
+ });
161
194
  }
162
195
  },
163
196
  children: /*#__PURE__*/_jsx(Link, {
@@ -156,26 +156,27 @@ var OpenMenu = props => {
156
156
  keyPath = _ref2.keyPath,
157
157
  key = _ref2.key,
158
158
  domEvent = _ref2.domEvent;
159
- // console.log('item', item);
160
- // console.log('keyPath', keyPath);
161
- // console.log('key', key);
162
- // console.log('domEvent', domEvent);
163
-
164
159
  // 查找完整的菜单项数据
165
160
  var menuItem = findMenuItemByKey(menus, key);
166
161
  var menuKeyPath = menuItem !== null && menuItem !== void 0 && menuItem.keyIdPath ? menuItem.keyIdPath.map(id => String(id)) : keyPath;
167
162
 
168
- // 调用用户传入的onMenuClick回调
163
+ // 调用用户传入的onMenuClick回调,获取返回值(是否应该激活菜单)
164
+ var shouldActivate = true;
169
165
  if (onMenuClick) {
170
- onMenuClick({
166
+ var result = onMenuClick({
171
167
  item: menuItem,
172
168
  key,
173
169
  keyPath: menuKeyPath
174
170
  });
171
+ // 如果返回 false,表示不应该激活菜单
172
+ if (result === false) {
173
+ shouldActivate = false;
174
+ }
175
175
  }
176
176
 
177
177
  // 只有最后一级菜单(叶子节点)才设置选中状态和路径
178
- if (menuItem && isLeafMenuItem(menuItem)) {
178
+ // 并且只有在 shouldActivate true 时才设置
179
+ if (menuItem && isLeafMenuItem(menuItem) && shouldActivate) {
179
180
  var _item$props, _item$props2;
180
181
  setState({
181
182
  selectedKeys: keyPath,
@@ -22,6 +22,14 @@ var TabItemComponent = _ref => {
22
22
  e.stopPropagation();
23
23
  _onClose();
24
24
  };
25
+
26
+ // 作为 antd Tabs label 使用时,不需要阻止事件冒泡
27
+ // antd Tabs 会通过 onChange 处理切换,我们的 onClick 作为备用
28
+ var handleLabelClick = e => {
29
+ // 不阻止冒泡,让 antd Tabs 处理切换
30
+ // 但我们也调用 onClick 以确保状态同步
31
+ onClick();
32
+ };
25
33
  return /*#__PURE__*/_jsx(TabContextMenu, {
26
34
  tabId: tab.id,
27
35
  closable: tab.closable,
@@ -35,7 +43,7 @@ var TabItemComponent = _ref => {
35
43
  tabMenuClick: tabMenuClick,
36
44
  children: /*#__PURE__*/_jsx("div", {
37
45
  className: `pro-layout-tab-item ${active ? 'active' : ''} ${tab.closable ? 'closable' : ''}`,
38
- onClick: onClick,
46
+ onClick: handleLabelClick,
39
47
  "data-testid": `tab-${tab.id}`,
40
48
  children: /*#__PURE__*/_jsxs("div", {
41
49
  className: "pro-layout-tab-content",
@@ -10,8 +10,10 @@ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key i
10
10
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : String(i); }
11
11
  function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
12
12
  import { useState, useCallback, useEffect, useRef } from 'react';
13
+ import { message } from 'antd';
13
14
  import { DEFAULT_TABS_CONFIG } from "../propTypes";
14
15
  import { useTabsCache } from "./useTabsCache";
16
+ import locale, { formatMessage } from "../../../../locale";
15
17
  import { createTabFromMenu, generateTabId, shouldOpenExternal, handleExternalOpen, checkTabLimit, getRightTabs, flattenMenuData, isLeafMenuItem } from "../utils";
16
18
 
17
19
  /**
@@ -106,12 +108,50 @@ export var useTabsState = options => {
106
108
  }, [state, saveToCache, finalConfig, isInitialized]);
107
109
 
108
110
  /**
109
- * 添加标签页
111
+ * 检查是否可以添加标签页(用于在菜单点击时判断是否应该激活菜单)
110
112
  */
111
- var addTab = useCallback((menuItem, options) => {
113
+ var canAddTab = useCallback((menuItem, options) => {
112
114
  var _ref = options || {},
113
115
  _ref$forceNew = _ref.forceNew,
114
116
  forceNew = _ref$forceNew === void 0 ? false : _ref$forceNew;
117
+
118
+ // 只有最后一级菜单(叶子节点)才能添加标签页
119
+ if (!isLeafMenuItem(menuItem)) {
120
+ return false;
121
+ }
122
+
123
+ // 检查是否需要外部跳转
124
+ if (shouldOpenExternal(menuItem)) {
125
+ return false;
126
+ }
127
+
128
+ // 如果 forceNew = false(默认),检查是否已存在相同的标签页
129
+ if (!forceNew) {
130
+ var existingTab = state.tabsList.find(tab => {
131
+ var _tab$menuItem;
132
+ return ((_tab$menuItem = tab.menuItem) === null || _tab$menuItem === void 0 ? void 0 : _tab$menuItem.code) === menuItem.code || tab.url === menuItem.url;
133
+ });
134
+ if (existingTab) {
135
+ // 如果已存在,可以添加(会切换到已存在的标签页)
136
+ return true;
137
+ }
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
+ var addTab = useCallback((menuItem, options) => {
152
+ var _ref2 = options || {},
153
+ _ref2$forceNew = _ref2.forceNew,
154
+ forceNew = _ref2$forceNew === void 0 ? false : _ref2$forceNew;
115
155
  setState(prevState => {
116
156
  // 只有最后一级菜单(叶子节点)才能添加标签页
117
157
  if (!isLeafMenuItem(menuItem)) {
@@ -129,8 +169,8 @@ export var useTabsState = options => {
129
169
  // 如果 forceNew = false(默认),检查是否已存在相同的标签页
130
170
  if (!forceNew) {
131
171
  var existingTab = prevState.tabsList.find(tab => {
132
- var _tab$menuItem;
133
- return ((_tab$menuItem = tab.menuItem) === null || _tab$menuItem === void 0 ? void 0 : _tab$menuItem.code) === menuItem.code || tab.url === menuItem.url;
172
+ var _tab$menuItem2;
173
+ return ((_tab$menuItem2 = tab.menuItem) === null || _tab$menuItem2 === void 0 ? void 0 : _tab$menuItem2.code) === menuItem.code || tab.url === menuItem.url;
134
174
  });
135
175
  if (existingTab) {
136
176
  var _existingTab$menuItem;
@@ -146,7 +186,11 @@ export var useTabsState = options => {
146
186
 
147
187
  // 检查是否超出限制
148
188
  if (checkTabLimit(prevState.tabsList, finalConfig.max)) {
149
- // 达到最大值时,不添加新标签页,直接返回
189
+ // 达到最大值时,不添加新标签页,显示提示信息
190
+ var messageText = formatMessage(locale.ProLayout.tabMaxLimitMessage, {
191
+ max: finalConfig.max
192
+ });
193
+ message.info(messageText);
150
194
  return prevState;
151
195
  }
152
196
 
@@ -337,8 +381,8 @@ export var useTabsState = options => {
337
381
 
338
382
  // 检查是否已在 Tabs 中
339
383
  var existingTab = state.tabsList.find(tab => {
340
- var _tab$menuItem2;
341
- return ((_tab$menuItem2 = tab.menuItem) === null || _tab$menuItem2 === void 0 ? void 0 : _tab$menuItem2.code) === targetMenu.code || tab.url === targetMenu.url;
384
+ var _tab$menuItem3;
385
+ return ((_tab$menuItem3 = tab.menuItem) === null || _tab$menuItem3 === void 0 ? void 0 : _tab$menuItem3.code) === targetMenu.code || tab.url === targetMenu.url;
342
386
  });
343
387
  if (existingTab) {
344
388
  // 如果已存在,切换到该 Tab
@@ -354,6 +398,7 @@ export var useTabsState = options => {
354
398
  return {
355
399
  state,
356
400
  addTab,
401
+ canAddTab,
357
402
  removeTab,
358
403
  switchTab,
359
404
  closeOtherTabs,
@@ -10,6 +10,7 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
10
10
  function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
11
11
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
12
12
  import { useCallback, useMemo, forwardRef, useImperativeHandle, useState, useEffect } from 'react';
13
+ import { Tabs } from 'antd';
13
14
  import { useTabsState } from "./hooks/useTabsState";
14
15
  import { TabItemComponent } from "./components/TabItem";
15
16
  import { TabsContext } from "./components/TabsContext";
@@ -31,6 +32,7 @@ var TabsManager = /*#__PURE__*/forwardRef((_ref, ref) => {
31
32
  }),
32
33
  state = _useTabsState.state,
33
34
  _addTab = _useTabsState.addTab,
35
+ canAddTab = _useTabsState.canAddTab,
34
36
  removeTab = _useTabsState.removeTab,
35
37
  switchTab = _useTabsState.switchTab,
36
38
  closeOtherTabs = _useTabsState.closeOtherTabs,
@@ -96,25 +98,58 @@ var TabsManager = /*#__PURE__*/forwardRef((_ref, ref) => {
96
98
  })
97
99
  }), [_addTab, removeTab, state.tabsList, state.activeKey, state.activeComponent]);
98
100
 
101
+ // 处理标签切换
102
+ var handleTabChange = useCallback(activeKey => {
103
+ switchTab(activeKey);
104
+ }, [switchTab]);
105
+
106
+ // 处理标签关闭
107
+ var handleTabEdit = useCallback((targetKey, action) => {
108
+ if (action === 'remove') {
109
+ removeTab(targetKey);
110
+ }
111
+ }, [removeTab]);
112
+
113
+ // 构建 Tabs items
114
+ var tabsItems = useMemo(() => {
115
+ if (state.tabsList.length === 0) return [];
116
+ return state.tabsList.map(tab => ({
117
+ key: tab.id,
118
+ label: /*#__PURE__*/_jsx(TabItemComponent, {
119
+ tab: tab,
120
+ active: tab.id === state.activeKey,
121
+ onClick: () => switchTab(tab.id),
122
+ onClose: () => removeTab(tab.id),
123
+ onCloseOthers: () => closeOtherTabs(tab.id),
124
+ onCloseRight: () => closeRightTabs(tab.id),
125
+ onCloseAll: closeAllTabs,
126
+ tabsList: state.tabsList,
127
+ menuItems: config === null || config === void 0 ? void 0 : config.menuItems,
128
+ tabMenuClick: config === null || config === void 0 ? void 0 : config.tabMenuClick
129
+ }),
130
+ closable: tab.closable,
131
+ children: null // 内容在 renderContent() 中渲染
132
+ }));
133
+ }, [state.tabsList, state.activeKey, config === null || config === void 0 ? void 0 : config.menuItems, config === null || config === void 0 ? void 0 : config.tabMenuClick, switchTab, removeTab, closeOtherTabs, closeRightTabs, closeAllTabs]);
134
+
99
135
  // 渲染标签页列表
100
136
  var renderTabList = () => {
101
137
  if (state.tabsList.length === 0) return null;
102
138
  return /*#__PURE__*/_jsx("div", {
103
139
  className: "pro-layout-tabs-header",
104
- children: /*#__PURE__*/_jsx("div", {
105
- className: "pro-layout-tab-list",
106
- children: state.tabsList.map(tab => /*#__PURE__*/_jsx(TabItemComponent, {
107
- tab: tab,
108
- active: tab.id === state.activeKey,
109
- onClick: () => switchTab(tab.id),
110
- onClose: () => removeTab(tab.id),
111
- onCloseOthers: () => closeOtherTabs(tab.id),
112
- onCloseRight: () => closeRightTabs(tab.id),
113
- onCloseAll: closeAllTabs,
114
- tabsList: state.tabsList,
115
- menuItems: config === null || config === void 0 ? void 0 : config.menuItems,
116
- tabMenuClick: config === null || config === void 0 ? void 0 : config.tabMenuClick
117
- }, tab.id))
140
+ children: /*#__PURE__*/_jsx(Tabs, {
141
+ activeKey: state.activeKey || undefined,
142
+ onChange: handleTabChange,
143
+ onEdit: handleTabEdit,
144
+ type: "editable-card",
145
+ hideAdd: true,
146
+ items: tabsItems,
147
+ className: "pro-layout-tabs-antd",
148
+ classNames: {
149
+ popup: {
150
+ root: 'pro-layout-tabs-dropdown-menu'
151
+ }
152
+ }
118
153
  })
119
154
  });
120
155
  };
@@ -164,8 +199,9 @@ var TabsManager = /*#__PURE__*/forwardRef((_ref, ref) => {
164
199
 
165
200
  // 暴露方法给父组件
166
201
  useImperativeHandle(ref, () => ({
167
- handleMenuClick
168
- }), [handleMenuClick]);
202
+ handleMenuClick,
203
+ canAddTab
204
+ }), [handleMenuClick, canAddTab]);
169
205
  return /*#__PURE__*/_jsx(TabsContext.Provider, {
170
206
  value: tabsInstance,
171
207
  children: /*#__PURE__*/_jsxs("div", {
@@ -49,6 +49,8 @@ export interface UseTabsStateReturn {
49
49
  state: TabsState;
50
50
  /** 添加标签页 */
51
51
  addTab: (menuItem: MenusType, options?: AddTabOptions) => void;
52
+ /** 检查是否可以添加标签页 */
53
+ canAddTab: (menuItem: MenusType, options?: AddTabOptions) => boolean;
52
54
  /** 移除标签页 */
53
55
  removeTab: (tabId: string) => void;
54
56
  /** 切换标签页 */