@zat-design/sisyphus-react 3.12.1-beta.3 → 3.13.0

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.
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+ import type { ProStepTabType, ProStepTabResultType } from './propsType';
3
+ /**
4
+ * 步骤化Tab管理钩子,用于管理多步骤表单或流程的切换和验证
5
+ *
6
+ * @param {ProStepTabType} props 配置参数
7
+ * @returns {ProStepTabResultType} 返回步骤Tab相关方法和状态
8
+ */
9
+ export declare function useStepTab(props?: ProStepTabType): ProStepTabResultType;
10
+ /**
11
+ * 在子组件中获取父级 StepTab 实例的钩子
12
+ * @returns {ProStepTabResultType} 步骤Tab实例
13
+ */
14
+ export declare function useStepTabInstance(): ProStepTabResultType;
15
+ interface ProStepTabComponent extends React.FC<React.PropsWithChildren<ProStepTabType>> {
16
+ useStepTabInstance: typeof useStepTabInstance;
17
+ }
18
+ /**
19
+ * ProStepTab 组件
20
+ */
21
+ declare const ProStepTab: ProStepTabComponent;
22
+ export default ProStepTab;
@@ -0,0 +1,341 @@
1
+ import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
2
+ import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
3
+ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
4
+ import _regeneratorRuntime from "@babel/runtime/helpers/esm/regeneratorRuntime";
5
+ import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator";
6
+ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
7
+ var _excluded = ["children"];
8
+ import React, { useState, useCallback, useEffect, createContext, useContext } from 'react';
9
+ import { isNaN } from 'lodash';
10
+ // 存储当前的 StepTab 实例
11
+ var StepTabInstanceContext = /*#__PURE__*/createContext(null);
12
+ /**
13
+ * 使用原生 JS 获取 URL 搜索参数
14
+ * @returns 当前 URL 的搜索参数和路径
15
+ */
16
+ var useNativeLocation = function useNativeLocation() {
17
+ var _useState = useState({
18
+ search: window.location.search,
19
+ pathname: window.location.pathname
20
+ }),
21
+ _useState2 = _slicedToArray(_useState, 2),
22
+ location = _useState2[0],
23
+ setLocation = _useState2[1];
24
+ // 监听 popstate 事件,更新 location 状态
25
+ useEffect(function () {
26
+ var handleLocationChange = function handleLocationChange() {
27
+ setLocation({
28
+ search: window.location.search,
29
+ pathname: window.location.pathname
30
+ });
31
+ };
32
+ window.addEventListener('popstate', handleLocationChange);
33
+ return function () {
34
+ window.removeEventListener('popstate', handleLocationChange);
35
+ };
36
+ }, []);
37
+ return location;
38
+ };
39
+ /**
40
+ * 步骤化Tab管理钩子,用于管理多步骤表单或流程的切换和验证
41
+ *
42
+ * @param {ProStepTabType} props 配置参数
43
+ * @returns {ProStepTabResultType} 返回步骤Tab相关方法和状态
44
+ */
45
+ export function useStepTab() {
46
+ var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
47
+ var _props$routerKeep = props.routerKeep,
48
+ routerKeep = _props$routerKeep === void 0 ? false : _props$routerKeep,
49
+ _props$routerSearchKe = props.routerSearchKey,
50
+ routerSearchKey = _props$routerSearchKe === void 0 ? 'tab' : _props$routerSearchKe,
51
+ _props$validate = props.validate,
52
+ validate = _props$validate === void 0 ? true : _props$validate,
53
+ onBeforeChange = props.onBeforeChange,
54
+ onAfterChange = props.onAfterChange,
55
+ defaultActiveKey = props.defaultActiveKey,
56
+ _props$defaultStep = props.defaultStep,
57
+ defaultStep = _props$defaultStep === void 0 ? 1 : _props$defaultStep,
58
+ queueSteps = props.queueSteps,
59
+ _props$autoNext = props.autoNext,
60
+ autoNext = _props$autoNext === void 0 ? false : _props$autoNext;
61
+ // 内部状态,避免全局污染
62
+ var _useState3 = useState({}),
63
+ _useState4 = _slicedToArray(_useState3, 2),
64
+ handlesState = _useState4[0],
65
+ setHandlesState = _useState4[1];
66
+ var location = useNativeLocation();
67
+ // 获取初始激活的tab key
68
+ var getInitialActiveKey = useCallback(function () {
69
+ if (routerKeep) {
70
+ var urlSearchParams = new URLSearchParams(location.search);
71
+ var tabValue = urlSearchParams.get(routerSearchKey);
72
+ if (tabValue) {
73
+ return tabValue;
74
+ }
75
+ }
76
+ return defaultActiveKey || '1';
77
+ }, [routerKeep, routerSearchKey, location.search, defaultActiveKey]);
78
+ // 获取初始激活的步骤
79
+ var getInitialStep = useCallback(function () {
80
+ if (routerKeep) {
81
+ var urlSearchParams = new URLSearchParams(location.search);
82
+ var stepValue = urlSearchParams.get(routerSearchKey);
83
+ // 如果stepValue是数字,则返回数字
84
+ if (stepValue && !isNaN(Number(stepValue))) {
85
+ return Number(stepValue);
86
+ }
87
+ }
88
+ return defaultStep;
89
+ }, [routerKeep, routerSearchKey, location.search, defaultStep]);
90
+ var _useState5 = useState(getInitialActiveKey()),
91
+ _useState6 = _slicedToArray(_useState5, 2),
92
+ activeKey = _useState6[0],
93
+ setActiveKeyState = _useState6[1];
94
+ var _useState7 = useState(getInitialStep()),
95
+ _useState8 = _slicedToArray(_useState7, 2),
96
+ step = _useState8[0],
97
+ setStepState = _useState8[1]; // 当前已激活步骤
98
+ var _useState9 = useState(false),
99
+ _useState10 = _slicedToArray(_useState9, 2),
100
+ loading = _useState10[0],
101
+ setLoading = _useState10[1];
102
+ // 同步URL参数
103
+ useEffect(function () {
104
+ if (routerKeep && activeKey) {
105
+ // 更新URL参数
106
+ var urlSearchParams = new URLSearchParams(location.search);
107
+ urlSearchParams.set(routerSearchKey, activeKey);
108
+ // 使用原生 history API 更新 URL
109
+ var newUrl = "".concat(location.pathname, "?").concat(urlSearchParams.toString());
110
+ window.history.replaceState(null, '', newUrl);
111
+ }
112
+ }, [activeKey, routerKeep, routerSearchKey, location]);
113
+ // 创建一个包装函数,自动处理loading状态
114
+ var wrapHandleWithLoading = useCallback(function (fn) {
115
+ return /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
116
+ var result;
117
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
118
+ while (1) switch (_context.prev = _context.next) {
119
+ case 0:
120
+ setLoading(true);
121
+ _context.prev = 1;
122
+ _context.next = 4;
123
+ return fn();
124
+ case 4:
125
+ result = _context.sent;
126
+ setLoading(false);
127
+ return _context.abrupt("return", result);
128
+ case 9:
129
+ _context.prev = 9;
130
+ _context.t0 = _context["catch"](1);
131
+ setLoading(false);
132
+ return _context.abrupt("return", false);
133
+ case 13:
134
+ _context.prev = 13;
135
+ setLoading(false);
136
+ return _context.finish(13);
137
+ case 16:
138
+ case "end":
139
+ return _context.stop();
140
+ }
141
+ }, _callee, null, [[1, 9, 13, 16]]);
142
+ }));
143
+ }, []);
144
+ // 注册步骤处理函数
145
+ var registerHandle = useCallback(function (key, handler) {
146
+ // 使用wrapHandleWithLoading包装处理函数
147
+ setHandlesState(function (prev) {
148
+ return _objectSpread(_objectSpread({}, prev), {}, _defineProperty({}, key, wrapHandleWithLoading(handler)));
149
+ });
150
+ }, [wrapHandleWithLoading]);
151
+ // 获取步骤处理函数
152
+ var getHandle = useCallback(function (key) {
153
+ return handlesState[key];
154
+ }, [handlesState]);
155
+ // 处理表单验证和切换(内部使用)
156
+ var validateAndChange = useCallback(/*#__PURE__*/function () {
157
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee2(targetKey) {
158
+ var currentHandler, handleResult, beforeResult;
159
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
160
+ while (1) switch (_context2.prev = _context2.next) {
161
+ case 0:
162
+ if (!(targetKey === activeKey)) {
163
+ _context2.next = 2;
164
+ break;
165
+ }
166
+ return _context2.abrupt("return", true);
167
+ case 2:
168
+ _context2.prev = 2;
169
+ // 执行当前步骤的保存处理, 如果validate为true,则执行验证
170
+ currentHandler = handlesState[activeKey];
171
+ if (!(currentHandler && validate)) {
172
+ _context2.next = 10;
173
+ break;
174
+ }
175
+ _context2.next = 7;
176
+ return currentHandler();
177
+ case 7:
178
+ handleResult = _context2.sent;
179
+ if (handleResult) {
180
+ _context2.next = 10;
181
+ break;
182
+ }
183
+ return _context2.abrupt("return", false);
184
+ case 10:
185
+ if (!onBeforeChange) {
186
+ _context2.next = 16;
187
+ break;
188
+ }
189
+ _context2.next = 13;
190
+ return onBeforeChange(activeKey, targetKey);
191
+ case 13:
192
+ beforeResult = _context2.sent;
193
+ if (!(beforeResult === false)) {
194
+ _context2.next = 16;
195
+ break;
196
+ }
197
+ return _context2.abrupt("return", false);
198
+ case 16:
199
+ // 更新激活的key
200
+ setActiveKeyState(targetKey);
201
+ // 执行切换后回调
202
+ if (onAfterChange) {
203
+ onAfterChange(targetKey);
204
+ }
205
+ return _context2.abrupt("return", true);
206
+ case 21:
207
+ _context2.prev = 21;
208
+ _context2.t0 = _context2["catch"](2);
209
+ // 验证失败
210
+ console.error('Tab切换验证失败:', _context2.t0);
211
+ return _context2.abrupt("return", false);
212
+ case 25:
213
+ case "end":
214
+ return _context2.stop();
215
+ }
216
+ }, _callee2, null, [[2, 21]]);
217
+ }));
218
+ return function (_x) {
219
+ return _ref2.apply(this, arguments);
220
+ };
221
+ }(), [activeKey, validate, onBeforeChange, onAfterChange, handlesState]);
222
+ // 设置激活的key
223
+ var setCheckActiveKey = useCallback(/*#__PURE__*/function () {
224
+ var _ref3 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee3(targetKey, validate) {
225
+ return _regeneratorRuntime().wrap(function _callee3$(_context3) {
226
+ while (1) switch (_context3.prev = _context3.next) {
227
+ case 0:
228
+ if (!(validate === false)) {
229
+ _context3.next = 3;
230
+ break;
231
+ }
232
+ setActiveKeyState(targetKey);
233
+ return _context3.abrupt("return", true);
234
+ case 3:
235
+ return _context3.abrupt("return", validateAndChange(targetKey));
236
+ case 4:
237
+ case "end":
238
+ return _context3.stop();
239
+ }
240
+ }, _callee3);
241
+ }));
242
+ return function (_x2, _x3) {
243
+ return _ref3.apply(this, arguments);
244
+ };
245
+ }(), [validateAndChange]);
246
+ // 执行当前步骤处理函数
247
+ var saveHandle = useCallback(/*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee4() {
248
+ var handler, result, currentKeyNum, nextKey;
249
+ return _regeneratorRuntime().wrap(function _callee4$(_context4) {
250
+ while (1) switch (_context4.prev = _context4.next) {
251
+ case 0:
252
+ handler = handlesState[activeKey];
253
+ if (!handler) {
254
+ _context4.next = 14;
255
+ break;
256
+ }
257
+ _context4.next = 4;
258
+ return handler();
259
+ case 4:
260
+ result = _context4.sent;
261
+ if (!(result && autoNext)) {
262
+ _context4.next = 11;
263
+ break;
264
+ }
265
+ // 只有当activeKey能转换为数字时才执行自动跳转
266
+ currentKeyNum = Number(activeKey);
267
+ if (isNaN(currentKeyNum)) {
268
+ _context4.next = 11;
269
+ break;
270
+ }
271
+ nextKey = String(currentKeyNum + 1); // 自动跳转到下一个tab
272
+ _context4.next = 11;
273
+ return setCheckActiveKey(nextKey);
274
+ case 11:
275
+ if (!(result === false)) {
276
+ _context4.next = 13;
277
+ break;
278
+ }
279
+ return _context4.abrupt("return", Promise.reject());
280
+ case 13:
281
+ return _context4.abrupt("return", result);
282
+ case 14:
283
+ return _context4.abrupt("return", Promise.resolve(true));
284
+ case 15:
285
+ case "end":
286
+ return _context4.stop();
287
+ }
288
+ }, _callee4);
289
+ })), [activeKey, handlesState, autoNext, queueSteps, setCheckActiveKey]);
290
+ // 拦截setStep, 最大值是queueSteps
291
+ var setStep = useCallback(function (step) {
292
+ if (step > queueSteps) {
293
+ return;
294
+ }
295
+ setStepState(step);
296
+ }, [queueSteps]);
297
+ // 重置handles,用于清空或组件卸载时调用
298
+ var resetHandles = useCallback(function () {
299
+ setHandlesState({});
300
+ }, []);
301
+ var stepTabInstance = {
302
+ activeKey: activeKey,
303
+ setCheckActiveKey: setCheckActiveKey,
304
+ loading: loading,
305
+ registerHandle: registerHandle,
306
+ getHandle: getHandle,
307
+ saveHandle: saveHandle,
308
+ resetHandles: resetHandles,
309
+ handles: handlesState,
310
+ step: step,
311
+ setStep: setStep,
312
+ queueSteps: queueSteps
313
+ };
314
+ return stepTabInstance;
315
+ }
316
+ /**
317
+ * 在子组件中获取父级 StepTab 实例的钩子
318
+ * @returns {ProStepTabResultType} 步骤Tab实例
319
+ */
320
+ export function useStepTabInstance() {
321
+ var context = useContext(StepTabInstanceContext);
322
+ if (context === null) {
323
+ throw new Error('useStepTabInstance must be used inside a ProStepTab component');
324
+ }
325
+ return context;
326
+ }
327
+ /**
328
+ * ProStepTab 组件
329
+ */
330
+ var ProStepTab = function ProStepTab(_ref5) {
331
+ var children = _ref5.children,
332
+ rest = _objectWithoutProperties(_ref5, _excluded);
333
+ var stepTabInstance = useStepTab(rest);
334
+ return /*#__PURE__*/React.createElement(StepTabInstanceContext.Provider, {
335
+ value: stepTabInstance
336
+ }, children);
337
+ };
338
+ // 将 useStepTabInstance 挂载到 ProStepTab 上作为静态方法
339
+ ProStepTab.useStepTabInstance = useStepTabInstance;
340
+ // 导出默认组件
341
+ export default ProStepTab;
@@ -0,0 +1,114 @@
1
+ /**
2
+ * HandleFunction 类型定义 - 步骤处理函数
3
+ */
4
+ export type HandleFunctionType = () => Promise<boolean>;
5
+ /**
6
+ * ProStepTab钩子参数接口
7
+ */
8
+ export interface ProStepTabType {
9
+ /**
10
+ * 是否将当前tab状态保存在URL中
11
+ * @default false
12
+ */
13
+ routerKeep?: boolean;
14
+ /**
15
+ * URL参数名称
16
+ * @default 'tab'
17
+ */
18
+ routerSearchKey?: string;
19
+ /**
20
+ * 切换tab前是否需要验证
21
+ * @default false
22
+ */
23
+ validate?: boolean;
24
+ /**
25
+ * 切换tab前的回调
26
+ * @param current 当前tabKey
27
+ * @param target 目标tabKey
28
+ * @returns 是否允许切换
29
+ */
30
+ onBeforeChange?: (current: string, target: string) => Promise<boolean>;
31
+ /**
32
+ * 切换tab后的回调
33
+ * @param key 切换后的tabKey
34
+ */
35
+ onAfterChange?: (key: string) => void;
36
+ /**
37
+ * 默认选中的tab key
38
+ * @default '1'
39
+ */
40
+ defaultActiveKey?: string;
41
+ /**
42
+ * 需要按顺序完成的步骤数量
43
+ * 与defaultStep必须同时存在或同时不存在
44
+ * @default -
45
+ */
46
+ queueSteps?: number;
47
+ /**
48
+ * 当前初始激活步骤
49
+ * 与queueSteps必须同时存在或同时不存在
50
+ * @default 1
51
+ */
52
+ defaultStep?: number;
53
+ /**
54
+ * 是否自动跳转下一步
55
+ * @default false
56
+ */
57
+ autoNext?: boolean;
58
+ }
59
+ /**
60
+ * ProStepTab钩子返回值接口
61
+ */
62
+ export interface ProStepTabResultType {
63
+ /**
64
+ * 当前激活的tabKey
65
+ */
66
+ activeKey: string;
67
+ /**
68
+ * 设置激活的tabKey
69
+ * @param key 目标tabKey
70
+ * @param validate 是否需要验证
71
+ */
72
+ setCheckActiveKey: (key: string, validate?: boolean) => Promise<boolean>;
73
+ /**
74
+ * 加载状态
75
+ */
76
+ loading: boolean;
77
+ /**
78
+ * 注册步骤处理函数
79
+ * @param key 步骤Key
80
+ * @param handler 处理函数
81
+ */
82
+ registerHandle: (key: string, handler: HandleFunctionType) => void;
83
+ /**
84
+ * 获取步骤处理函数
85
+ * @param key 步骤Key
86
+ */
87
+ getHandle: (key: string) => HandleFunctionType | undefined;
88
+ /**
89
+ * 执行当前步骤处理函数
90
+ * @returns 处理结果
91
+ */
92
+ saveHandle: () => Promise<boolean>;
93
+ /**
94
+ * 所有步骤处理函数映射
95
+ */
96
+ handles: Record<string, HandleFunctionType>;
97
+ /**
98
+ * 重置所有步骤处理函数
99
+ */
100
+ resetHandles: () => void;
101
+ /**
102
+ * 最大步骤数
103
+ */
104
+ queueSteps?: number;
105
+ /**
106
+ * 当前已激活步骤,最大值为queueSteps
107
+ */
108
+ step?: number;
109
+ /**
110
+ * 设置当前顺序步骤
111
+ * @param step 顺序步骤
112
+ */
113
+ setStep?: (step: number) => void;
114
+ }
@@ -0,0 +1 @@
1
+ export {};
package/es/index.d.ts CHANGED
@@ -8,6 +8,7 @@ export { default as ProViewer } from './ProViewer';
8
8
  export { default as ProEditTable } from './ProEditTable';
9
9
  export { default as ProDrawerForm } from './ProDrawerForm';
10
10
  export { default as ProEditLabel } from './ProEditLabel';
11
+ export { default as ProStepTab } from './ProStepTab';
11
12
  export { default as ProForm } from './ProForm';
12
13
  export { ProFormProvider } from './ProForm';
13
14
  export * from './ProForm/components';
@@ -40,4 +41,5 @@ export type { ProEditTableType, ProEditTableColumnType, ProEditTableSummaryColum
40
41
  export type { ProStepType, ProStepContextType, ProStepItemType, ProStepPropsType, ProStepItemPropsType } from './ProStep/propsType';
41
42
  export type { ProDrawerFormType, ProDrawerFormPropsType } from './ProDrawerForm/propsType';
42
43
  export type { ProModalSelectType, ProModalSelectConfigType, ProModalSelectPropsType } from './ProForm/components/combination/ProModalSelect/propsType';
44
+ export type { ProStepTabType, ProStepTabResultType } from './ProStepTab/propsType';
43
45
  export * from './tokens';
package/es/index.js CHANGED
@@ -11,6 +11,7 @@ export { default as ProViewer } from './ProViewer';
11
11
  export { default as ProEditTable } from './ProEditTable';
12
12
  export { default as ProDrawerForm } from './ProDrawerForm';
13
13
  export { default as ProEditLabel } from './ProEditLabel';
14
+ export { default as ProStepTab } from './ProStepTab';
14
15
  // 表单
15
16
  export { default as ProForm } from './ProForm';
16
17
  export { ProFormProvider } from './ProForm';
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+ import type { ProStepTabType, ProStepTabResultType } from './propsType';
3
+ /**
4
+ * 步骤化Tab管理钩子,用于管理多步骤表单或流程的切换和验证
5
+ *
6
+ * @param {ProStepTabType} props 配置参数
7
+ * @returns {ProStepTabResultType} 返回步骤Tab相关方法和状态
8
+ */
9
+ export declare function useStepTab(props?: ProStepTabType): ProStepTabResultType;
10
+ /**
11
+ * 在子组件中获取父级 StepTab 实例的钩子
12
+ * @returns {ProStepTabResultType} 步骤Tab实例
13
+ */
14
+ export declare function useStepTabInstance(): ProStepTabResultType;
15
+ interface ProStepTabComponent extends React.FC<React.PropsWithChildren<ProStepTabType>> {
16
+ useStepTabInstance: typeof useStepTabInstance;
17
+ }
18
+ /**
19
+ * ProStepTab 组件
20
+ */
21
+ declare const ProStepTab: ProStepTabComponent;
22
+ export default ProStepTab;
@@ -0,0 +1,351 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
+ var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.default = void 0;
9
+ exports.useStepTab = useStepTab;
10
+ exports.useStepTabInstance = useStepTabInstance;
11
+ var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
12
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
13
+ var _objectSpread3 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
14
+ var _regeneratorRuntime2 = _interopRequireDefault(require("@babel/runtime/helpers/regeneratorRuntime"));
15
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
16
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
17
+ var _react = _interopRequireWildcard(require("react"));
18
+ var _lodash = require("lodash");
19
+ var _excluded = ["children"];
20
+ // 存储当前的 StepTab 实例
21
+ var StepTabInstanceContext = /*#__PURE__*/(0, _react.createContext)(null);
22
+ /**
23
+ * 使用原生 JS 获取 URL 搜索参数
24
+ * @returns 当前 URL 的搜索参数和路径
25
+ */
26
+ var useNativeLocation = function useNativeLocation() {
27
+ var _useState = (0, _react.useState)({
28
+ search: window.location.search,
29
+ pathname: window.location.pathname
30
+ }),
31
+ _useState2 = (0, _slicedToArray2.default)(_useState, 2),
32
+ location = _useState2[0],
33
+ setLocation = _useState2[1];
34
+ // 监听 popstate 事件,更新 location 状态
35
+ (0, _react.useEffect)(function () {
36
+ var handleLocationChange = function handleLocationChange() {
37
+ setLocation({
38
+ search: window.location.search,
39
+ pathname: window.location.pathname
40
+ });
41
+ };
42
+ window.addEventListener('popstate', handleLocationChange);
43
+ return function () {
44
+ window.removeEventListener('popstate', handleLocationChange);
45
+ };
46
+ }, []);
47
+ return location;
48
+ };
49
+ /**
50
+ * 步骤化Tab管理钩子,用于管理多步骤表单或流程的切换和验证
51
+ *
52
+ * @param {ProStepTabType} props 配置参数
53
+ * @returns {ProStepTabResultType} 返回步骤Tab相关方法和状态
54
+ */
55
+ function useStepTab() {
56
+ var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
57
+ var _props$routerKeep = props.routerKeep,
58
+ routerKeep = _props$routerKeep === void 0 ? false : _props$routerKeep,
59
+ _props$routerSearchKe = props.routerSearchKey,
60
+ routerSearchKey = _props$routerSearchKe === void 0 ? 'tab' : _props$routerSearchKe,
61
+ _props$validate = props.validate,
62
+ validate = _props$validate === void 0 ? true : _props$validate,
63
+ onBeforeChange = props.onBeforeChange,
64
+ onAfterChange = props.onAfterChange,
65
+ defaultActiveKey = props.defaultActiveKey,
66
+ _props$defaultStep = props.defaultStep,
67
+ defaultStep = _props$defaultStep === void 0 ? 1 : _props$defaultStep,
68
+ queueSteps = props.queueSteps,
69
+ _props$autoNext = props.autoNext,
70
+ autoNext = _props$autoNext === void 0 ? false : _props$autoNext;
71
+ // 内部状态,避免全局污染
72
+ var _useState3 = (0, _react.useState)({}),
73
+ _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
74
+ handlesState = _useState4[0],
75
+ setHandlesState = _useState4[1];
76
+ var location = useNativeLocation();
77
+ // 获取初始激活的tab key
78
+ var getInitialActiveKey = (0, _react.useCallback)(function () {
79
+ if (routerKeep) {
80
+ var urlSearchParams = new URLSearchParams(location.search);
81
+ var tabValue = urlSearchParams.get(routerSearchKey);
82
+ if (tabValue) {
83
+ return tabValue;
84
+ }
85
+ }
86
+ return defaultActiveKey || '1';
87
+ }, [routerKeep, routerSearchKey, location.search, defaultActiveKey]);
88
+ // 获取初始激活的步骤
89
+ var getInitialStep = (0, _react.useCallback)(function () {
90
+ if (routerKeep) {
91
+ var urlSearchParams = new URLSearchParams(location.search);
92
+ var stepValue = urlSearchParams.get(routerSearchKey);
93
+ // 如果stepValue是数字,则返回数字
94
+ if (stepValue && !(0, _lodash.isNaN)(Number(stepValue))) {
95
+ return Number(stepValue);
96
+ }
97
+ }
98
+ return defaultStep;
99
+ }, [routerKeep, routerSearchKey, location.search, defaultStep]);
100
+ var _useState5 = (0, _react.useState)(getInitialActiveKey()),
101
+ _useState6 = (0, _slicedToArray2.default)(_useState5, 2),
102
+ activeKey = _useState6[0],
103
+ setActiveKeyState = _useState6[1];
104
+ var _useState7 = (0, _react.useState)(getInitialStep()),
105
+ _useState8 = (0, _slicedToArray2.default)(_useState7, 2),
106
+ step = _useState8[0],
107
+ setStepState = _useState8[1]; // 当前已激活步骤
108
+ var _useState9 = (0, _react.useState)(false),
109
+ _useState10 = (0, _slicedToArray2.default)(_useState9, 2),
110
+ loading = _useState10[0],
111
+ setLoading = _useState10[1];
112
+ // 同步URL参数
113
+ (0, _react.useEffect)(function () {
114
+ if (routerKeep && activeKey) {
115
+ // 更新URL参数
116
+ var urlSearchParams = new URLSearchParams(location.search);
117
+ urlSearchParams.set(routerSearchKey, activeKey);
118
+ // 使用原生 history API 更新 URL
119
+ var newUrl = "".concat(location.pathname, "?").concat(urlSearchParams.toString());
120
+ window.history.replaceState(null, '', newUrl);
121
+ }
122
+ }, [activeKey, routerKeep, routerSearchKey, location]);
123
+ // 创建一个包装函数,自动处理loading状态
124
+ var wrapHandleWithLoading = (0, _react.useCallback)(function (fn) {
125
+ return /*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/(0, _regeneratorRuntime2.default)().mark(function _callee() {
126
+ var result;
127
+ return (0, _regeneratorRuntime2.default)().wrap(function _callee$(_context) {
128
+ while (1) switch (_context.prev = _context.next) {
129
+ case 0:
130
+ setLoading(true);
131
+ _context.prev = 1;
132
+ _context.next = 4;
133
+ return fn();
134
+ case 4:
135
+ result = _context.sent;
136
+ setLoading(false);
137
+ return _context.abrupt("return", result);
138
+ case 9:
139
+ _context.prev = 9;
140
+ _context.t0 = _context["catch"](1);
141
+ setLoading(false);
142
+ return _context.abrupt("return", false);
143
+ case 13:
144
+ _context.prev = 13;
145
+ setLoading(false);
146
+ return _context.finish(13);
147
+ case 16:
148
+ case "end":
149
+ return _context.stop();
150
+ }
151
+ }, _callee, null, [[1, 9, 13, 16]]);
152
+ }));
153
+ }, []);
154
+ // 注册步骤处理函数
155
+ var registerHandle = (0, _react.useCallback)(function (key, handler) {
156
+ // 使用wrapHandleWithLoading包装处理函数
157
+ setHandlesState(function (prev) {
158
+ return (0, _objectSpread3.default)((0, _objectSpread3.default)({}, prev), {}, (0, _defineProperty2.default)({}, key, wrapHandleWithLoading(handler)));
159
+ });
160
+ }, [wrapHandleWithLoading]);
161
+ // 获取步骤处理函数
162
+ var getHandle = (0, _react.useCallback)(function (key) {
163
+ return handlesState[key];
164
+ }, [handlesState]);
165
+ // 处理表单验证和切换(内部使用)
166
+ var validateAndChange = (0, _react.useCallback)(/*#__PURE__*/function () {
167
+ var _ref2 = (0, _asyncToGenerator2.default)(/*#__PURE__*/(0, _regeneratorRuntime2.default)().mark(function _callee2(targetKey) {
168
+ var currentHandler, handleResult, beforeResult;
169
+ return (0, _regeneratorRuntime2.default)().wrap(function _callee2$(_context2) {
170
+ while (1) switch (_context2.prev = _context2.next) {
171
+ case 0:
172
+ if (!(targetKey === activeKey)) {
173
+ _context2.next = 2;
174
+ break;
175
+ }
176
+ return _context2.abrupt("return", true);
177
+ case 2:
178
+ _context2.prev = 2;
179
+ // 执行当前步骤的保存处理, 如果validate为true,则执行验证
180
+ currentHandler = handlesState[activeKey];
181
+ if (!(currentHandler && validate)) {
182
+ _context2.next = 10;
183
+ break;
184
+ }
185
+ _context2.next = 7;
186
+ return currentHandler();
187
+ case 7:
188
+ handleResult = _context2.sent;
189
+ if (handleResult) {
190
+ _context2.next = 10;
191
+ break;
192
+ }
193
+ return _context2.abrupt("return", false);
194
+ case 10:
195
+ if (!onBeforeChange) {
196
+ _context2.next = 16;
197
+ break;
198
+ }
199
+ _context2.next = 13;
200
+ return onBeforeChange(activeKey, targetKey);
201
+ case 13:
202
+ beforeResult = _context2.sent;
203
+ if (!(beforeResult === false)) {
204
+ _context2.next = 16;
205
+ break;
206
+ }
207
+ return _context2.abrupt("return", false);
208
+ case 16:
209
+ // 更新激活的key
210
+ setActiveKeyState(targetKey);
211
+ // 执行切换后回调
212
+ if (onAfterChange) {
213
+ onAfterChange(targetKey);
214
+ }
215
+ return _context2.abrupt("return", true);
216
+ case 21:
217
+ _context2.prev = 21;
218
+ _context2.t0 = _context2["catch"](2);
219
+ // 验证失败
220
+ console.error('Tab切换验证失败:', _context2.t0);
221
+ return _context2.abrupt("return", false);
222
+ case 25:
223
+ case "end":
224
+ return _context2.stop();
225
+ }
226
+ }, _callee2, null, [[2, 21]]);
227
+ }));
228
+ return function (_x) {
229
+ return _ref2.apply(this, arguments);
230
+ };
231
+ }(), [activeKey, validate, onBeforeChange, onAfterChange, handlesState]);
232
+ // 设置激活的key
233
+ var setCheckActiveKey = (0, _react.useCallback)(/*#__PURE__*/function () {
234
+ var _ref3 = (0, _asyncToGenerator2.default)(/*#__PURE__*/(0, _regeneratorRuntime2.default)().mark(function _callee3(targetKey, validate) {
235
+ return (0, _regeneratorRuntime2.default)().wrap(function _callee3$(_context3) {
236
+ while (1) switch (_context3.prev = _context3.next) {
237
+ case 0:
238
+ if (!(validate === false)) {
239
+ _context3.next = 3;
240
+ break;
241
+ }
242
+ setActiveKeyState(targetKey);
243
+ return _context3.abrupt("return", true);
244
+ case 3:
245
+ return _context3.abrupt("return", validateAndChange(targetKey));
246
+ case 4:
247
+ case "end":
248
+ return _context3.stop();
249
+ }
250
+ }, _callee3);
251
+ }));
252
+ return function (_x2, _x3) {
253
+ return _ref3.apply(this, arguments);
254
+ };
255
+ }(), [validateAndChange]);
256
+ // 执行当前步骤处理函数
257
+ var saveHandle = (0, _react.useCallback)(/*#__PURE__*/(0, _asyncToGenerator2.default)(/*#__PURE__*/(0, _regeneratorRuntime2.default)().mark(function _callee4() {
258
+ var handler, result, currentKeyNum, nextKey;
259
+ return (0, _regeneratorRuntime2.default)().wrap(function _callee4$(_context4) {
260
+ while (1) switch (_context4.prev = _context4.next) {
261
+ case 0:
262
+ handler = handlesState[activeKey];
263
+ if (!handler) {
264
+ _context4.next = 14;
265
+ break;
266
+ }
267
+ _context4.next = 4;
268
+ return handler();
269
+ case 4:
270
+ result = _context4.sent;
271
+ if (!(result && autoNext)) {
272
+ _context4.next = 11;
273
+ break;
274
+ }
275
+ // 只有当activeKey能转换为数字时才执行自动跳转
276
+ currentKeyNum = Number(activeKey);
277
+ if ((0, _lodash.isNaN)(currentKeyNum)) {
278
+ _context4.next = 11;
279
+ break;
280
+ }
281
+ nextKey = String(currentKeyNum + 1); // 自动跳转到下一个tab
282
+ _context4.next = 11;
283
+ return setCheckActiveKey(nextKey);
284
+ case 11:
285
+ if (!(result === false)) {
286
+ _context4.next = 13;
287
+ break;
288
+ }
289
+ return _context4.abrupt("return", Promise.reject());
290
+ case 13:
291
+ return _context4.abrupt("return", result);
292
+ case 14:
293
+ return _context4.abrupt("return", Promise.resolve(true));
294
+ case 15:
295
+ case "end":
296
+ return _context4.stop();
297
+ }
298
+ }, _callee4);
299
+ })), [activeKey, handlesState, autoNext, queueSteps, setCheckActiveKey]);
300
+ // 拦截setStep, 最大值是queueSteps
301
+ var setStep = (0, _react.useCallback)(function (step) {
302
+ if (step > queueSteps) {
303
+ return;
304
+ }
305
+ setStepState(step);
306
+ }, [queueSteps]);
307
+ // 重置handles,用于清空或组件卸载时调用
308
+ var resetHandles = (0, _react.useCallback)(function () {
309
+ setHandlesState({});
310
+ }, []);
311
+ var stepTabInstance = {
312
+ activeKey: activeKey,
313
+ setCheckActiveKey: setCheckActiveKey,
314
+ loading: loading,
315
+ registerHandle: registerHandle,
316
+ getHandle: getHandle,
317
+ saveHandle: saveHandle,
318
+ resetHandles: resetHandles,
319
+ handles: handlesState,
320
+ step: step,
321
+ setStep: setStep,
322
+ queueSteps: queueSteps
323
+ };
324
+ return stepTabInstance;
325
+ }
326
+ /**
327
+ * 在子组件中获取父级 StepTab 实例的钩子
328
+ * @returns {ProStepTabResultType} 步骤Tab实例
329
+ */
330
+ function useStepTabInstance() {
331
+ var context = (0, _react.useContext)(StepTabInstanceContext);
332
+ if (context === null) {
333
+ throw new Error('useStepTabInstance must be used inside a ProStepTab component');
334
+ }
335
+ return context;
336
+ }
337
+ /**
338
+ * ProStepTab 组件
339
+ */
340
+ var ProStepTab = function ProStepTab(_ref5) {
341
+ var children = _ref5.children,
342
+ rest = (0, _objectWithoutProperties2.default)(_ref5, _excluded);
343
+ var stepTabInstance = useStepTab(rest);
344
+ return /*#__PURE__*/_react.default.createElement(StepTabInstanceContext.Provider, {
345
+ value: stepTabInstance
346
+ }, children);
347
+ };
348
+ // 将 useStepTabInstance 挂载到 ProStepTab 上作为静态方法
349
+ ProStepTab.useStepTabInstance = useStepTabInstance;
350
+ // 导出默认组件
351
+ var _default = exports.default = ProStepTab;
@@ -0,0 +1,114 @@
1
+ /**
2
+ * HandleFunction 类型定义 - 步骤处理函数
3
+ */
4
+ export type HandleFunctionType = () => Promise<boolean>;
5
+ /**
6
+ * ProStepTab钩子参数接口
7
+ */
8
+ export interface ProStepTabType {
9
+ /**
10
+ * 是否将当前tab状态保存在URL中
11
+ * @default false
12
+ */
13
+ routerKeep?: boolean;
14
+ /**
15
+ * URL参数名称
16
+ * @default 'tab'
17
+ */
18
+ routerSearchKey?: string;
19
+ /**
20
+ * 切换tab前是否需要验证
21
+ * @default false
22
+ */
23
+ validate?: boolean;
24
+ /**
25
+ * 切换tab前的回调
26
+ * @param current 当前tabKey
27
+ * @param target 目标tabKey
28
+ * @returns 是否允许切换
29
+ */
30
+ onBeforeChange?: (current: string, target: string) => Promise<boolean>;
31
+ /**
32
+ * 切换tab后的回调
33
+ * @param key 切换后的tabKey
34
+ */
35
+ onAfterChange?: (key: string) => void;
36
+ /**
37
+ * 默认选中的tab key
38
+ * @default '1'
39
+ */
40
+ defaultActiveKey?: string;
41
+ /**
42
+ * 需要按顺序完成的步骤数量
43
+ * 与defaultStep必须同时存在或同时不存在
44
+ * @default -
45
+ */
46
+ queueSteps?: number;
47
+ /**
48
+ * 当前初始激活步骤
49
+ * 与queueSteps必须同时存在或同时不存在
50
+ * @default 1
51
+ */
52
+ defaultStep?: number;
53
+ /**
54
+ * 是否自动跳转下一步
55
+ * @default false
56
+ */
57
+ autoNext?: boolean;
58
+ }
59
+ /**
60
+ * ProStepTab钩子返回值接口
61
+ */
62
+ export interface ProStepTabResultType {
63
+ /**
64
+ * 当前激活的tabKey
65
+ */
66
+ activeKey: string;
67
+ /**
68
+ * 设置激活的tabKey
69
+ * @param key 目标tabKey
70
+ * @param validate 是否需要验证
71
+ */
72
+ setCheckActiveKey: (key: string, validate?: boolean) => Promise<boolean>;
73
+ /**
74
+ * 加载状态
75
+ */
76
+ loading: boolean;
77
+ /**
78
+ * 注册步骤处理函数
79
+ * @param key 步骤Key
80
+ * @param handler 处理函数
81
+ */
82
+ registerHandle: (key: string, handler: HandleFunctionType) => void;
83
+ /**
84
+ * 获取步骤处理函数
85
+ * @param key 步骤Key
86
+ */
87
+ getHandle: (key: string) => HandleFunctionType | undefined;
88
+ /**
89
+ * 执行当前步骤处理函数
90
+ * @returns 处理结果
91
+ */
92
+ saveHandle: () => Promise<boolean>;
93
+ /**
94
+ * 所有步骤处理函数映射
95
+ */
96
+ handles: Record<string, HandleFunctionType>;
97
+ /**
98
+ * 重置所有步骤处理函数
99
+ */
100
+ resetHandles: () => void;
101
+ /**
102
+ * 最大步骤数
103
+ */
104
+ queueSteps?: number;
105
+ /**
106
+ * 当前已激活步骤,最大值为queueSteps
107
+ */
108
+ step?: number;
109
+ /**
110
+ * 设置当前顺序步骤
111
+ * @param step 顺序步骤
112
+ */
113
+ setStep?: (step: number) => void;
114
+ }
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
package/lib/index.d.ts CHANGED
@@ -8,6 +8,7 @@ export { default as ProViewer } from './ProViewer';
8
8
  export { default as ProEditTable } from './ProEditTable';
9
9
  export { default as ProDrawerForm } from './ProDrawerForm';
10
10
  export { default as ProEditLabel } from './ProEditLabel';
11
+ export { default as ProStepTab } from './ProStepTab';
11
12
  export { default as ProForm } from './ProForm';
12
13
  export { ProFormProvider } from './ProForm';
13
14
  export * from './ProForm/components';
@@ -40,4 +41,5 @@ export type { ProEditTableType, ProEditTableColumnType, ProEditTableSummaryColum
40
41
  export type { ProStepType, ProStepContextType, ProStepItemType, ProStepPropsType, ProStepItemPropsType } from './ProStep/propsType';
41
42
  export type { ProDrawerFormType, ProDrawerFormPropsType } from './ProDrawerForm/propsType';
42
43
  export type { ProModalSelectType, ProModalSelectConfigType, ProModalSelectPropsType } from './ProForm/components/combination/ProModalSelect/propsType';
44
+ export type { ProStepTabType, ProStepTabResultType } from './ProStepTab/propsType';
43
45
  export * from './tokens';
package/lib/index.js CHANGED
@@ -15,6 +15,7 @@ var _exportNames = {
15
15
  ProEditTable: true,
16
16
  ProDrawerForm: true,
17
17
  ProEditLabel: true,
18
+ ProStepTab: true,
18
19
  ProForm: true,
19
20
  ProFormProvider: true,
20
21
  ProSelect: true,
@@ -133,6 +134,12 @@ Object.defineProperty(exports, "ProStep", {
133
134
  return _ProStep.default;
134
135
  }
135
136
  });
137
+ Object.defineProperty(exports, "ProStepTab", {
138
+ enumerable: true,
139
+ get: function get() {
140
+ return _ProStepTab.default;
141
+ }
142
+ });
136
143
  Object.defineProperty(exports, "ProTable", {
137
144
  enumerable: true,
138
145
  get: function get() {
@@ -184,6 +191,7 @@ var _ProViewer = _interopRequireDefault(require("./ProViewer"));
184
191
  var _ProEditTable = _interopRequireDefault(require("./ProEditTable"));
185
192
  var _ProDrawerForm = _interopRequireDefault(require("./ProDrawerForm"));
186
193
  var _ProEditLabel = _interopRequireDefault(require("./ProEditLabel"));
194
+ var _ProStepTab = _interopRequireDefault(require("./ProStepTab"));
187
195
  var _ProForm = _interopRequireWildcard(require("./ProForm"));
188
196
  var _components = require("./ProForm/components");
189
197
  Object.keys(_components).forEach(function (key) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zat-design/sisyphus-react",
3
- "version": "3.12.1-beta.3",
3
+ "version": "3.13.0",
4
4
  "license": "MIT",
5
5
  "main": "lib/index.js",
6
6
  "module": "es/index.js",