@trackunit/react-form-wizard 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +25 -0
  2. package/index.cjs.d.ts +1 -0
  3. package/index.cjs.js +339 -0
  4. package/index.esm.js +334 -0
  5. package/package.json +22 -0
  6. package/src/FormWizard/FormWizard.d.ts +8 -0
  7. package/src/FormWizard/FormWizard.variants.d.ts +3 -0
  8. package/src/FormWizard/useFormWizard.d.ts +44 -0
  9. package/src/FormWizardFooter/FormWizardFooter.d.ts +14 -0
  10. package/src/FormWizardFooter/FormWizardFooter.variants.d.ts +2 -0
  11. package/src/FormWizardHeader/FormWizardHeader.d.ts +12 -0
  12. package/src/FormWizardHeader/FormWizardHeader.variants.d.ts +1 -0
  13. package/src/FormWizardSidebar/FormWizardSidebar.d.ts +14 -0
  14. package/src/FormWizardSidebar/FormWizardSidebar.variants.d.ts +2 -0
  15. package/src/FormWizardSidebarStep/FormWizardSidebarStep.d.ts +16 -0
  16. package/src/FormWizardSidebarStep/FormWizardSidebarStep.variants.d.ts +12 -0
  17. package/src/FormWizardStepWrapper/FormWizardStepWrapper.d.ts +23 -0
  18. package/src/FormWizardStepWrapper/FormWizardStepWrapper.variants.d.ts +2 -0
  19. package/src/index.d.ts +2 -0
  20. package/src/translation.d.ts +34 -0
  21. package/translation.cjs.js +7 -0
  22. package/translation.cjs10.js +7 -0
  23. package/translation.cjs11.js +7 -0
  24. package/translation.cjs12.js +7 -0
  25. package/translation.cjs13.js +7 -0
  26. package/translation.cjs14.js +7 -0
  27. package/translation.cjs15.js +7 -0
  28. package/translation.cjs16.js +7 -0
  29. package/translation.cjs17.js +7 -0
  30. package/translation.cjs2.js +7 -0
  31. package/translation.cjs3.js +7 -0
  32. package/translation.cjs4.js +7 -0
  33. package/translation.cjs5.js +7 -0
  34. package/translation.cjs6.js +7 -0
  35. package/translation.cjs7.js +7 -0
  36. package/translation.cjs8.js +7 -0
  37. package/translation.cjs9.js +7 -0
  38. package/translation.esm.js +5 -0
  39. package/translation.esm10.js +5 -0
  40. package/translation.esm11.js +5 -0
  41. package/translation.esm12.js +5 -0
  42. package/translation.esm13.js +5 -0
  43. package/translation.esm14.js +5 -0
  44. package/translation.esm15.js +5 -0
  45. package/translation.esm16.js +5 -0
  46. package/translation.esm17.js +5 -0
  47. package/translation.esm2.js +5 -0
  48. package/translation.esm3.js +5 -0
  49. package/translation.esm4.js +5 -0
  50. package/translation.esm5.js +5 -0
  51. package/translation.esm6.js +5 -0
  52. package/translation.esm7.js +5 -0
  53. package/translation.esm8.js +5 -0
  54. package/translation.esm9.js +5 -0
