@trackunit/react-form-wizard 0.0.26 → 0.0.27
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.
package/index.cjs.js
CHANGED
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var jsxRuntime = require('react/jsx-runtime');
|
|
6
6
|
var i18nLibraryTranslation = require('@trackunit/i18n-library-translation');
|
|
7
|
+
var sharedUtils = require('@trackunit/shared-utils');
|
|
7
8
|
var react = require('react');
|
|
8
9
|
var reactRouterDom = require('react-router-dom');
|
|
9
10
|
var cssClassVarianceUtilities = require('@trackunit/css-class-variance-utilities');
|
|
@@ -12,7 +13,9 @@ var zod = require('@hookform/resolvers/zod');
|
|
|
12
13
|
var reactHookForm = require('react-hook-form');
|
|
13
14
|
|
|
14
15
|
var defaultTranslations = {
|
|
15
|
-
|
|
16
|
+
"wizard.defaults.back": "Back",
|
|
17
|
+
"wizard.defaults.cancel": "Cancel",
|
|
18
|
+
"wizard.defaults.next": "Next"
|
|
16
19
|
};
|
|
17
20
|
|
|
18
21
|
/** The translation namespace for this library */
|
|
@@ -46,6 +49,10 @@ const translations = {
|
|
|
46
49
|
th: () => Promise.resolve().then(function () { return require('./translation.cjs17.js'); }),
|
|
47
50
|
},
|
|
48
51
|
};
|
|
52
|
+
/**
|
|
53
|
+
* Local useTranslation for this specific library
|
|
54
|
+
*/
|
|
55
|
+
const useTranslation = () => i18nLibraryTranslation.useNamespaceTranslation(namespace);
|
|
49
56
|
/**
|
|
50
57
|
* Registers the translations for this library
|
|
51
58
|
*/
|
|
@@ -53,43 +60,6 @@ const setupLibraryTranslations = () => {
|
|
|
53
60
|
i18nLibraryTranslation.registerTranslations(translations);
|
|
54
61
|
};
|
|
55
62
|
|
|
56
|
-
/******************************************************************************
|
|
57
|
-
Copyright (c) Microsoft Corporation.
|
|
58
|
-
|
|
59
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
|
60
|
-
purpose with or without fee is hereby granted.
|
|
61
|
-
|
|
62
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
63
|
-
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
64
|
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
65
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
66
|
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
67
|
-
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
68
|
-
PERFORMANCE OF THIS SOFTWARE.
|
|
69
|
-
***************************************************************************** */
|
|
70
|
-
|
|
71
|
-
function __rest(s, e) {
|
|
72
|
-
var t = {};
|
|
73
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
74
|
-
t[p] = s[p];
|
|
75
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
76
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
77
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
78
|
-
t[p[i]] = s[p[i]];
|
|
79
|
-
}
|
|
80
|
-
return t;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function __awaiter(thisArg, _arguments, P, generator) {
|
|
84
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
85
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
86
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
87
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
88
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
89
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
|
|
93
63
|
const cvaFillSection = cssClassVarianceUtilities.cvaMerge(["flex-grow", "p-0"]);
|
|
94
64
|
const cvaSidebar = cssClassVarianceUtilities.cvaMerge([
|
|
95
65
|
"flex",
|
|
@@ -167,6 +137,31 @@ const FormWizardSidebarStep = ({ stepNumber, state, title, subTitle, path, dataT
|
|
|
167
137
|
return (jsxRuntime.jsx(reactRouterDom.NavLink, { className: cvaFormWizardSidebarStep({ state }), "data-testid": dataTestId !== null && dataTestId !== void 0 ? dataTestId : `form-wizard-sidebar-step-${path}`, onClick: () => onBeforeNavigate(), to: path, children: jsxRuntime.jsxs("div", { className: cvaSectionHeaderContainer(), children: [jsxRuntime.jsx("div", { children: stateIcon !== null && stateIcon !== void 0 ? stateIcon : jsxRuntime.jsx("span", { className: cvaStepNumber({ state }), children: stepNumber }) }), jsxRuntime.jsxs("div", { className: cvaTitleAndDescription(), children: [jsxRuntime.jsx("h1", { className: cvaHeader(), children: title }), subTitle ? jsxRuntime.jsx("p", { className: cvaSubtitle(), children: subTitle }) : null] })] }) }));
|
|
168
138
|
};
|
|
169
139
|
|
|
140
|
+
/******************************************************************************
|
|
141
|
+
Copyright (c) Microsoft Corporation.
|
|
142
|
+
|
|
143
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
144
|
+
purpose with or without fee is hereby granted.
|
|
145
|
+
|
|
146
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
147
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
148
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
149
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
150
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
151
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
152
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
153
|
+
***************************************************************************** */
|
|
154
|
+
|
|
155
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
156
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
157
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
158
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
159
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
160
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
161
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
|
|
170
165
|
const cvaFooterContainer = cssClassVarianceUtilities.cvaMerge([
|
|
171
166
|
"flex-grow-0",
|
|
172
167
|
"flex",
|
|
@@ -184,7 +179,8 @@ const cvaNavigationContainer = cssClassVarianceUtilities.cvaMerge(["flex", "gap-
|
|
|
184
179
|
* In most cases you should not be using this component directly, but rather use the FormWizard component.
|
|
185
180
|
*/
|
|
186
181
|
const FormWizardFooter = ({ onBack, onCancel, isValid, primaryActionLabel = "Next" }) => {
|
|
187
|
-
|
|
182
|
+
const [t] = useTranslation();
|
|
183
|
+
return (jsxRuntime.jsxs("div", { className: cvaFooterContainer(), children: [jsxRuntime.jsx(reactComponents.Button, { dataTestId: "wizard-cancel", onClick: onCancel, variant: "ghost-neutral", children: t("wizard.defaults.cancel") }), jsxRuntime.jsxs("div", { className: cvaNavigationContainer(), children: [onBack ? (jsxRuntime.jsx(reactComponents.Button, { dataTestId: "wizard-back", onClick: onBack, variant: "secondary", children: t("wizard.defaults.back") })) : null, jsxRuntime.jsx(reactComponents.Button, { dataTestId: "wizard-next", disabled: !isValid, type: "submit", children: primaryActionLabel ? primaryActionLabel : t("wizard.defaults.next") })] })] }));
|
|
188
184
|
};
|
|
189
185
|
|
|
190
186
|
const cvaFormWizardHeader = cssClassVarianceUtilities.cvaMerge([
|
|
@@ -238,7 +234,7 @@ const FormWizardStepWrapper = ({ stepKey, onCancel, description, title, componen
|
|
|
238
234
|
const setSubmitHandler = react.useCallback(callback => {
|
|
239
235
|
setSubmitHandlerInternal(() => callback);
|
|
240
236
|
}, [setSubmitHandlerInternal]);
|
|
241
|
-
const isEmptyStep =
|
|
237
|
+
const isEmptyStep = sharedUtils.objectKeys(form.getValues()).length === 0;
|
|
242
238
|
const emptyStepSubmitHandler = react.useCallback((e) => {
|
|
243
239
|
e === null || e === void 0 ? void 0 : e.preventDefault();
|
|
244
240
|
submitHandlerInternal === null || submitHandlerInternal === void 0 ? void 0 : submitHandlerInternal(fullFormState);
|
|
@@ -296,14 +292,13 @@ const FormWizard = ({ lastStepPrimaryActionLabel, steps, fullFormSchema, onCance
|
|
|
296
292
|
const [stepStates, setStepStates] = react.useState({});
|
|
297
293
|
const [stepForms, setStepForms] = react.useState({});
|
|
298
294
|
const [fullFormState, setFullFormState] = react.useState({});
|
|
299
|
-
const currentVisibleStepKey = (_a =
|
|
300
|
-
const currentVisibleStepIndex =
|
|
301
|
-
return (jsxRuntime.jsx("div", { className: cvaFormWizardContainer({ className }), "data-testid": dataTestId, children: jsxRuntime.jsxs("div", { className: cvaFormWizardLayout(), children: [jsxRuntime.jsx(FormWizardSidebar, { children:
|
|
295
|
+
const currentVisibleStepKey = (_a = sharedUtils.objectEntries(steps).find(([, { path }]) => location.pathname === basePath + path)) === null || _a === void 0 ? void 0 : _a[0];
|
|
296
|
+
const currentVisibleStepIndex = sharedUtils.objectKeys(steps).findIndex(key => key === currentVisibleStepKey);
|
|
297
|
+
return (jsxRuntime.jsx("div", { className: cvaFormWizardContainer({ className }), "data-testid": dataTestId, children: jsxRuntime.jsxs("div", { className: cvaFormWizardLayout(), children: [jsxRuntime.jsx(FormWizardSidebar, { children: sharedUtils.objectEntries(steps).map(([key, { path, title, sidebarDescription }], index) => {
|
|
302
298
|
const isPastStep = index < currentVisibleStepIndex;
|
|
303
299
|
const isFutureStep = index > currentVisibleStepIndex;
|
|
304
300
|
const isCurrentStep = key === currentVisibleStepKey;
|
|
305
|
-
|
|
306
|
-
const previousStepKey = Object.keys(steps)[index - 1];
|
|
301
|
+
const previousStepKey = sharedUtils.objectKeys(steps)[index - 1];
|
|
307
302
|
const stepState = () => {
|
|
308
303
|
if (isCurrentStep) {
|
|
309
304
|
return "active";
|
|
@@ -312,7 +307,7 @@ const FormWizard = ({ lastStepPrimaryActionLabel, steps, fullFormSchema, onCance
|
|
|
312
307
|
return stepStates[key] === "valid" ? "done" : "invalid";
|
|
313
308
|
}
|
|
314
309
|
if (isFutureStep) {
|
|
315
|
-
return
|
|
310
|
+
return sharedUtils.objectKeys(steps)
|
|
316
311
|
.filter((_, stepIndex) => stepIndex < index)
|
|
317
312
|
.every((pastStepKey) => stepStates[pastStepKey] === "valid")
|
|
318
313
|
? "ready"
|
|
@@ -333,11 +328,10 @@ const FormWizard = ({ lastStepPrimaryActionLabel, steps, fullFormSchema, onCance
|
|
|
333
328
|
},
|
|
334
329
|
path: basePath + path,
|
|
335
330
|
subTitle: sidebarDescription }));
|
|
336
|
-
}) }), jsxRuntime.jsx("div", { className: cvaStepContainer(), children: jsxRuntime.jsx(reactRouterDom.Routes, { children:
|
|
337
|
-
var _b, _c, _d
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
stepKey,
|
|
331
|
+
}) }), jsxRuntime.jsx("div", { className: cvaStepContainer(), children: jsxRuntime.jsx(reactRouterDom.Routes, { children: sharedUtils.objectEntries(steps).map(([stepKey, props], index) => {
|
|
332
|
+
var _a, _b, _c, _d;
|
|
333
|
+
return (jsxRuntime.jsx(reactRouterDom.Route, { index: false, path: props.path, key: stepKey.toString(), element: jsxRuntime.jsx(FormWizardStepWrapper, Object.assign({}, props, { basePath,
|
|
334
|
+
stepKey: stepKey.toString(),
|
|
341
335
|
stepForms,
|
|
342
336
|
setStepForms,
|
|
343
337
|
onCancel,
|
|
@@ -346,8 +340,8 @@ const FormWizard = ({ lastStepPrimaryActionLabel, steps, fullFormSchema, onCance
|
|
|
346
340
|
setStepStates,
|
|
347
341
|
fullFormSchema,
|
|
348
342
|
lastStepPrimaryActionLabel,
|
|
349
|
-
nextStepPath: (
|
|
350
|
-
previousStepPath: (
|
|
343
|
+
nextStepPath: (_b = (_a = sharedUtils.objectValues(steps)[index + 1]) === null || _a === void 0 ? void 0 : _a.path) !== null && _b !== void 0 ? _b : null,
|
|
344
|
+
previousStepPath: (_d = (_c = sharedUtils.objectValues(steps)[index - 1]) === null || _c === void 0 ? void 0 : _c.path) !== null && _d !== void 0 ? _d : null }), stepKey.toString()) }));
|
|
351
345
|
}) }) })] }) }));
|
|
352
346
|
};
|
|
353
347
|
|
|
@@ -358,7 +352,7 @@ const useFormWizard = (props) => {
|
|
|
358
352
|
return react.useMemo(() => (Object.assign(Object.assign({}, props), {
|
|
359
353
|
// Object.fromEntries is not super type safe... This is a workaround...
|
|
360
354
|
// eslint-disable-next-line local-rules/no-typescript-assertion
|
|
361
|
-
steps:
|
|
355
|
+
steps: sharedUtils.objectFromEntries(Object.entries(props.steps).map(([key, step]) => [
|
|
362
356
|
key,
|
|
363
357
|
Object.assign(Object.assign({}, step), { formSchema: props.fullFormSchema.shape[key] }),
|
|
364
358
|
])) })), [props]);
|
package/index.esm.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { registerTranslations } from '@trackunit/i18n-library-translation';
|
|
2
|
+
import { registerTranslations, useNamespaceTranslation } from '@trackunit/i18n-library-translation';
|
|
3
|
+
import { objectKeys, objectEntries, objectValues, objectFromEntries } from '@trackunit/shared-utils';
|
|
3
4
|
import { useRef, useState, useEffect, useCallback, useMemo } from 'react';
|
|
4
5
|
import { NavLink, useNavigate, useLocation, Routes, Route } from 'react-router-dom';
|
|
5
6
|
import { cvaMerge } from '@trackunit/css-class-variance-utilities';
|
|
@@ -8,7 +9,9 @@ import { zodResolver } from '@hookform/resolvers/zod';
|
|
|
8
9
|
import { useForm } from 'react-hook-form';
|
|
9
10
|
|
|
10
11
|
var defaultTranslations = {
|
|
11
|
-
|
|
12
|
+
"wizard.defaults.back": "Back",
|
|
13
|
+
"wizard.defaults.cancel": "Cancel",
|
|
14
|
+
"wizard.defaults.next": "Next"
|
|
12
15
|
};
|
|
13
16
|
|
|
14
17
|
/** The translation namespace for this library */
|
|
@@ -42,6 +45,10 @@ const translations = {
|
|
|
42
45
|
th: () => import('./translation.esm17.js'),
|
|
43
46
|
},
|
|
44
47
|
};
|
|
48
|
+
/**
|
|
49
|
+
* Local useTranslation for this specific library
|
|
50
|
+
*/
|
|
51
|
+
const useTranslation = () => useNamespaceTranslation(namespace);
|
|
45
52
|
/**
|
|
46
53
|
* Registers the translations for this library
|
|
47
54
|
*/
|
|
@@ -49,43 +56,6 @@ const setupLibraryTranslations = () => {
|
|
|
49
56
|
registerTranslations(translations);
|
|
50
57
|
};
|
|
51
58
|
|
|
52
|
-
/******************************************************************************
|
|
53
|
-
Copyright (c) Microsoft Corporation.
|
|
54
|
-
|
|
55
|
-
Permission to use, copy, modify, and/or distribute this software for any
|
|
56
|
-
purpose with or without fee is hereby granted.
|
|
57
|
-
|
|
58
|
-
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
59
|
-
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
60
|
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
61
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
62
|
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
63
|
-
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
64
|
-
PERFORMANCE OF THIS SOFTWARE.
|
|
65
|
-
***************************************************************************** */
|
|
66
|
-
|
|
67
|
-
function __rest(s, e) {
|
|
68
|
-
var t = {};
|
|
69
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
70
|
-
t[p] = s[p];
|
|
71
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
72
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
73
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
74
|
-
t[p[i]] = s[p[i]];
|
|
75
|
-
}
|
|
76
|
-
return t;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function __awaiter(thisArg, _arguments, P, generator) {
|
|
80
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
81
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
82
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
83
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
84
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
85
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
|
|
89
59
|
const cvaFillSection = cvaMerge(["flex-grow", "p-0"]);
|
|
90
60
|
const cvaSidebar = cvaMerge([
|
|
91
61
|
"flex",
|
|
@@ -163,6 +133,31 @@ const FormWizardSidebarStep = ({ stepNumber, state, title, subTitle, path, dataT
|
|
|
163
133
|
return (jsx(NavLink, { className: cvaFormWizardSidebarStep({ state }), "data-testid": dataTestId !== null && dataTestId !== void 0 ? dataTestId : `form-wizard-sidebar-step-${path}`, onClick: () => onBeforeNavigate(), to: path, children: jsxs("div", { className: cvaSectionHeaderContainer(), children: [jsx("div", { children: stateIcon !== null && stateIcon !== void 0 ? stateIcon : jsx("span", { className: cvaStepNumber({ state }), children: stepNumber }) }), jsxs("div", { className: cvaTitleAndDescription(), children: [jsx("h1", { className: cvaHeader(), children: title }), subTitle ? jsx("p", { className: cvaSubtitle(), children: subTitle }) : null] })] }) }));
|
|
164
134
|
};
|
|
165
135
|
|
|
136
|
+
/******************************************************************************
|
|
137
|
+
Copyright (c) Microsoft Corporation.
|
|
138
|
+
|
|
139
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
140
|
+
purpose with or without fee is hereby granted.
|
|
141
|
+
|
|
142
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
143
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
144
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
145
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
146
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
147
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
148
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
149
|
+
***************************************************************************** */
|
|
150
|
+
|
|
151
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
152
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
153
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
154
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
155
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
156
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
157
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
|
|
166
161
|
const cvaFooterContainer = cvaMerge([
|
|
167
162
|
"flex-grow-0",
|
|
168
163
|
"flex",
|
|
@@ -180,7 +175,8 @@ const cvaNavigationContainer = cvaMerge(["flex", "gap-responsive-space"]);
|
|
|
180
175
|
* In most cases you should not be using this component directly, but rather use the FormWizard component.
|
|
181
176
|
*/
|
|
182
177
|
const FormWizardFooter = ({ onBack, onCancel, isValid, primaryActionLabel = "Next" }) => {
|
|
183
|
-
|
|
178
|
+
const [t] = useTranslation();
|
|
179
|
+
return (jsxs("div", { className: cvaFooterContainer(), children: [jsx(Button, { dataTestId: "wizard-cancel", onClick: onCancel, variant: "ghost-neutral", children: t("wizard.defaults.cancel") }), jsxs("div", { className: cvaNavigationContainer(), children: [onBack ? (jsx(Button, { dataTestId: "wizard-back", onClick: onBack, variant: "secondary", children: t("wizard.defaults.back") })) : null, jsx(Button, { dataTestId: "wizard-next", disabled: !isValid, type: "submit", children: primaryActionLabel ? primaryActionLabel : t("wizard.defaults.next") })] })] }));
|
|
184
180
|
};
|
|
185
181
|
|
|
186
182
|
const cvaFormWizardHeader = cvaMerge([
|
|
@@ -234,7 +230,7 @@ const FormWizardStepWrapper = ({ stepKey, onCancel, description, title, componen
|
|
|
234
230
|
const setSubmitHandler = useCallback(callback => {
|
|
235
231
|
setSubmitHandlerInternal(() => callback);
|
|
236
232
|
}, [setSubmitHandlerInternal]);
|
|
237
|
-
const isEmptyStep =
|
|
233
|
+
const isEmptyStep = objectKeys(form.getValues()).length === 0;
|
|
238
234
|
const emptyStepSubmitHandler = useCallback((e) => {
|
|
239
235
|
e === null || e === void 0 ? void 0 : e.preventDefault();
|
|
240
236
|
submitHandlerInternal === null || submitHandlerInternal === void 0 ? void 0 : submitHandlerInternal(fullFormState);
|
|
@@ -292,14 +288,13 @@ const FormWizard = ({ lastStepPrimaryActionLabel, steps, fullFormSchema, onCance
|
|
|
292
288
|
const [stepStates, setStepStates] = useState({});
|
|
293
289
|
const [stepForms, setStepForms] = useState({});
|
|
294
290
|
const [fullFormState, setFullFormState] = useState({});
|
|
295
|
-
const currentVisibleStepKey = (_a =
|
|
296
|
-
const currentVisibleStepIndex =
|
|
297
|
-
return (jsx("div", { className: cvaFormWizardContainer({ className }), "data-testid": dataTestId, children: jsxs("div", { className: cvaFormWizardLayout(), children: [jsx(FormWizardSidebar, { children:
|
|
291
|
+
const currentVisibleStepKey = (_a = objectEntries(steps).find(([, { path }]) => location.pathname === basePath + path)) === null || _a === void 0 ? void 0 : _a[0];
|
|
292
|
+
const currentVisibleStepIndex = objectKeys(steps).findIndex(key => key === currentVisibleStepKey);
|
|
293
|
+
return (jsx("div", { className: cvaFormWizardContainer({ className }), "data-testid": dataTestId, children: jsxs("div", { className: cvaFormWizardLayout(), children: [jsx(FormWizardSidebar, { children: objectEntries(steps).map(([key, { path, title, sidebarDescription }], index) => {
|
|
298
294
|
const isPastStep = index < currentVisibleStepIndex;
|
|
299
295
|
const isFutureStep = index > currentVisibleStepIndex;
|
|
300
296
|
const isCurrentStep = key === currentVisibleStepKey;
|
|
301
|
-
|
|
302
|
-
const previousStepKey = Object.keys(steps)[index - 1];
|
|
297
|
+
const previousStepKey = objectKeys(steps)[index - 1];
|
|
303
298
|
const stepState = () => {
|
|
304
299
|
if (isCurrentStep) {
|
|
305
300
|
return "active";
|
|
@@ -308,7 +303,7 @@ const FormWizard = ({ lastStepPrimaryActionLabel, steps, fullFormSchema, onCance
|
|
|
308
303
|
return stepStates[key] === "valid" ? "done" : "invalid";
|
|
309
304
|
}
|
|
310
305
|
if (isFutureStep) {
|
|
311
|
-
return
|
|
306
|
+
return objectKeys(steps)
|
|
312
307
|
.filter((_, stepIndex) => stepIndex < index)
|
|
313
308
|
.every((pastStepKey) => stepStates[pastStepKey] === "valid")
|
|
314
309
|
? "ready"
|
|
@@ -329,11 +324,10 @@ const FormWizard = ({ lastStepPrimaryActionLabel, steps, fullFormSchema, onCance
|
|
|
329
324
|
},
|
|
330
325
|
path: basePath + path,
|
|
331
326
|
subTitle: sidebarDescription }));
|
|
332
|
-
}) }), jsx("div", { className: cvaStepContainer(), children: jsx(Routes, { children:
|
|
333
|
-
var _b, _c, _d
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
stepKey,
|
|
327
|
+
}) }), jsx("div", { className: cvaStepContainer(), children: jsx(Routes, { children: objectEntries(steps).map(([stepKey, props], index) => {
|
|
328
|
+
var _a, _b, _c, _d;
|
|
329
|
+
return (jsx(Route, { index: false, path: props.path, key: stepKey.toString(), element: jsx(FormWizardStepWrapper, Object.assign({}, props, { basePath,
|
|
330
|
+
stepKey: stepKey.toString(),
|
|
337
331
|
stepForms,
|
|
338
332
|
setStepForms,
|
|
339
333
|
onCancel,
|
|
@@ -342,8 +336,8 @@ const FormWizard = ({ lastStepPrimaryActionLabel, steps, fullFormSchema, onCance
|
|
|
342
336
|
setStepStates,
|
|
343
337
|
fullFormSchema,
|
|
344
338
|
lastStepPrimaryActionLabel,
|
|
345
|
-
nextStepPath: (
|
|
346
|
-
previousStepPath: (
|
|
339
|
+
nextStepPath: (_b = (_a = objectValues(steps)[index + 1]) === null || _a === void 0 ? void 0 : _a.path) !== null && _b !== void 0 ? _b : null,
|
|
340
|
+
previousStepPath: (_d = (_c = objectValues(steps)[index - 1]) === null || _c === void 0 ? void 0 : _c.path) !== null && _d !== void 0 ? _d : null }), stepKey.toString()) }));
|
|
347
341
|
}) }) })] }) }));
|
|
348
342
|
};
|
|
349
343
|
|
|
@@ -354,7 +348,7 @@ const useFormWizard = (props) => {
|
|
|
354
348
|
return useMemo(() => (Object.assign(Object.assign({}, props), {
|
|
355
349
|
// Object.fromEntries is not super type safe... This is a workaround...
|
|
356
350
|
// eslint-disable-next-line local-rules/no-typescript-assertion
|
|
357
|
-
steps:
|
|
351
|
+
steps: objectFromEntries(Object.entries(props.steps).map(([key, step]) => [
|
|
358
352
|
key,
|
|
359
353
|
Object.assign(Object.assign({}, step), { formSchema: props.fullFormSchema.shape[key] }),
|
|
360
354
|
])) })), [props]);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trackunit/react-form-wizard",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.27",
|
|
4
4
|
"repository": "https://github.com/Trackunit/manager",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
6
|
"dependencies": {
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
"@trackunit/react-components": "*",
|
|
12
12
|
"@hookform/resolvers": "^3.3.4",
|
|
13
13
|
"react-hook-form": "7.40.0",
|
|
14
|
-
"@trackunit/i18n-library-translation": "*"
|
|
14
|
+
"@trackunit/i18n-library-translation": "*",
|
|
15
|
+
"@trackunit/shared-utils": "*"
|
|
15
16
|
},
|
|
16
17
|
"engines": {
|
|
17
18
|
"node": ">=18.x",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
1
|
import { CommonProps } from "@trackunit/react-components";
|
|
2
|
+
import { ReactNode } from "react";
|
|
3
3
|
interface FormWizardHeaderProps extends CommonProps {
|
|
4
4
|
title: string;
|
|
5
|
-
description?: string;
|
|
5
|
+
description?: string | ReactNode;
|
|
6
6
|
}
|
|
7
7
|
/**
|
|
8
8
|
* The header component for the FormWizard.
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { Dispatch, SetStateAction } from "react";
|
|
1
|
+
import { Dispatch, ReactNode, SetStateAction } from "react";
|
|
2
2
|
import { UseFormReturn } from "react-hook-form";
|
|
3
3
|
import { ZodTypeAny, z } from "zod";
|
|
4
4
|
import { FormWizardStepFormReturnMap } from "../FormWizard/FormWizard";
|
|
5
|
-
import { SimpleStepProps, StepComponentPropsInner
|
|
5
|
+
import { ComponentStepDefinitions, SimpleStepProps, StepComponentPropsInner } from "../FormWizard/useFormWizard";
|
|
6
|
+
export type StepFormValidity = "valid" | "invalid";
|
|
6
7
|
export interface FormWizardStepWrapperProps<TStepKey extends keyof z.infer<TFullSchema>, TFullSchema extends ZodTypeAny> extends SimpleStepProps {
|
|
7
|
-
description: string;
|
|
8
|
+
description: string | ReactNode;
|
|
8
9
|
lastStepPrimaryActionLabel: string;
|
|
9
10
|
nextStepPath: string | null;
|
|
10
11
|
basePath: string;
|
|
@@ -15,8 +16,8 @@ export interface FormWizardStepWrapperProps<TStepKey extends keyof z.infer<TFull
|
|
|
15
16
|
setFullFormState: Dispatch<SetStateAction<Partial<z.TypeOf<TFullSchema>>>>;
|
|
16
17
|
stepKey: TStepKey;
|
|
17
18
|
formSchema: z.infer<TFullSchema>[TStepKey];
|
|
18
|
-
setStepStates: Dispatch<SetStateAction<Partial<Record<
|
|
19
|
-
component: (props: StepComponentPropsInner<z.infer<TFullSchema>[TStepKey], TFullSchema>) =>
|
|
19
|
+
setStepStates: Dispatch<SetStateAction<Partial<Record<keyof ComponentStepDefinitions<TFullSchema>, StepFormValidity>>>>;
|
|
20
|
+
component: (props: StepComponentPropsInner<z.infer<TFullSchema>[TStepKey], TFullSchema>) => ReactNode;
|
|
20
21
|
stepForms: FormWizardStepFormReturnMap<TFullSchema>;
|
|
21
22
|
setStepForms: Dispatch<SetStateAction<Partial<{
|
|
22
23
|
[TStepKey2 in keyof z.TypeOf<TFullSchema>]: UseFormReturn<z.TypeOf<TFullSchema>[TStepKey2]>;
|
package/src/translation.d.ts
CHANGED
|
@@ -15,8 +15,8 @@ export declare const translations: TranslationResource<TranslationKeys>;
|
|
|
15
15
|
/**
|
|
16
16
|
* Local useTranslation for this specific library
|
|
17
17
|
*/
|
|
18
|
-
export declare const useTranslation: () => [TransForLibs<
|
|
19
|
-
t: TransForLibs<
|
|
18
|
+
export declare const useTranslation: () => [TransForLibs<"wizard.defaults.back" | "wizard.defaults.cancel" | "wizard.defaults.next">, import("i18next").i18n, boolean] & {
|
|
19
|
+
t: TransForLibs<"wizard.defaults.back" | "wizard.defaults.cancel" | "wizard.defaults.next">;
|
|
20
20
|
i18n: import("i18next").i18n;
|
|
21
21
|
ready: boolean;
|
|
22
22
|
};
|