@trackunit/react-form-wizard 0.0.25 → 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
- return (jsxRuntime.jsxs("div", { className: cvaFooterContainer(), children: [jsxRuntime.jsx(reactComponents.Button, { dataTestId: "wizard-cancel", onClick: onCancel, variant: "ghost-neutral", children: "Cancel" }), jsxRuntime.jsxs("div", { className: cvaNavigationContainer(), children: [onBack ? (jsxRuntime.jsx(reactComponents.Button, { dataTestId: "wizard-back", onClick: onBack, variant: "secondary", children: "Back" })) : null, jsxRuntime.jsx(reactComponents.Button, { dataTestId: "wizard-next", disabled: !isValid, type: "submit", children: primaryActionLabel ? primaryActionLabel : "Next" })] })] }));
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 = Object.keys(form.getValues()).length === 0;
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 = Object.entries(steps).find(([, { path }]) => location.pathname === basePath + path)) === null || _a === void 0 ? void 0 : _a[0];
300
- const currentVisibleStepIndex = Object.keys(steps).findIndex(key => key === currentVisibleStepKey);
301
- return (jsxRuntime.jsx("div", { className: cvaFormWizardContainer({ className }), "data-testid": dataTestId, children: jsxRuntime.jsxs("div", { className: cvaFormWizardLayout(), children: [jsxRuntime.jsx(FormWizardSidebar, { children: Object.entries(steps).map(([key, { path, title, sidebarDescription }], index) => {
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
- // eslint-disable-next-line local-rules/no-typescript-assertion
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 Object.keys(steps)
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: Object.entries(steps).map((_a, index) => {
337
- var _b, _c, _d, _e;
338
- var [stepKey, _f] = _a, { path } = _f, rest = __rest(_f, ["path"]);
339
- return (jsxRuntime.jsx(reactRouterDom.Route, { index: false, path, key: stepKey, element: jsxRuntime.jsx(FormWizardStepWrapper, Object.assign({}, rest, { basePath,
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: (_c = (_b = Object.values(steps)[index + 1]) === null || _b === void 0 ? void 0 : _b.path) !== null && _c !== void 0 ? _c : null,
350
- previousStepPath: (_e = (_d = Object.values(steps)[index - 1]) === null || _d === void 0 ? void 0 : _d.path) !== null && _e !== void 0 ? _e : null }), stepKey) }));
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: Object.fromEntries(Object.entries(props.steps).map(([key, step]) => [
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
- return (jsxs("div", { className: cvaFooterContainer(), children: [jsx(Button, { dataTestId: "wizard-cancel", onClick: onCancel, variant: "ghost-neutral", children: "Cancel" }), jsxs("div", { className: cvaNavigationContainer(), children: [onBack ? (jsx(Button, { dataTestId: "wizard-back", onClick: onBack, variant: "secondary", children: "Back" })) : null, jsx(Button, { dataTestId: "wizard-next", disabled: !isValid, type: "submit", children: primaryActionLabel ? primaryActionLabel : "Next" })] })] }));
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 = Object.keys(form.getValues()).length === 0;
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 = Object.entries(steps).find(([, { path }]) => location.pathname === basePath + path)) === null || _a === void 0 ? void 0 : _a[0];
296
- const currentVisibleStepIndex = Object.keys(steps).findIndex(key => key === currentVisibleStepKey);
297
- return (jsx("div", { className: cvaFormWizardContainer({ className }), "data-testid": dataTestId, children: jsxs("div", { className: cvaFormWizardLayout(), children: [jsx(FormWizardSidebar, { children: Object.entries(steps).map(([key, { path, title, sidebarDescription }], index) => {
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
- // eslint-disable-next-line local-rules/no-typescript-assertion
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 Object.keys(steps)
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: Object.entries(steps).map((_a, index) => {
333
- var _b, _c, _d, _e;
334
- var [stepKey, _f] = _a, { path } = _f, rest = __rest(_f, ["path"]);
335
- return (jsx(Route, { index: false, path, key: stepKey, element: jsx(FormWizardStepWrapper, Object.assign({}, rest, { basePath,
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: (_c = (_b = Object.values(steps)[index + 1]) === null || _b === void 0 ? void 0 : _b.path) !== null && _c !== void 0 ? _c : null,
346
- previousStepPath: (_e = (_d = Object.values(steps)[index - 1]) === null || _d === void 0 ? void 0 : _d.path) !== null && _e !== void 0 ? _e : null }), stepKey) }));
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: Object.fromEntries(Object.entries(props.steps).map(([key, step]) => [
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.25",
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, StepState } from "../FormWizard/useFormWizard";
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<TStepKey, StepState>>>>;
19
- component: (props: StepComponentPropsInner<z.infer<TFullSchema>[TStepKey], TFullSchema>) => React.ReactNode;
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]>;
@@ -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<never>, import("i18next").i18n, boolean] & {
19
- t: TransForLibs<never>;
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
  };