package/README.md ADDED
@@ -0,0 +1,25 @@
1
+ > **⚠️ Beta**
2
+ >
3
+ > This is a beta version and subject to change without notice.
4
+
5
+ # Trackunit react-form-wizard
6
+
7
+ The `@trackunit/react-form-wizard` package is the home of Trackunits public react form wizard components.
8
+
9
+ This library is exposed publicly for use in the the Trackunit [Iris App SDK](https://www.npmjs.com/package/@trackunit/iris-app).
10
+
11
+ To browse all avaliable components visit our [Public Storybook](https://apps.iris.trackunit.com/storybook/).
12
+
13
+ For more info and a full guide on Iris App SDK Development, please visit our [Developer Hub](https://developers.trackunit.com/).
14
+
15
+ ## Development
16
+
17
+ At this point this library is only developed by Trackunit Employees.
18
+ For development related information see the [development readme](https://github.com/Trackunit/manager/blob/master/libs/react/components/DEVELOPMENT.md).
19
+
20
+ ## Trackunit
21
+
22
+ This package was developed by Trackunit ApS.
23
+ Trackunit is the leading SaaS-based IoT solution for the construction industry, offering an ecosystem of hardware, fleet management software & telematics.
24
+
25
+ ![The Trackunit logo](https://trackunit.com/wp-content/uploads/2022/03/top-logo.svg)
package/index.cjs.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from "./src/index";
package/index.cjs.js ADDED
@@ -0,0 +1,339 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var jsxRuntime = require('react/jsx-runtime');
6
+ var i18nLibraryTranslation = require('@trackunit/i18n-library-translation');
7
+ var react = require('react');
8
+ var reactRouterDom = require('react-router-dom');
9
+ var cssClassVarianceUtilities = require('@trackunit/css-class-variance-utilities');
10
+ var reactComponents = require('@trackunit/react-components');
11
+ var zod = require('@hookform/resolvers/zod');
12
+ var reactHookForm = require('react-hook-form');
13
+
14
+ var defaultTranslations = {
15
+
16
+ };
17
+
18
+ /** The translation namespace for this library */
19
+ const namespace = "react.form-wizard";
20
+ /**
21
+ * The TranslationResource for this Library.
22
+ * Holds lazy loaded imports for all languages supported by the library.
23
+ *
24
+ * This is used to register the translations for this library before initializing i18next.
25
+ */
26
+ const translations = {
27
+ ns: namespace,
28
+ default: defaultTranslations,
29
+ languages: {
30
+ de: () => Promise.resolve().then(function () { return require('./translation.cjs.js'); }),
31
+ da: () => Promise.resolve().then(function () { return require('./translation.cjs2.js'); }),
32
+ cs: () => Promise.resolve().then(function () { return require('./translation.cjs3.js'); }),
33
+ nl: () => Promise.resolve().then(function () { return require('./translation.cjs4.js'); }),
34
+ fr: () => Promise.resolve().then(function () { return require('./translation.cjs5.js'); }),
35
+ fi: () => Promise.resolve().then(function () { return require('./translation.cjs6.js'); }),
36
+ hu: () => Promise.resolve().then(function () { return require('./translation.cjs7.js'); }),
37
+ it: () => Promise.resolve().then(function () { return require('./translation.cjs8.js'); }),
38
+ nb: () => Promise.resolve().then(function () { return require('./translation.cjs9.js'); }),
39
+ pl: () => Promise.resolve().then(function () { return require('./translation.cjs10.js'); }),
40
+ pt: () => Promise.resolve().then(function () { return require('./translation.cjs11.js'); }),
41
+ ru: () => Promise.resolve().then(function () { return require('./translation.cjs12.js'); }),
42
+ ro: () => Promise.resolve().then(function () { return require('./translation.cjs13.js'); }),
43
+ es: () => Promise.resolve().then(function () { return require('./translation.cjs14.js'); }),
44
+ sv: () => Promise.resolve().then(function () { return require('./translation.cjs15.js'); }),
45
+ ja: () => Promise.resolve().then(function () { return require('./translation.cjs16.js'); }),
46
+ th: () => Promise.resolve().then(function () { return require('./translation.cjs17.js'); }),
47
+ },
48
+ };
49
+ /**
50
+ * Registers the translations for this library
51
+ */
52
+ const setupLibraryTranslations = () => {
53
+ i18nLibraryTranslation.registerTranslations(translations);
54
+ };
55
+
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
+ const cvaFillSection = cssClassVarianceUtilities.cvaMerge(["flex-grow", "p-0"]);
94
+ const cvaSidebar = cssClassVarianceUtilities.cvaMerge([
95
+ "flex",
96
+ "flex-col",
97
+ "overflow-x-hidden",
98
+ "h-full",
99
+ "gap-2",
100
+ "p-responsive-space",
101
+ "bg-slate-50",
102
+ "border-r",
103
+ "border-slate-200",
104
+ ]);
105
+
106
+ /**
107
+ * Displays the sidebar with steps for the wizard.
108
+ * Prefer using the FormWizard component instead of this directly.
109
+ */
110
+ function FormWizardSidebar({ dataTestId, children, className }) {
111
+ return (jsxRuntime.jsxs("aside", { className: cvaSidebar({ className }), "data-testid": dataTestId, children: [children, jsxRuntime.jsx("div", { className: cvaFillSection() })] }));
112
+ }
113
+
114
+ const cvaFormWizardSidebarStep = cssClassVarianceUtilities.cvaMerge(["p-2", "rounded-md", "hover:bg-slate-200", "transition"], {
115
+ variants: {
116
+ state: {
117
+ ready: "",
118
+ active: "text-primary-600 bg-slate-100",
119
+ done: "text-success-600",
120
+ invalid: "text-warning-600",
121
+ disabled: "pointer-events-none cursor-not-allowed opacity-50 hover:bg-transparent",
122
+ },
123
+ },
124
+ });
125
+ const cvaSectionHeaderContainer = cssClassVarianceUtilities.cvaMerge(["flex", "justify-between", "gap-2"], {
126
+ variants: {
127
+ cursor: {
128
+ withCursor: "hover:cursor-pointer",
129
+ default: "",
130
+ },
131
+ },
132
+ defaultVariants: {
133
+ cursor: "default",
134
+ },
135
+ });
136
+ const cvaHeader = cssClassVarianceUtilities.cvaMerge(["text-md"]);
137
+ const cvaSubtitle = cssClassVarianceUtilities.cvaMerge(["text-xs", "text-gray-500"]);
138
+ const cvaStepNumber = cssClassVarianceUtilities.cvaMerge(["flex", "justify-center", "text-xs", "items-center", "m-0.5", "w-[20px]", "h-[20px]", "bg-gray-100", "rounded-full"], {
139
+ variants: {
140
+ state: {
141
+ ready: "",
142
+ active: "bg-primary-600 text-white",
143
+ done: "",
144
+ invalid: "bg-warning-500 text-white",
145
+ disabled: "",
146
+ },
147
+ },
148
+ });
149
+ const cvaTitleAndDescription = cssClassVarianceUtilities.cvaMerge(["justify-center", "flex-1", "flex-col", "hidden", "@3xl:flex"]); //use same container breakpoint as cvaWizardContainer so it collapses at the same time
150
+
151
+ const getStateIcon = (state) => {
152
+ switch (state) {
153
+ case "done":
154
+ return jsxRuntime.jsx(reactComponents.Icon, { color: "success", name: "CheckCircle", type: "solid" });
155
+ case "invalid":
156
+ return jsxRuntime.jsx(reactComponents.Icon, { color: "warning", name: "ExclamationCircle", type: "solid" });
157
+ default:
158
+ return null;
159
+ }
160
+ };
161
+ /**
162
+ * A sidebar step component used by the FormWizard component to render each step.
163
+ * This component is generally used internally by the FormWizard component.
164
+ */
165
+ const FormWizardSidebarStep = ({ stepNumber, state, title, subTitle, path, dataTestId, }) => {
166
+ const stateIcon = getStateIcon(state);
167
+ return (jsxRuntime.jsx(reactRouterDom.NavLink, { className: cvaFormWizardSidebarStep({ state }), "data-testid": dataTestId !== null && dataTestId !== void 0 ? dataTestId : `form-wizard-sidebar-step-${path}`, 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
+ };
169
+
170
+ const cvaFooterContainer = cssClassVarianceUtilities.cvaMerge([
171
+ "flex-grow-0",
172
+ "flex",
173
+ "justify-between",
174
+ "items-center",
175
+ "h-min",
176
+ "p-responsive-space",
177
+ "border-t",
178
+ "gap-responsive-space",
179
+ ]);
180
+ const cvaNavigationContainer = cssClassVarianceUtilities.cvaMerge(["flex", "gap-responsive-space"]);
181
+
182
+ /**
183
+ * The footer component for the FormWizard.
184
+ * In most cases you should not be using this component directly, but rather use the FormWizard component.
185
+ */
186
+ 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" })] })] }));
188
+ };
189
+
190
+ const cvaFormWizardHeader = cssClassVarianceUtilities.cvaMerge([
191
+ "flex",
192
+ "flex-col",
193
+ "p-responsive-space",
194
+ "border-b-slate-300",
195
+ "border-b-2",
196
+ ]);
197
+
198
+ /**
199
+ * The header component for the FormWizard.
200
+ * In most cases you should not be using this component directly, but rather use the FormWizard component.
201
+ */
202
+ const FormWizardHeader = ({ title, description, className, dataTestId }) => {
203
+ return (jsxRuntime.jsxs("div", { className: cvaFormWizardHeader({ className }), "data-testid": dataTestId, children: [jsxRuntime.jsx(reactComponents.Heading, { variant: "primary", children: title }), description ? description : null] }));
204
+ };
205
+
206
+ const cvaFormWizardComponentContainer = cssClassVarianceUtilities.cvaMerge(["p-responsive-space"]);
207
+ const cvaFormWizardComponentStepForm = cssClassVarianceUtilities.cvaMerge(["grid-rows-min-fr-min", "grid", "h-full"]);
208
+
209
+ /**
210
+ * A wrapper component used by the FormWizard component to render each step.
211
+ * In most cases you should not be using this component directly, but rather use the FormWizard component.
212
+ */
213
+ const FormWizardStepWrapper = ({ stepKey, onCancel, description, title, component, formSchema, nextStepPath, previousStepPath, lastStepPrimaryActionLabel, fullFormSchema, setFullFormState, fullFormState, setStepStates, basePath, }) => {
214
+ const navigate = reactRouterDom.useNavigate();
215
+ const [submitHandlerInternal, setSubmitHandlerInternal] = react.useState(null);
216
+ const form = reactHookForm.useForm({ resolver: zod.zodResolver(formSchema), mode: "all" });
217
+ const fullForm = reactHookForm.useForm({
218
+ resolver: zod.zodResolver(fullFormSchema),
219
+ mode: "all",
220
+ defaultValues: fullFormState,
221
+ });
222
+ react.useEffect(() => {
223
+ setStepStates(prev => (Object.assign(Object.assign({}, prev), { [stepKey]: form.formState.isValid ? "valid" : "invalid" })));
224
+ }, [form.formState.isValid, setStepStates, stepKey]);
225
+ const isLastStep = nextStepPath === null;
226
+ const handleCancel = react.useCallback(() => {
227
+ // TODO: Get previous path from before wizard the wizard was started
228
+ return onCancel ? onCancel() : navigate(basePath);
229
+ }, [onCancel, navigate, basePath]);
230
+ const setSubmitHandler = react.useCallback(callback => {
231
+ setSubmitHandlerInternal(() => callback);
232
+ }, [setSubmitHandlerInternal]);
233
+ return (jsxRuntime.jsxs("form", { className: cvaFormWizardComponentStepForm(), onSubmit: form.handleSubmit((data) => __awaiter(void 0, void 0, void 0, function* () {
234
+ //? This state is not updated for the submit handler below; therefore, there is duplication.
235
+ setFullFormState(prev => (Object.assign(Object.assign({}, prev), { [stepKey]: data })));
236
+ if (isLastStep) {
237
+ //? This state is not updated for the submit handler below; therefore, there is duplication.
238
+ submitHandlerInternal === null || submitHandlerInternal === void 0 ? void 0 : submitHandlerInternal(Object.assign(Object.assign({}, fullFormState), { [stepKey]: data }));
239
+ }
240
+ else if (nextStepPath) {
241
+ navigate(basePath + nextStepPath);
242
+ }
243
+ })), children: [jsxRuntime.jsx(FormWizardHeader, { title, description }), jsxRuntime.jsx("div", { className: cvaFormWizardComponentContainer(), children: component({
244
+ form,
245
+ fullForm,
246
+ setSubmitHandler: isLastStep ? setSubmitHandler : null,
247
+ }) }), jsxRuntime.jsx(FormWizardFooter, { onBack: previousStepPath ? () => navigate(basePath + previousStepPath) : null,
248
+ primaryActionLabel: isLastStep ? lastStepPrimaryActionLabel : undefined,
249
+ onCancel: handleCancel,
250
+ isValid: form.formState.isValid })] }, String(stepKey)));
251
+ };
252
+
253
+ const cvaFormWizardContainer = cssClassVarianceUtilities.cvaMerge(["h-full"]);
254
+ const cvaFormWizardLayout = cssClassVarianceUtilities.cvaMerge([
255
+ "grid",
256
+ "h-full",
257
+ "grid-cols-min-fr",
258
+ "@3xl:grid-cols-[240px_1fr]",
259
+ "@4xl:grid-cols-[320px_1fr]",
260
+ ]);
261
+ const cvaStepContainer = cssClassVarianceUtilities.cvaMerge(["h-full", "grid", "bg-white", "overflow-hidden"]);
262
+
263
+ /**
264
+ * The FormWizard component is used for forms in multiple steps.
265
+ * Use the useFormWizard hook to generate the props for this component.
266
+ */
267
+ const FormWizard = ({ lastStepPrimaryActionLabel, steps, fullFormSchema, onCancel, className, dataTestId, basePath, }) => {
268
+ var _a;
269
+ const location = reactRouterDom.useLocation();
270
+ const [stepStates, setStepStates] = react.useState({});
271
+ const [fullFormState, setFullFormState] = react.useState({});
272
+ const currentVisibleStepKey = (_a = Object.entries(steps).find(([, { path }]) => location.pathname === path)) === null || _a === void 0 ? void 0 : _a[0];
273
+ const currentVisibleStepIndex = Object.keys(steps).findIndex(key => key === currentVisibleStepKey);
274
+ 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) => {
275
+ const isPastStep = index < currentVisibleStepIndex;
276
+ const isFutureStep = index > currentVisibleStepIndex;
277
+ const isCurrentStep = key === currentVisibleStepKey;
278
+ const stepState = () => {
279
+ if (isCurrentStep) {
280
+ return "active";
281
+ }
282
+ if (isPastStep) {
283
+ return stepStates[key] === "valid" ? "done" : "invalid";
284
+ }
285
+ if (isFutureStep) {
286
+ return Object.keys(steps)
287
+ .filter((_, stepIndex) => stepIndex < index)
288
+ .every((pastStepKey) => stepStates[pastStepKey] === "valid")
289
+ ? "ready"
290
+ : "disabled";
291
+ }
292
+ return "ready";
293
+ };
294
+ return (jsxRuntime.jsx(FormWizardSidebarStep, { key: String(key),
295
+ state: stepState(),
296
+ stepNumber: index + 1,
297
+ title,
298
+ path,
299
+ subTitle: sidebarDescription }));
300
+ }) }), jsxRuntime.jsx("div", { className: cvaStepContainer(), children: jsxRuntime.jsx(reactRouterDom.Routes, { children: Object.entries(steps).map((_a, index) => {
301
+ var _b, _c, _d, _e;
302
+ var [stepKey, _f] = _a, { path } = _f, rest = __rest(_f, ["path"]);
303
+ return (jsxRuntime.jsx(reactRouterDom.Route, { index: true, path, key: stepKey, element: jsxRuntime.jsx(FormWizardStepWrapper, Object.assign({}, rest, { basePath,
304
+ stepKey,
305
+ onCancel,
306
+ fullFormState,
307
+ setFullFormState,
308
+ setStepStates,
309
+ fullFormSchema,
310
+ lastStepPrimaryActionLabel,
311
+ nextStepPath: (_c = (_b = Object.values(steps)[index + 1]) === null || _b === void 0 ? void 0 : _b.path) !== null && _c !== void 0 ? _c : null,
312
+ previousStepPath: (_e = (_d = Object.values(steps)[index - 1]) === null || _d === void 0 ? void 0 : _d.path) !== null && _e !== void 0 ? _e : null })) }));
313
+ }) }) })] }) }));
314
+ };
315
+
316
+ /**
317
+ *
318
+ */
319
+ const useFormWizard = (props) => {
320
+ return react.useMemo(() => (Object.assign(Object.assign({}, props), {
321
+ // Object.fromEntries is not super type safe... This is a workaround...
322
+ // eslint-disable-next-line local-rules/no-typescript-assertion
323
+ steps: Object.fromEntries(Object.entries(props.steps).map(([key, step]) => [
324
+ key,
325
+ Object.assign(Object.assign({}, step), { formSchema: props.fullFormSchema.shape[key] }),
326
+ ])) })), [props]);
327
+ };
328
+
329
+ /*
330
+ * ----------------------------
331
+ * | SETUP TRANSLATIONS START |
332
+ * ----------------------------
333
+ * This import and function call is needed to register translations for this library.
334
+ * Do not remove this if this library has translations.
335
+ */
336
+ setupLibraryTranslations();
337
+
338
+ exports.FormWizard = FormWizard;
339
+ exports.useFormWizard = useFormWizard;
package/index.esm.js ADDED
@@ -0,0 +1,334 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { registerTranslations } from '@trackunit/i18n-library-translation';
3
+ import { useState, useEffect, useCallback, useMemo } from 'react';
4
+ import { NavLink, useNavigate, useLocation, Routes, Route } from 'react-router-dom';
5
+ import { cvaMerge } from '@trackunit/css-class-variance-utilities';
6
+ import { Icon, Button, Heading } from '@trackunit/react-components';
7
+ import { zodResolver } from '@hookform/resolvers/zod';
8
+ import { useForm } from 'react-hook-form';
9
+
10
+ var defaultTranslations = {
11
+
12
+ };
13
+
14
+ /** The translation namespace for this library */
15
+ const namespace = "react.form-wizard";
16
+ /**
17
+ * The TranslationResource for this Library.
18
+ * Holds lazy loaded imports for all languages supported by the library.
19
+ *
20
+ * This is used to register the translations for this library before initializing i18next.
21
+ */
22
+ const translations = {
23
+ ns: namespace,
24
+ default: defaultTranslations,
25
+ languages: {
26
+ de: () => import('./translation.esm.js'),
27
+ da: () => import('./translation.esm2.js'),
28
+ cs: () => import('./translation.esm3.js'),
29
+ nl: () => import('./translation.esm4.js'),
30
+ fr: () => import('./translation.esm5.js'),
31
+ fi: () => import('./translation.esm6.js'),
32
+ hu: () => import('./translation.esm7.js'),
33
+ it: () => import('./translation.esm8.js'),
34
+ nb: () => import('./translation.esm9.js'),
35
+ pl: () => import('./translation.esm10.js'),
36
+ pt: () => import('./translation.esm11.js'),
37
+ ru: () => import('./translation.esm12.js'),
38
+ ro: () => import('./translation.esm13.js'),
39
+ es: () => import('./translation.esm14.js'),
40
+ sv: () => import('./translation.esm15.js'),
41
+ ja: () => import('./translation.esm16.js'),
42
+ th: () => import('./translation.esm17.js'),
43
+ },
44
+ };
45
+ /**
46
+ * Registers the translations for this library
47
+ */
48
+ const setupLibraryTranslations = () => {
49
+ registerTranslations(translations);
50
+ };
51
+
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
+ const cvaFillSection = cvaMerge(["flex-grow", "p-0"]);
90
+ const cvaSidebar = cvaMerge([
91
+ "flex",
92
+ "flex-col",
93
+ "overflow-x-hidden",
94
+ "h-full",
95
+ "gap-2",
96
+ "p-responsive-space",
97
+ "bg-slate-50",
98
+ "border-r",
99
+ "border-slate-200",
100
+ ]);
101
+
102
+ /**
103
+ * Displays the sidebar with steps for the wizard.
104
+ * Prefer using the FormWizard component instead of this directly.
105
+ */
106
+ function FormWizardSidebar({ dataTestId, children, className }) {
107
+ return (jsxs("aside", { className: cvaSidebar({ className }), "data-testid": dataTestId, children: [children, jsx("div", { className: cvaFillSection() })] }));
108
+ }
109
+
110
+ const cvaFormWizardSidebarStep = cvaMerge(["p-2", "rounded-md", "hover:bg-slate-200", "transition"], {
111
+ variants: {
112
+ state: {
113
+ ready: "",
114
+ active: "text-primary-600 bg-slate-100",
115
+ done: "text-success-600",
116
+ invalid: "text-warning-600",
117
+ disabled: "pointer-events-none cursor-not-allowed opacity-50 hover:bg-transparent",
118
+ },
119
+ },
120
+ });
121
+ const cvaSectionHeaderContainer = cvaMerge(["flex", "justify-between", "gap-2"], {
122
+ variants: {
123
+ cursor: {
124
+ withCursor: "hover:cursor-pointer",
125
+ default: "",
126
+ },
127
+ },
128
+ defaultVariants: {
129
+ cursor: "default",
130
+ },
131
+ });
132
+ const cvaHeader = cvaMerge(["text-md"]);
133
+ const cvaSubtitle = cvaMerge(["text-xs", "text-gray-500"]);
134
+ const cvaStepNumber = cvaMerge(["flex", "justify-center", "text-xs", "items-center", "m-0.5", "w-[20px]", "h-[20px]", "bg-gray-100", "rounded-full"], {
135
+ variants: {
136
+ state: {
137
+ ready: "",
138
+ active: "bg-primary-600 text-white",
139
+ done: "",
140
+ invalid: "bg-warning-500 text-white",
141
+ disabled: "",
142
+ },
143
+ },
144
+ });
145
+ const cvaTitleAndDescription = cvaMerge(["justify-center", "flex-1", "flex-col", "hidden", "@3xl:flex"]); //use same container breakpoint as cvaWizardContainer so it collapses at the same time
146
+
147
+ const getStateIcon = (state) => {
148
+ switch (state) {
149
+ case "done":
150
+ return jsx(Icon, { color: "success", name: "CheckCircle", type: "solid" });
151
+ case "invalid":
152
+ return jsx(Icon, { color: "warning", name: "ExclamationCircle", type: "solid" });
153
+ default:
154
+ return null;
155
+ }
156
+ };
157
+ /**
158
+ * A sidebar step component used by the FormWizard component to render each step.
159
+ * This component is generally used internally by the FormWizard component.
160
+ */
161
+ const FormWizardSidebarStep = ({ stepNumber, state, title, subTitle, path, dataTestId, }) => {
162
+ const stateIcon = getStateIcon(state);
163
+ return (jsx(NavLink, { className: cvaFormWizardSidebarStep({ state }), "data-testid": dataTestId !== null && dataTestId !== void 0 ? dataTestId : `form-wizard-sidebar-step-${path}`, 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
+ };
165
+
166
+ const cvaFooterContainer = cvaMerge([
167
+ "flex-grow-0",
168
+ "flex",
169
+ "justify-between",
170
+ "items-center",
171
+ "h-min",
172
+ "p-responsive-space",
173
+ "border-t",
174
+ "gap-responsive-space",
175
+ ]);
176
+ const cvaNavigationContainer = cvaMerge(["flex", "gap-responsive-space"]);
177
+
178
+ /**
179
+ * The footer component for the FormWizard.
180
+ * In most cases you should not be using this component directly, but rather use the FormWizard component.
181
+ */
182
+ 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" })] })] }));
184
+ };
185
+
186
+ const cvaFormWizardHeader = cvaMerge([
187
+ "flex",
188
+ "flex-col",
189
+ "p-responsive-space",
190
+ "border-b-slate-300",
191
+ "border-b-2",
192
+ ]);
193
+
194
+ /**
195
+ * The header component for the FormWizard.
196
+ * In most cases you should not be using this component directly, but rather use the FormWizard component.
197
+ */
198
+ const FormWizardHeader = ({ title, description, className, dataTestId }) => {
199
+ return (jsxs("div", { className: cvaFormWizardHeader({ className }), "data-testid": dataTestId, children: [jsx(Heading, { variant: "primary", children: title }), description ? description : null] }));
200
+ };
201
+
202
+ const cvaFormWizardComponentContainer = cvaMerge(["p-responsive-space"]);
203
+ const cvaFormWizardComponentStepForm = cvaMerge(["grid-rows-min-fr-min", "grid", "h-full"]);
204
+
205
+ /**
206
+ * A wrapper component used by the FormWizard component to render each step.
207
+ * In most cases you should not be using this component directly, but rather use the FormWizard component.
208
+ */
209
+ const FormWizardStepWrapper = ({ stepKey, onCancel, description, title, component, formSchema, nextStepPath, previousStepPath, lastStepPrimaryActionLabel, fullFormSchema, setFullFormState, fullFormState, setStepStates, basePath, }) => {
210
+ const navigate = useNavigate();
211
+ const [submitHandlerInternal, setSubmitHandlerInternal] = useState(null);
212
+ const form = useForm({ resolver: zodResolver(formSchema), mode: "all" });
213
+ const fullForm = useForm({
214
+ resolver: zodResolver(fullFormSchema),
215
+ mode: "all",
216
+ defaultValues: fullFormState,
217
+ });
218
+ useEffect(() => {
219
+ setStepStates(prev => (Object.assign(Object.assign({}, prev), { [stepKey]: form.formState.isValid ? "valid" : "invalid" })));
220
+ }, [form.formState.isValid, setStepStates, stepKey]);
221
+ const isLastStep = nextStepPath === null;
222
+ const handleCancel = useCallback(() => {
223
+ // TODO: Get previous path from before wizard the wizard was started
224
+ return onCancel ? onCancel() : navigate(basePath);
225
+ }, [onCancel, navigate, basePath]);
226
+ const setSubmitHandler = useCallback(callback => {
227
+ setSubmitHandlerInternal(() => callback);
228
+ }, [setSubmitHandlerInternal]);
229
+ return (jsxs("form", { className: cvaFormWizardComponentStepForm(), onSubmit: form.handleSubmit((data) => __awaiter(void 0, void 0, void 0, function* () {
230
+ //? This state is not updated for the submit handler below; therefore, there is duplication.
231
+ setFullFormState(prev => (Object.assign(Object.assign({}, prev), { [stepKey]: data })));
232
+ if (isLastStep) {
233
+ //? This state is not updated for the submit handler below; therefore, there is duplication.
234
+ submitHandlerInternal === null || submitHandlerInternal === void 0 ? void 0 : submitHandlerInternal(Object.assign(Object.assign({}, fullFormState), { [stepKey]: data }));
235
+ }
236
+ else if (nextStepPath) {
237
+ navigate(basePath + nextStepPath);
238
+ }
239
+ })), children: [jsx(FormWizardHeader, { title, description }), jsx("div", { className: cvaFormWizardComponentContainer(), children: component({
240
+ form,
241
+ fullForm,
242
+ setSubmitHandler: isLastStep ? setSubmitHandler : null,
243
+ }) }), jsx(FormWizardFooter, { onBack: previousStepPath ? () => navigate(basePath + previousStepPath) : null,
244
+ primaryActionLabel: isLastStep ? lastStepPrimaryActionLabel : undefined,
245
+ onCancel: handleCancel,
246
+ isValid: form.formState.isValid })] }, String(stepKey)));
247
+ };
248
+
249
+ const cvaFormWizardContainer = cvaMerge(["h-full"]);
250
+ const cvaFormWizardLayout = cvaMerge([
251
+ "grid",
252
+ "h-full",
253
+ "grid-cols-min-fr",
254
+ "@3xl:grid-cols-[240px_1fr]",
255
+ "@4xl:grid-cols-[320px_1fr]",
256
+ ]);
257
+ const cvaStepContainer = cvaMerge(["h-full", "grid", "bg-white", "overflow-hidden"]);
258
+
259
+ /**
260
+ * The FormWizard component is used for forms in multiple steps.
261
+ * Use the useFormWizard hook to generate the props for this component.
262
+ */
263
+ const FormWizard = ({ lastStepPrimaryActionLabel, steps, fullFormSchema, onCancel, className, dataTestId, basePath, }) => {
264
+ var _a;
265
+ const location = useLocation();
266
+ const [stepStates, setStepStates] = useState({});
267
+ const [fullFormState, setFullFormState] = useState({});
268
+ const currentVisibleStepKey = (_a = Object.entries(steps).find(([, { path }]) => location.pathname === path)) === null || _a === void 0 ? void 0 : _a[0];
269
+ const currentVisibleStepIndex = Object.keys(steps).findIndex(key => key === currentVisibleStepKey);
270
+ 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) => {
271
+ const isPastStep = index < currentVisibleStepIndex;
272
+ const isFutureStep = index > currentVisibleStepIndex;
273
+ const isCurrentStep = key === currentVisibleStepKey;
274
+ const stepState = () => {
275
+ if (isCurrentStep) {
276
+ return "active";
277
+ }
278
+ if (isPastStep) {
279
+ return stepStates[key] === "valid" ? "done" : "invalid";
280
+ }
281
+ if (isFutureStep) {
282
+ return Object.keys(steps)
283
+ .filter((_, stepIndex) => stepIndex < index)
284
+ .every((pastStepKey) => stepStates[pastStepKey] === "valid")
285
+ ? "ready"
286
+ : "disabled";
287
+ }
288
+ return "ready";
289
+ };
290
+ return (jsx(FormWizardSidebarStep, { key: String(key),
291
+ state: stepState(),
292
+ stepNumber: index + 1,
293
+ title,
294
+ path,
295
+ subTitle: sidebarDescription }));
296
+ }) }), jsx("div", { className: cvaStepContainer(), children: jsx(Routes, { children: Object.entries(steps).map((_a, index) => {
297
+ var _b, _c, _d, _e;
298
+ var [stepKey, _f] = _a, { path } = _f, rest = __rest(_f, ["path"]);
299
+ return (jsx(Route, { index: true, path, key: stepKey, element: jsx(FormWizardStepWrapper, Object.assign({}, rest, { basePath,
300
+ stepKey,
301
+ onCancel,
302
+ fullFormState,
303
+ setFullFormState,
304
+ setStepStates,
305
+ fullFormSchema,
306
+ lastStepPrimaryActionLabel,
307
+ nextStepPath: (_c = (_b = Object.values(steps)[index + 1]) === null || _b === void 0 ? void 0 : _b.path) !== null && _c !== void 0 ? _c : null,
308
+ previousStepPath: (_e = (_d = Object.values(steps)[index - 1]) === null || _d === void 0 ? void 0 : _d.path) !== null && _e !== void 0 ? _e : null })) }));
309
+ }) }) })] }) }));
310
+ };
311
+
312
+ /**
313
+ *
314
+ */
315
+ const useFormWizard = (props) => {
316
+ return useMemo(() => (Object.assign(Object.assign({}, props), {
317
+ // Object.fromEntries is not super type safe... This is a workaround...
318
+ // eslint-disable-next-line local-rules/no-typescript-assertion
319
+ steps: Object.fromEntries(Object.entries(props.steps).map(([key, step]) => [
320
+ key,
321
+ Object.assign(Object.assign({}, step), { formSchema: props.fullFormSchema.shape[key] }),
322
+ ])) })), [props]);
323
+ };
324
+
325
+ /*
326
+ * ----------------------------
327
+ * | SETUP TRANSLATIONS START |
328
+ * ----------------------------
329
+ * This import and function call is needed to register translations for this library.
330
+ * Do not remove this if this library has translations.
331
+ */
332
+ setupLibraryTranslations();
333
+
334
+ export { FormWizard, useFormWizard };
package/package.json ADDED
@@ -0,0 +1,22 @@
1
+ {
2
+ "name": "@trackunit/react-form-wizard",
3
+ "version": "0.0.2",
4
+ "repository": "https://github.com/Trackunit/manager",
5
+ "license": "SEE LICENSE IN LICENSE.txt",
6
+ "dependencies": {
7
+ "react": "^18.2.0",
8
+ "react-router-dom": "6.18.0",
9
+ "zod": "3.22.4",
10
+ "@trackunit/css-class-variance-utilities": "*",
11
+ "@trackunit/react-components": "*",
12
+ "@hookform/resolvers": "^3.3.4",
13
+ "react-hook-form": "7.40.0",
14
+ "@trackunit/i18n-library-translation": "*"
15
+ },
16
+ "engines": {
17
+ "node": ">=18.x",
18
+ "yarn": "3.7.0"
19
+ },
20
+ "module": "./index.esm.js",
21
+ "main": "./index.cjs.js"
22
+ }
@@ -0,0 +1,8 @@
1
+ /// <reference types="react" />
2
+ import { ZodTypeAny } from "zod";
3
+ import { ComponentStepDefinitions, FromWizardComponentProps } from "./useFormWizard";
4
+ /**
5
+ * The FormWizard component is used for forms in multiple steps.
6
+ * Use the useFormWizard hook to generate the props for this component.
7
+ */
8
+ export declare const FormWizard: <TFullSchema extends ZodTypeAny, TComponentStepDefinitions extends ComponentStepDefinitions<TFullSchema>>({ lastStepPrimaryActionLabel, steps, fullFormSchema, onCancel, className, dataTestId, basePath, }: FromWizardComponentProps<TFullSchema, TComponentStepDefinitions>) => JSX.Element;
@@ -0,0 +1,3 @@
1
+ export declare const cvaFormWizardContainer: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
2
+ export declare const cvaFormWizardLayout: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
3
+ export declare const cvaStepContainer: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
@@ -0,0 +1,44 @@
1
+ /// <reference types="react" />
2
+ import { CommonProps } from "@trackunit/react-components";
3
+ import { UseFormReturn } from "react-hook-form";
4
+ import { AnyZodObject, ZodTypeAny, z } from "zod";
5
+ export type StepState = "active" | "done" | "invalid" | "disabled" | "ready";
6
+ export type StepDefinitions<TFullSchema extends ZodTypeAny> = {
7
+ [KStepKey in keyof z.infer<TFullSchema>]: DefinedStep<z.infer<TFullSchema>[KStepKey], z.infer<TFullSchema>>;
8
+ };
9
+ export type StepComponentPropsInner<TStepSchema extends ZodTypeAny, TFullSchema extends ZodTypeAny> = {
10
+ form: UseFormReturn<TStepSchema>;
11
+ fullForm: UseFormReturn<TFullSchema>;
12
+ setSubmitHandler: ((onFinalSubmit: (fullFormState: TFullSchema) => void) => void) | null;
13
+ };
14
+ export interface SimpleStepProps {
15
+ title: string;
16
+ description: string;
17
+ sidebarDescription?: string;
18
+ path: string;
19
+ }
20
+ interface DefinedStep<TStepSchema extends ZodTypeAny, TFullSchema extends ZodTypeAny> extends SimpleStepProps {
21
+ component: (props: StepComponentPropsInner<TStepSchema, TFullSchema>) => React.ReactNode;
22
+ }
23
+ export type StepComponentProps<TFullSchemaHook extends () => ZodTypeAny, TStepKey extends keyof z.infer<ReturnType<TFullSchemaHook>>> = StepComponentPropsInner<z.infer<ReturnType<TFullSchemaHook>>[TStepKey], z.infer<ReturnType<TFullSchemaHook>>>;
24
+ export type ComponentStepDefinitions<TFullSchema extends ZodTypeAny> = {
25
+ [KStepKey in keyof z.infer<TFullSchema>]: DefinedComponentStep<z.infer<TFullSchema>[KStepKey], TFullSchema>;
26
+ };
27
+ interface DefinedComponentStep<TStepSchema extends ZodTypeAny, TFullSchema extends ZodTypeAny> extends DefinedStep<TStepSchema, TFullSchema> {
28
+ formSchema: TStepSchema;
29
+ }
30
+ export interface FromWizardComponentProps<TFullSchema extends ZodTypeAny, TComponentStepDefinitions extends ComponentStepDefinitions<TFullSchema>> extends Omit<UseFormWizardProps<TFullSchema, TComponentStepDefinitions>, "steps">, CommonProps {
31
+ steps: TComponentStepDefinitions;
32
+ }
33
+ export interface UseFormWizardProps<TFullSchema extends ZodTypeAny, TStepDefinitions extends StepDefinitions<TFullSchema>> {
34
+ fullFormSchema: TFullSchema;
35
+ lastStepPrimaryActionLabel: string;
36
+ onCancel?: () => void;
37
+ basePath: string;
38
+ steps: TStepDefinitions;
39
+ }
40
+ /**
41
+ *
42
+ */
43
+ export declare const useFormWizard: <TStepDefinition extends StepDefinitions<TFullSchema>, TFullSchema extends AnyZodObject>(props: UseFormWizardProps<TFullSchema, TStepDefinition>) => FromWizardComponentProps<TFullSchema, ComponentStepDefinitions<TFullSchema>>;
44
+ export {};
@@ -0,0 +1,14 @@
1
+ /// <reference types="react" />
2
+ import { CommonProps } from "@trackunit/react-components";
3
+ interface FormWizardFooterProps extends CommonProps {
4
+ primaryActionLabel?: string;
5
+ isValid?: boolean;
6
+ onCancel: () => void;
7
+ onBack: (() => void) | null;
8
+ }
9
+ /**
10
+ * The footer component for the FormWizard.
11
+ * In most cases you should not be using this component directly, but rather use the FormWizard component.
12
+ */
13
+ export declare const FormWizardFooter: ({ onBack, onCancel, isValid, primaryActionLabel }: FormWizardFooterProps) => JSX.Element;
14
+ export {};
@@ -0,0 +1,2 @@
1
+ export declare const cvaFooterContainer: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
2
+ export declare const cvaNavigationContainer: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
@@ -0,0 +1,12 @@
1
+ /// <reference types="react" />
2
+ import { CommonProps } from "@trackunit/react-components";
3
+ interface FormWizardHeaderProps extends CommonProps {
4
+ title: string;
5
+ description?: string;
6
+ }
7
+ /**
8
+ * The header component for the FormWizard.
9
+ * In most cases you should not be using this component directly, but rather use the FormWizard component.
10
+ */
11
+ export declare const FormWizardHeader: ({ title, description, className, dataTestId }: FormWizardHeaderProps) => JSX.Element;
12
+ export {};
@@ -0,0 +1 @@
1
+ export declare const cvaFormWizardHeader: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
@@ -0,0 +1,14 @@
1
+ import { CommonProps } from "@trackunit/react-components";
2
+ import { ReactNode } from "react";
3
+ interface FormWizardSidebarProps extends CommonProps {
4
+ /**
5
+ * Steps of the wizard.
6
+ */
7
+ children: ReactNode;
8
+ }
9
+ /**
10
+ * Displays the sidebar with steps for the wizard.
11
+ * Prefer using the FormWizard component instead of this directly.
12
+ */
13
+ export declare function FormWizardSidebar({ dataTestId, children, className }: FormWizardSidebarProps): JSX.Element;
14
+ export {};
@@ -0,0 +1,2 @@
1
+ export declare const cvaFillSection: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
2
+ export declare const cvaSidebar: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
@@ -0,0 +1,16 @@
1
+ /// <reference types="react" />
2
+ import { CommonProps } from "@trackunit/react-components";
3
+ import { StepState } from "../FormWizard/useFormWizard";
4
+ interface FormWizardSidebarStepProps extends CommonProps {
5
+ state: StepState;
6
+ stepNumber?: number;
7
+ title: string;
8
+ subTitle?: string;
9
+ path: string;
10
+ }
11
+ /**
12
+ * A sidebar step component used by the FormWizard component to render each step.
13
+ * This component is generally used internally by the FormWizard component.
14
+ */
15
+ export declare const FormWizardSidebarStep: ({ stepNumber, state, title, subTitle, path, dataTestId, }: FormWizardSidebarStepProps) => JSX.Element;
16
+ export {};
@@ -0,0 +1,12 @@
1
+ export declare const cvaFormWizardSidebarStep: (props?: ({
2
+ state?: "ready" | "active" | "done" | "invalid" | "disabled" | null | undefined;
3
+ } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
4
+ export declare const cvaSectionHeaderContainer: (props?: ({
5
+ cursor?: "default" | "withCursor" | null | undefined;
6
+ } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
7
+ export declare const cvaHeader: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
8
+ export declare const cvaSubtitle: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
9
+ export declare const cvaStepNumber: (props?: ({
10
+ state?: "ready" | "active" | "done" | "invalid" | "disabled" | null | undefined;
11
+ } & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
12
+ export declare const cvaTitleAndDescription: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
@@ -0,0 +1,23 @@
1
+ import { Dispatch, SetStateAction } from "react";
2
+ import { ZodTypeAny, z } from "zod";
3
+ import { SimpleStepProps, StepComponentPropsInner, StepState } from "../FormWizard/useFormWizard";
4
+ export interface FormWizardStepWrapperProps<TStepKey extends keyof z.infer<TFullSchema>, TFullSchema extends ZodTypeAny> extends SimpleStepProps {
5
+ description: string;
6
+ lastStepPrimaryActionLabel: string;
7
+ nextStepPath: string | null;
8
+ basePath: string;
9
+ previousStepPath: string | null;
10
+ onCancel?: () => void;
11
+ fullFormSchema: TFullSchema;
12
+ fullFormState: z.TypeOf<TFullSchema>;
13
+ setFullFormState: Dispatch<SetStateAction<Partial<z.TypeOf<TFullSchema>>>>;
14
+ stepKey: TStepKey;
15
+ formSchema: z.infer<TFullSchema>[TStepKey];
16
+ setStepStates: Dispatch<SetStateAction<Partial<Record<TStepKey, StepState>>>>;
17
+ component: (props: StepComponentPropsInner<z.infer<TFullSchema>[TStepKey], TFullSchema>) => React.ReactNode;
18
+ }
19
+ /**
20
+ * A wrapper component used by the FormWizard component to render each step.
21
+ * In most cases you should not be using this component directly, but rather use the FormWizard component.
22
+ */
23
+ export declare const FormWizardStepWrapper: <TFullSchema extends ZodTypeAny, TStepKey extends keyof z.TypeOf<TFullSchema>>({ stepKey, onCancel, description, title, component, formSchema, nextStepPath, previousStepPath, lastStepPrimaryActionLabel, fullFormSchema, setFullFormState, fullFormState, setStepStates, basePath, }: FormWizardStepWrapperProps<TStepKey, TFullSchema>) => JSX.Element;
@@ -0,0 +1,2 @@
1
+ export declare const cvaFormWizardComponentContainer: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
2
+ export declare const cvaFormWizardComponentStepForm: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
package/src/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./FormWizard/FormWizard";
2
+ export * from "./FormWizard/useFormWizard";
@@ -0,0 +1,34 @@
1
+ /// <reference types="react" />
2
+ import { NamespaceTransProps, TransForLibs, TranslationResource } from "@trackunit/i18n-library-translation";
3
+ import defaultTranslations from "./locales/en/translation.json";
4
+ /** A type for all available translation keys in this library */
5
+ export type TranslationKeys = keyof typeof defaultTranslations;
6
+ /** The translation namespace for this library */
7
+ export declare const namespace = "react.form-wizard";
8
+ /**
9
+ * The TranslationResource for this Library.
10
+ * Holds lazy loaded imports for all languages supported by the library.
11
+ *
12
+ * This is used to register the translations for this library before initializing i18next.
13
+ */
14
+ export declare const translations: TranslationResource<TranslationKeys>;
15
+ /**
16
+ * Local useTranslation for this specific library
17
+ */
18
+ export declare const useTranslation: () => [TransForLibs<never>, import("i18next").i18n, boolean] & {
19
+ t: TransForLibs<never>;
20
+ i18n: import("i18next").i18n;
21
+ ready: boolean;
22
+ };
23
+ /**
24
+ * Type of the t function for the local useTranslation for this specific library
25
+ */
26
+ export type TranslationFunction = TransForLibs<TranslationKeys>;
27
+ /**
28
+ * Trans for this specific library.
29
+ */
30
+ export declare const Trans: (props: NamespaceTransProps<TranslationKeys>) => JSX.Element;
31
+ /**
32
+ * Registers the translations for this library
33
+ */
34
+ export declare const setupLibraryTranslations: () => void;
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ var translation = {
4
+
5
+ };
6
+
7
+ exports["default"] = translation;
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ var translation = {
4
+
5
+ };
6
+
7
+ exports["default"] = translation;
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ var translation = {
4
+
5
+ };
6
+
7
+ exports["default"] = translation;
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ var translation = {
4
+
5
+ };
6
+
7
+ exports["default"] = translation;
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ var translation = {
4
+
5
+ };
6
+
7
+ exports["default"] = translation;
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ var translation = {
4
+
5
+ };
6
+
7
+ exports["default"] = translation;
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ var translation = {
4
+
5
+ };
6
+
7
+ exports["default"] = translation;
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ var translation = {
4
+
5
+ };
6
+
7
+ exports["default"] = translation;
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ var translation = {
4
+
5
+ };
6
+
7
+ exports["default"] = translation;
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ var translation = {
4
+
5
+ };
6
+
7
+ exports["default"] = translation;
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ var translation = {
4
+
5
+ };
6
+
7
+ exports["default"] = translation;
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ var translation = {
4
+
5
+ };
6
+
7
+ exports["default"] = translation;
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ var translation = {
4
+
5
+ };
6
+
7
+ exports["default"] = translation;
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ var translation = {
4
+
5
+ };
6
+
7
+ exports["default"] = translation;
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ var translation = {
4
+
5
+ };
6
+
7
+ exports["default"] = translation;
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ var translation = {
4
+
5
+ };
6
+
7
+ exports["default"] = translation;
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ var translation = {
4
+
5
+ };
6
+
7
+ exports["default"] = translation;
@@ -0,0 +1,5 @@
1
+ var translation = {
2
+
3
+ };
4
+
5
+ export { translation as default };
@@ -0,0 +1,5 @@
1
+ var translation = {
2
+
3
+ };
4
+
5
+ export { translation as default };
@@ -0,0 +1,5 @@
1
+ var translation = {
2
+
3
+ };
4
+
5
+ export { translation as default };
@@ -0,0 +1,5 @@
1
+ var translation = {
2
+
3
+ };
4
+
5
+ export { translation as default };
@@ -0,0 +1,5 @@
1
+ var translation = {
2
+
3
+ };
4
+
5
+ export { translation as default };
@@ -0,0 +1,5 @@
1
+ var translation = {
2
+
3
+ };
4
+
5
+ export { translation as default };
@@ -0,0 +1,5 @@
1
+ var translation = {
2
+
3
+ };
4
+
5
+ export { translation as default };
@@ -0,0 +1,5 @@
1
+ var translation = {
2
+
3
+ };
4
+
5
+ export { translation as default };
@@ -0,0 +1,5 @@
1
+ var translation = {
2
+
3
+ };
4
+
5
+ export { translation as default };
@@ -0,0 +1,5 @@
1
+ var translation = {
2
+
3
+ };
4
+
5
+ export { translation as default };
@@ -0,0 +1,5 @@
1
+ var translation = {
2
+
3
+ };
4
+
5
+ export { translation as default };
@@ -0,0 +1,5 @@
1
+ var translation = {
2
+
3
+ };
4
+
5
+ export { translation as default };
@@ -0,0 +1,5 @@
1
+ var translation = {
2
+
3
+ };
4
+
5
+ export { translation as default };
@@ -0,0 +1,5 @@
1
+ var translation = {
2
+
3
+ };
4
+
5
+ export { translation as default };
@@ -0,0 +1,5 @@
1
+ var translation = {
2
+
3
+ };
4
+
5
+ export { translation as default };
@@ -0,0 +1,5 @@
1
+ var translation = {
2
+
3
+ };
4
+
5
+ export { translation as default };
@@ -0,0 +1,5 @@
1
+ var translation = {
2
+
3
+ };
4
+
5
+ export { translation as default };