@algodomain/smart-forms 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +313 -0
- package/dist/SmartFormProvider-B-BTl4wO.d.cts +94 -0
- package/dist/SmartFormProvider-B-BTl4wO.d.ts +94 -0
- package/dist/SmartTags-HmvmCJPT.d.cts +111 -0
- package/dist/SmartTags-HmvmCJPT.d.ts +111 -0
- package/dist/chunk-6WAEAWTD.js +949 -0
- package/dist/chunk-6WAEAWTD.js.map +1 -0
- package/dist/chunk-IG4XDQMV.js +604 -0
- package/dist/chunk-IG4XDQMV.js.map +1 -0
- package/dist/chunk-Y6NGPMDH.cjs +982 -0
- package/dist/chunk-Y6NGPMDH.cjs.map +1 -0
- package/dist/chunk-YV7RVYMD.cjs +639 -0
- package/dist/chunk-YV7RVYMD.cjs.map +1 -0
- package/dist/fields.cjs +1445 -0
- package/dist/fields.cjs.map +1 -0
- package/dist/fields.d.cts +119 -0
- package/dist/fields.d.ts +119 -0
- package/dist/fields.js +1384 -0
- package/dist/fields.js.map +1 -0
- package/dist/index.cjs +906 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +165 -0
- package/dist/index.d.ts +165 -0
- package/dist/index.js +821 -0
- package/dist/index.js.map +1 -0
- package/dist/opinionated.cjs +408 -0
- package/dist/opinionated.cjs.map +1 -0
- package/dist/opinionated.d.cts +274 -0
- package/dist/opinionated.d.ts +274 -0
- package/dist/opinionated.js +382 -0
- package/dist/opinionated.js.map +1 -0
- package/dist/style.css +114 -0
- package/package.json +90 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,906 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkY6NGPMDH_cjs = require('./chunk-Y6NGPMDH.cjs');
|
|
4
|
+
var chunkYV7RVYMD_cjs = require('./chunk-YV7RVYMD.cjs');
|
|
5
|
+
var React3 = require('react');
|
|
6
|
+
var reactToastify = require('react-toastify');
|
|
7
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
8
|
+
var lucideReact = require('lucide-react');
|
|
9
|
+
var zod = require('zod');
|
|
10
|
+
var TabsPrimitive = require('@radix-ui/react-tabs');
|
|
11
|
+
|
|
12
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
13
|
+
|
|
14
|
+
function _interopNamespace(e) {
|
|
15
|
+
if (e && e.__esModule) return e;
|
|
16
|
+
var n = Object.create(null);
|
|
17
|
+
if (e) {
|
|
18
|
+
Object.keys(e).forEach(function (k) {
|
|
19
|
+
if (k !== 'default') {
|
|
20
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
21
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
22
|
+
enumerable: true,
|
|
23
|
+
get: function () { return e[k]; }
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
n.default = e;
|
|
29
|
+
return Object.freeze(n);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
var React3__default = /*#__PURE__*/_interopDefault(React3);
|
|
33
|
+
var TabsPrimitive__namespace = /*#__PURE__*/_interopNamespace(TabsPrimitive);
|
|
34
|
+
|
|
35
|
+
var ToastContainerWrapper = () => /* @__PURE__ */ jsxRuntime.jsx(
|
|
36
|
+
reactToastify.ToastContainer,
|
|
37
|
+
{
|
|
38
|
+
position: "top-center",
|
|
39
|
+
autoClose: 2e3,
|
|
40
|
+
newestOnTop: false,
|
|
41
|
+
closeOnClick: true,
|
|
42
|
+
rtl: false,
|
|
43
|
+
pauseOnFocusLoss: true,
|
|
44
|
+
draggable: true,
|
|
45
|
+
pauseOnHover: true,
|
|
46
|
+
theme: "light",
|
|
47
|
+
transition: reactToastify.Bounce
|
|
48
|
+
}
|
|
49
|
+
);
|
|
50
|
+
var FormHeader = ({ title, subTitle, logo }) => {
|
|
51
|
+
if (!title && !subTitle && !logo) return null;
|
|
52
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-4 border-b border-gray-200 pb-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-center space-x-4", children: [
|
|
53
|
+
logo && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-shrink-0", children: logo }),
|
|
54
|
+
(title || subTitle) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: logo ? "text-left" : "text-center", children: [
|
|
55
|
+
title && /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-xl font-bold text-gray-800", children: title }),
|
|
56
|
+
subTitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground text-sm", children: subTitle })
|
|
57
|
+
] })
|
|
58
|
+
] }) });
|
|
59
|
+
};
|
|
60
|
+
var Section = ({ text }) => {
|
|
61
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative my-6", children: [
|
|
62
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 flex items-center", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full border-t border-gray-300" }) }),
|
|
63
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative flex justify-center text-sm", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "bg-white px-2 text-gray-500", children: text }) })
|
|
64
|
+
] });
|
|
65
|
+
};
|
|
66
|
+
var Footer = ({ children, className = "" }) => {
|
|
67
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `mt-4 pt-4 border-t border-gray-200 ${className}`, children });
|
|
68
|
+
};
|
|
69
|
+
var BaseSmartForm = ({
|
|
70
|
+
children,
|
|
71
|
+
api,
|
|
72
|
+
method = "POST",
|
|
73
|
+
submitButtonText = "Submit",
|
|
74
|
+
submitButtonIcon,
|
|
75
|
+
allowSaveDraft = false,
|
|
76
|
+
saveDraftApi,
|
|
77
|
+
enableLocalStorage = false,
|
|
78
|
+
storageKey,
|
|
79
|
+
logFormData = false,
|
|
80
|
+
onSuccess,
|
|
81
|
+
onError,
|
|
82
|
+
transformData,
|
|
83
|
+
className = "max-w-2xl mx-auto p-6 bg-white",
|
|
84
|
+
title,
|
|
85
|
+
subTitle,
|
|
86
|
+
logo,
|
|
87
|
+
footer,
|
|
88
|
+
initialData = {},
|
|
89
|
+
showReset = false,
|
|
90
|
+
showProgressBar = true,
|
|
91
|
+
showTabNumbers = true,
|
|
92
|
+
authentication
|
|
93
|
+
}) => {
|
|
94
|
+
const config = {
|
|
95
|
+
api,
|
|
96
|
+
method,
|
|
97
|
+
submitButtonText,
|
|
98
|
+
submitButtonIcon,
|
|
99
|
+
allowSaveDraft,
|
|
100
|
+
saveDraftApi,
|
|
101
|
+
enableLocalStorage,
|
|
102
|
+
storageKey,
|
|
103
|
+
logFormData,
|
|
104
|
+
onSuccess,
|
|
105
|
+
onError,
|
|
106
|
+
transformData,
|
|
107
|
+
className,
|
|
108
|
+
title,
|
|
109
|
+
subTitle,
|
|
110
|
+
logo,
|
|
111
|
+
footer,
|
|
112
|
+
showReset,
|
|
113
|
+
showProgressBar,
|
|
114
|
+
showTabNumbers,
|
|
115
|
+
authentication
|
|
116
|
+
};
|
|
117
|
+
return /* @__PURE__ */ jsxRuntime.jsx(chunkYV7RVYMD_cjs.SmartFormProvider, { config, initialData, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className, children: [
|
|
118
|
+
/* @__PURE__ */ jsxRuntime.jsx(ToastContainerWrapper, {}),
|
|
119
|
+
/* @__PURE__ */ jsxRuntime.jsx(FormHeader, { title, subTitle, logo }),
|
|
120
|
+
children,
|
|
121
|
+
footer && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 pt-4 border-t border-gray-200", children: footer })
|
|
122
|
+
] }) });
|
|
123
|
+
};
|
|
124
|
+
var LoadingSpinner = ({ className = "h-4 w-4" }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: `animate-spin rounded-full border-b-2 border-current ${className}` });
|
|
125
|
+
var SubmitButton = ({ onClick, disabled, children, className }) => /* @__PURE__ */ jsxRuntime.jsx(chunkY6NGPMDH_cjs.Button, { onClick, disabled, className, children: disabled ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
126
|
+
/* @__PURE__ */ jsxRuntime.jsx(LoadingSpinner, {}),
|
|
127
|
+
"Submitting..."
|
|
128
|
+
] }) : children });
|
|
129
|
+
var DraftSaveButton = ({ onClick, disabled }) => /* @__PURE__ */ jsxRuntime.jsx(chunkY6NGPMDH_cjs.Button, { onClick, disabled, variant: "secondary", children: disabled ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
130
|
+
/* @__PURE__ */ jsxRuntime.jsx(LoadingSpinner, {}),
|
|
131
|
+
"Saving..."
|
|
132
|
+
] }) : "Save Draft" });
|
|
133
|
+
var ResetButton = ({ onClick }) => /* @__PURE__ */ jsxRuntime.jsx(chunkY6NGPMDH_cjs.Button, { onClick, variant: "secondary", children: "Reset Form" });
|
|
134
|
+
var NavigationButtons = ({
|
|
135
|
+
onPrevious,
|
|
136
|
+
onNext,
|
|
137
|
+
onSubmit,
|
|
138
|
+
onSaveDraft,
|
|
139
|
+
onReset,
|
|
140
|
+
isLoading,
|
|
141
|
+
isDraftSaving,
|
|
142
|
+
config,
|
|
143
|
+
isFirstTab = false,
|
|
144
|
+
isLastTab = false
|
|
145
|
+
}) => {
|
|
146
|
+
const hasResetButton = !!onReset;
|
|
147
|
+
const hasDraftButton = config.allowSaveDraft && !!onSaveDraft;
|
|
148
|
+
const hasSubmitOrNextButton = isLastTab || !!onNext;
|
|
149
|
+
const rightSectionButtons = [hasResetButton, hasDraftButton, hasSubmitOrNextButton].filter(Boolean).length;
|
|
150
|
+
const hasPreviousButton = !!onPrevious;
|
|
151
|
+
const isSingleButton = rightSectionButtons === 1 && !hasPreviousButton;
|
|
152
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between items-center mt-8 pt-6 border-t border-gray-200", children: [
|
|
153
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-4", children: onPrevious && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
154
|
+
chunkY6NGPMDH_cjs.Button,
|
|
155
|
+
{
|
|
156
|
+
onClick: onPrevious,
|
|
157
|
+
disabled: isFirstTab,
|
|
158
|
+
variant: "secondary",
|
|
159
|
+
children: [
|
|
160
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { className: "h-4 w-4" }),
|
|
161
|
+
"Previous"
|
|
162
|
+
]
|
|
163
|
+
}
|
|
164
|
+
) }),
|
|
165
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: isSingleButton ? "w-full" : "flex gap-4", children: [
|
|
166
|
+
onReset && /* @__PURE__ */ jsxRuntime.jsx(ResetButton, { onClick: onReset }),
|
|
167
|
+
config.allowSaveDraft && onSaveDraft && /* @__PURE__ */ jsxRuntime.jsx(DraftSaveButton, { onClick: onSaveDraft, disabled: isDraftSaving }),
|
|
168
|
+
isLastTab ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
169
|
+
SubmitButton,
|
|
170
|
+
{
|
|
171
|
+
onClick: onSubmit,
|
|
172
|
+
disabled: isLoading,
|
|
173
|
+
className: isSingleButton ? "w-full" : "",
|
|
174
|
+
children: [
|
|
175
|
+
config.submitButtonIcon,
|
|
176
|
+
config.submitButtonText || "Submit"
|
|
177
|
+
]
|
|
178
|
+
}
|
|
179
|
+
) : onNext && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
180
|
+
chunkY6NGPMDH_cjs.Button,
|
|
181
|
+
{
|
|
182
|
+
onClick: onNext,
|
|
183
|
+
className: isSingleButton ? "w-full" : "",
|
|
184
|
+
children: [
|
|
185
|
+
"Next",
|
|
186
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRight, { className: "h-4 w-4" })
|
|
187
|
+
]
|
|
188
|
+
}
|
|
189
|
+
)
|
|
190
|
+
] })
|
|
191
|
+
] });
|
|
192
|
+
};
|
|
193
|
+
var SimpleFormButtons = ({
|
|
194
|
+
onSubmit,
|
|
195
|
+
onSaveDraft,
|
|
196
|
+
onReset,
|
|
197
|
+
isLoading,
|
|
198
|
+
isDraftSaving,
|
|
199
|
+
config
|
|
200
|
+
}) => {
|
|
201
|
+
const hasResetButton = !!onReset;
|
|
202
|
+
const hasDraftButton = config.allowSaveDraft && !!onSaveDraft;
|
|
203
|
+
const hasSubmitButton = true;
|
|
204
|
+
const totalButtons = [hasResetButton, hasDraftButton, hasSubmitButton].filter(Boolean).length;
|
|
205
|
+
const isSingleButton = totalButtons === 1;
|
|
206
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-end mt-8 pt-6 border-t border-gray-200", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: isSingleButton ? "w-full" : "flex gap-4", children: [
|
|
207
|
+
onReset && /* @__PURE__ */ jsxRuntime.jsx(ResetButton, { onClick: onReset }),
|
|
208
|
+
config.allowSaveDraft && onSaveDraft && /* @__PURE__ */ jsxRuntime.jsx(DraftSaveButton, { onClick: onSaveDraft, disabled: isDraftSaving }),
|
|
209
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
210
|
+
SubmitButton,
|
|
211
|
+
{
|
|
212
|
+
onClick: onSubmit,
|
|
213
|
+
disabled: isLoading,
|
|
214
|
+
className: isSingleButton ? "w-full" : "",
|
|
215
|
+
children: [
|
|
216
|
+
config.submitButtonIcon,
|
|
217
|
+
config.submitButtonText || "Submit"
|
|
218
|
+
]
|
|
219
|
+
}
|
|
220
|
+
)
|
|
221
|
+
] }) });
|
|
222
|
+
};
|
|
223
|
+
var SubmitButton2 = () => {
|
|
224
|
+
const { isLoading, isDraftSaving, submitForm, saveDraft, resetForm, config } = chunkYV7RVYMD_cjs.useSmartForm();
|
|
225
|
+
const shouldShowReset = config.showReset || config.enableLocalStorage;
|
|
226
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
227
|
+
SimpleFormButtons,
|
|
228
|
+
{
|
|
229
|
+
onSubmit: submitForm,
|
|
230
|
+
onSaveDraft: config.allowSaveDraft ? saveDraft : void 0,
|
|
231
|
+
onReset: shouldShowReset ? resetForm : void 0,
|
|
232
|
+
isLoading,
|
|
233
|
+
isDraftSaving,
|
|
234
|
+
config
|
|
235
|
+
}
|
|
236
|
+
);
|
|
237
|
+
};
|
|
238
|
+
var SmartForm = (props) => {
|
|
239
|
+
const { children, ...otherProps } = props;
|
|
240
|
+
const childArray = React3__default.default.Children.toArray(children);
|
|
241
|
+
const footerChildren = [];
|
|
242
|
+
const regularChildren = [];
|
|
243
|
+
childArray.forEach((child) => {
|
|
244
|
+
if (React3.isValidElement(child) && child.type === Footer) {
|
|
245
|
+
footerChildren.push(child);
|
|
246
|
+
} else {
|
|
247
|
+
regularChildren.push(child);
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(BaseSmartForm, { ...otherProps, children: [
|
|
251
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-6", children: regularChildren }),
|
|
252
|
+
/* @__PURE__ */ jsxRuntime.jsx(SubmitButton2, {}),
|
|
253
|
+
footerChildren.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-4", children: footerChildren })
|
|
254
|
+
] });
|
|
255
|
+
};
|
|
256
|
+
function Tabs({
|
|
257
|
+
className,
|
|
258
|
+
...props
|
|
259
|
+
}) {
|
|
260
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
261
|
+
TabsPrimitive__namespace.Root,
|
|
262
|
+
{
|
|
263
|
+
"data-slot": "tabs",
|
|
264
|
+
className: chunkYV7RVYMD_cjs.cn("flex flex-col gap-2", className),
|
|
265
|
+
...props
|
|
266
|
+
}
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
function TabsList({
|
|
270
|
+
className,
|
|
271
|
+
...props
|
|
272
|
+
}) {
|
|
273
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
274
|
+
TabsPrimitive__namespace.List,
|
|
275
|
+
{
|
|
276
|
+
"data-slot": "tabs-list",
|
|
277
|
+
className: chunkYV7RVYMD_cjs.cn(
|
|
278
|
+
"bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]",
|
|
279
|
+
className
|
|
280
|
+
),
|
|
281
|
+
...props
|
|
282
|
+
}
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
function TabsTrigger({
|
|
286
|
+
className,
|
|
287
|
+
...props
|
|
288
|
+
}) {
|
|
289
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
290
|
+
TabsPrimitive__namespace.Trigger,
|
|
291
|
+
{
|
|
292
|
+
"data-slot": "tabs-trigger",
|
|
293
|
+
className: chunkYV7RVYMD_cjs.cn(
|
|
294
|
+
"data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap transition-[color,box-shadow] focus-visible:ring-[3px] focus-visible:outline-1 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
|
|
295
|
+
className
|
|
296
|
+
),
|
|
297
|
+
...props
|
|
298
|
+
}
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
function TabsContent({
|
|
302
|
+
className,
|
|
303
|
+
...props
|
|
304
|
+
}) {
|
|
305
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
306
|
+
TabsPrimitive__namespace.Content,
|
|
307
|
+
{
|
|
308
|
+
"data-slot": "tabs-content",
|
|
309
|
+
className: chunkYV7RVYMD_cjs.cn("flex-1 outline-none", className),
|
|
310
|
+
...props
|
|
311
|
+
}
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
var TabIndexContext = React3__default.default.createContext(null);
|
|
315
|
+
var useTabIndex = () => {
|
|
316
|
+
const context = React3.useContext(TabIndexContext);
|
|
317
|
+
return context;
|
|
318
|
+
};
|
|
319
|
+
var TabIndexProvider = ({
|
|
320
|
+
children,
|
|
321
|
+
tabIndex
|
|
322
|
+
}) => {
|
|
323
|
+
return /* @__PURE__ */ jsxRuntime.jsx(TabIndexContext.Provider, { value: { tabIndex }, children });
|
|
324
|
+
};
|
|
325
|
+
var ExternalFormContext = React3.createContext(null);
|
|
326
|
+
var Tab = ({ children }) => {
|
|
327
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
|
|
328
|
+
};
|
|
329
|
+
var NavigationButtonsWrapper = ({
|
|
330
|
+
activeTab,
|
|
331
|
+
totalTabs,
|
|
332
|
+
onPrevious,
|
|
333
|
+
onNext,
|
|
334
|
+
onSubmit,
|
|
335
|
+
onSaveDraft,
|
|
336
|
+
onReset,
|
|
337
|
+
isLoading,
|
|
338
|
+
isDraftSaving,
|
|
339
|
+
config
|
|
340
|
+
}) => {
|
|
341
|
+
const isLastTab = activeTab === totalTabs - 1;
|
|
342
|
+
const isFirstTab = activeTab === 0;
|
|
343
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
344
|
+
NavigationButtons,
|
|
345
|
+
{
|
|
346
|
+
onPrevious,
|
|
347
|
+
onNext,
|
|
348
|
+
onSubmit,
|
|
349
|
+
onSaveDraft,
|
|
350
|
+
onReset,
|
|
351
|
+
isLoading,
|
|
352
|
+
isDraftSaving,
|
|
353
|
+
config,
|
|
354
|
+
isFirstTab,
|
|
355
|
+
isLastTab
|
|
356
|
+
}
|
|
357
|
+
);
|
|
358
|
+
};
|
|
359
|
+
var MultiTabSmartForm = ({
|
|
360
|
+
children,
|
|
361
|
+
showProgressBar = true,
|
|
362
|
+
showTabNumbers = true,
|
|
363
|
+
...baseProps
|
|
364
|
+
}) => {
|
|
365
|
+
const [activeTab, setActiveTab] = React3.useState(0);
|
|
366
|
+
const [tabFields, setTabFields] = React3.useState([]);
|
|
367
|
+
const [completedTabs, setCompletedTabs] = React3.useState(/* @__PURE__ */ new Set());
|
|
368
|
+
const [validationErrorTabs, setValidationErrorTabs] = React3.useState(/* @__PURE__ */ new Set());
|
|
369
|
+
const [externalTabFields, setExternalTabFields] = React3.useState({});
|
|
370
|
+
const { footerChildren, regularChildren } = React3.useMemo(() => {
|
|
371
|
+
const childArray = React3__default.default.Children.toArray(children);
|
|
372
|
+
const footerChildren2 = [];
|
|
373
|
+
const regularChildren2 = [];
|
|
374
|
+
childArray.forEach((child) => {
|
|
375
|
+
if (React3.isValidElement(child) && child.type === Footer) {
|
|
376
|
+
footerChildren2.push(child);
|
|
377
|
+
} else {
|
|
378
|
+
regularChildren2.push(child);
|
|
379
|
+
}
|
|
380
|
+
});
|
|
381
|
+
return { footerChildren: footerChildren2, regularChildren: regularChildren2 };
|
|
382
|
+
}, [children]);
|
|
383
|
+
const tabs = [];
|
|
384
|
+
React3__default.default.Children.forEach(regularChildren, (child) => {
|
|
385
|
+
if (React3__default.default.isValidElement(child) && child.type === Tab) {
|
|
386
|
+
const props = child.props;
|
|
387
|
+
if (props.title) {
|
|
388
|
+
tabs.push(props.title);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
});
|
|
392
|
+
const findSmartInputs = React3.useCallback((children2) => {
|
|
393
|
+
const fields = [];
|
|
394
|
+
React3__default.default.Children.forEach(children2, (child) => {
|
|
395
|
+
if (React3__default.default.isValidElement(child)) {
|
|
396
|
+
const fieldProps = child.props;
|
|
397
|
+
if (fieldProps && typeof fieldProps === "object" && "field" in fieldProps && fieldProps.field) {
|
|
398
|
+
fields.push(fieldProps.field);
|
|
399
|
+
} else if (child.props && typeof child.props === "object" && "children" in child.props) {
|
|
400
|
+
const nestedFields = findSmartInputs(child.props.children);
|
|
401
|
+
fields.push(...nestedFields);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
return fields;
|
|
406
|
+
}, []);
|
|
407
|
+
const registerTabFields = React3.useCallback((tabIndex, fields) => {
|
|
408
|
+
setExternalTabFields((prev) => ({
|
|
409
|
+
...prev,
|
|
410
|
+
[tabIndex]: fields
|
|
411
|
+
}));
|
|
412
|
+
}, []);
|
|
413
|
+
React3__default.default.useEffect(() => {
|
|
414
|
+
const fields = [];
|
|
415
|
+
React3__default.default.Children.forEach(regularChildren, (child) => {
|
|
416
|
+
if (React3__default.default.isValidElement(child) && child.type === Tab) {
|
|
417
|
+
const tabFieldsInTab = findSmartInputs(child.props.children);
|
|
418
|
+
fields.push(tabFieldsInTab);
|
|
419
|
+
}
|
|
420
|
+
});
|
|
421
|
+
setTabFields(fields);
|
|
422
|
+
}, [regularChildren, findSmartInputs]);
|
|
423
|
+
const getCombinedTabFields = React3.useCallback((tabIndex) => {
|
|
424
|
+
const internalFields = tabFields[tabIndex] || [];
|
|
425
|
+
const externalFields = externalTabFields[tabIndex] || [];
|
|
426
|
+
return [...internalFields, ...externalFields];
|
|
427
|
+
}, [tabFields, externalTabFields]);
|
|
428
|
+
const config = {
|
|
429
|
+
...baseProps,
|
|
430
|
+
showProgressBar,
|
|
431
|
+
showTabNumbers
|
|
432
|
+
};
|
|
433
|
+
const handleTabChange = React3.useCallback((index) => {
|
|
434
|
+
setActiveTab(index);
|
|
435
|
+
}, []);
|
|
436
|
+
const handlePrevious = React3.useCallback(() => {
|
|
437
|
+
if (activeTab > 0) {
|
|
438
|
+
setActiveTab(activeTab - 1);
|
|
439
|
+
}
|
|
440
|
+
}, [activeTab]);
|
|
441
|
+
const handleNext = React3.useCallback(() => {
|
|
442
|
+
if (activeTab < tabs.length - 1) {
|
|
443
|
+
setActiveTab(activeTab + 1);
|
|
444
|
+
}
|
|
445
|
+
}, [activeTab, tabs.length]);
|
|
446
|
+
const externalFormContextValue = React3.useMemo(() => ({
|
|
447
|
+
registerTabFields,
|
|
448
|
+
currentTabIndex: activeTab
|
|
449
|
+
}), [registerTabFields, activeTab]);
|
|
450
|
+
return /* @__PURE__ */ jsxRuntime.jsx(BaseSmartForm, { ...baseProps, children: /* @__PURE__ */ jsxRuntime.jsx(ExternalFormContext.Provider, { value: externalFormContextValue, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
451
|
+
MultiTabFormContent,
|
|
452
|
+
{
|
|
453
|
+
activeTab,
|
|
454
|
+
tabs,
|
|
455
|
+
getCombinedTabFields,
|
|
456
|
+
config,
|
|
457
|
+
onTabChange: handleTabChange,
|
|
458
|
+
onPrevious: handlePrevious,
|
|
459
|
+
onNext: handleNext,
|
|
460
|
+
completedTabs,
|
|
461
|
+
setCompletedTabs,
|
|
462
|
+
validationErrorTabs,
|
|
463
|
+
setValidationErrorTabs,
|
|
464
|
+
footerChildren,
|
|
465
|
+
children: regularChildren
|
|
466
|
+
}
|
|
467
|
+
) }) });
|
|
468
|
+
};
|
|
469
|
+
var MultiTabFormContent = ({
|
|
470
|
+
activeTab,
|
|
471
|
+
tabs,
|
|
472
|
+
getCombinedTabFields,
|
|
473
|
+
config,
|
|
474
|
+
onTabChange,
|
|
475
|
+
onPrevious,
|
|
476
|
+
onNext,
|
|
477
|
+
completedTabs,
|
|
478
|
+
setCompletedTabs,
|
|
479
|
+
validationErrorTabs,
|
|
480
|
+
setValidationErrorTabs,
|
|
481
|
+
footerChildren,
|
|
482
|
+
children
|
|
483
|
+
}) => {
|
|
484
|
+
const { isLoading, isDraftSaving, submitForm, saveDraft, resetForm, validateFields, formData, validationRegistry, setErrors } = chunkYV7RVYMD_cjs.useSmartForm();
|
|
485
|
+
const [maxContentHeight, setMaxContentHeight] = React3.useState(0);
|
|
486
|
+
const contentRefs = React3.useRef([]);
|
|
487
|
+
const debounce = (func, wait) => {
|
|
488
|
+
let timeout;
|
|
489
|
+
return function executedFunction(...args) {
|
|
490
|
+
const later = () => {
|
|
491
|
+
clearTimeout(timeout);
|
|
492
|
+
func(...args);
|
|
493
|
+
};
|
|
494
|
+
clearTimeout(timeout);
|
|
495
|
+
timeout = setTimeout(later, wait);
|
|
496
|
+
};
|
|
497
|
+
};
|
|
498
|
+
React3__default.default.useEffect(() => {
|
|
499
|
+
const calculateMaxHeight = () => {
|
|
500
|
+
let maxHeight = 0;
|
|
501
|
+
contentRefs.current.forEach((ref) => {
|
|
502
|
+
if (ref) {
|
|
503
|
+
const height = ref.scrollHeight;
|
|
504
|
+
maxHeight = Math.max(maxHeight, height);
|
|
505
|
+
}
|
|
506
|
+
});
|
|
507
|
+
if (maxHeight > 0) {
|
|
508
|
+
setMaxContentHeight(maxHeight);
|
|
509
|
+
}
|
|
510
|
+
};
|
|
511
|
+
const timeoutId = setTimeout(calculateMaxHeight, 100);
|
|
512
|
+
window.addEventListener("resize", calculateMaxHeight);
|
|
513
|
+
return () => {
|
|
514
|
+
clearTimeout(timeoutId);
|
|
515
|
+
window.removeEventListener("resize", calculateMaxHeight);
|
|
516
|
+
};
|
|
517
|
+
}, [children, activeTab]);
|
|
518
|
+
React3__default.default.useEffect(() => {
|
|
519
|
+
const checkTabCompletion = debounce(() => {
|
|
520
|
+
tabs.forEach((_, tabIndex) => {
|
|
521
|
+
const tabFieldsInTab = getCombinedTabFields(tabIndex);
|
|
522
|
+
if (tabFieldsInTab.length === 0) {
|
|
523
|
+
setCompletedTabs((prev) => {
|
|
524
|
+
const newSet = new Set(prev);
|
|
525
|
+
newSet.delete(tabIndex);
|
|
526
|
+
return newSet;
|
|
527
|
+
});
|
|
528
|
+
return;
|
|
529
|
+
}
|
|
530
|
+
let allFieldsValid = true;
|
|
531
|
+
let hasAnyValue = false;
|
|
532
|
+
for (const field of tabFieldsInTab) {
|
|
533
|
+
const validation = validationRegistry[field];
|
|
534
|
+
const fieldValue = formData[field];
|
|
535
|
+
if (fieldValue !== void 0 && fieldValue !== null && fieldValue !== "") {
|
|
536
|
+
hasAnyValue = true;
|
|
537
|
+
}
|
|
538
|
+
if (validation) {
|
|
539
|
+
try {
|
|
540
|
+
validation.parse(fieldValue);
|
|
541
|
+
} catch (error) {
|
|
542
|
+
if (error instanceof zod.z.ZodError) {
|
|
543
|
+
allFieldsValid = false;
|
|
544
|
+
break;
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
if (hasAnyValue && allFieldsValid) {
|
|
550
|
+
setCompletedTabs((prev) => /* @__PURE__ */ new Set([...prev, tabIndex]));
|
|
551
|
+
setValidationErrorTabs((prev) => {
|
|
552
|
+
const newSet = new Set(prev);
|
|
553
|
+
newSet.delete(tabIndex);
|
|
554
|
+
return newSet;
|
|
555
|
+
});
|
|
556
|
+
} else {
|
|
557
|
+
setCompletedTabs((prev) => {
|
|
558
|
+
const newSet = new Set(prev);
|
|
559
|
+
newSet.delete(tabIndex);
|
|
560
|
+
return newSet;
|
|
561
|
+
});
|
|
562
|
+
}
|
|
563
|
+
});
|
|
564
|
+
}, 300);
|
|
565
|
+
checkTabCompletion();
|
|
566
|
+
}, [formData, validationRegistry, getCombinedTabFields, tabs, setCompletedTabs, setValidationErrorTabs]);
|
|
567
|
+
const handleTabChangeWithErrorCheck = React3.useCallback((index) => {
|
|
568
|
+
onTabChange(index);
|
|
569
|
+
}, [onTabChange]);
|
|
570
|
+
const handleNextWithValidation = React3.useCallback(() => {
|
|
571
|
+
const currentTabFields = getCombinedTabFields(activeTab);
|
|
572
|
+
if (currentTabFields.length > 0) {
|
|
573
|
+
const allErrors = {};
|
|
574
|
+
let isValid = true;
|
|
575
|
+
for (const field of currentTabFields) {
|
|
576
|
+
const validation = validationRegistry[field];
|
|
577
|
+
if (validation) {
|
|
578
|
+
try {
|
|
579
|
+
validation.parse(formData[field]);
|
|
580
|
+
} catch (error) {
|
|
581
|
+
if (error instanceof zod.z.ZodError) {
|
|
582
|
+
allErrors[field] = error.issues[0]?.message || `Invalid ${field}`;
|
|
583
|
+
isValid = false;
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
if (isValid) {
|
|
589
|
+
setCompletedTabs((prev) => /* @__PURE__ */ new Set([...prev, activeTab]));
|
|
590
|
+
setValidationErrorTabs((prev) => {
|
|
591
|
+
const newSet = new Set(prev);
|
|
592
|
+
newSet.delete(activeTab);
|
|
593
|
+
return newSet;
|
|
594
|
+
});
|
|
595
|
+
onNext();
|
|
596
|
+
} else {
|
|
597
|
+
setCompletedTabs((prev) => {
|
|
598
|
+
const newSet = new Set(prev);
|
|
599
|
+
newSet.delete(activeTab);
|
|
600
|
+
return newSet;
|
|
601
|
+
});
|
|
602
|
+
setValidationErrorTabs((prev) => /* @__PURE__ */ new Set([...prev, activeTab]));
|
|
603
|
+
validateFields(currentTabFields);
|
|
604
|
+
const firstErrorField = currentTabFields.find((field) => allErrors[field]);
|
|
605
|
+
if (firstErrorField) {
|
|
606
|
+
setTimeout(() => {
|
|
607
|
+
const element = document.querySelector(`[data-field="${firstErrorField}"]`);
|
|
608
|
+
if (element) {
|
|
609
|
+
element.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
610
|
+
element.focus();
|
|
611
|
+
}
|
|
612
|
+
}, 50);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
} else {
|
|
616
|
+
onNext();
|
|
617
|
+
}
|
|
618
|
+
}, [activeTab, getCombinedTabFields, validateFields, onNext, setCompletedTabs, setValidationErrorTabs, validationRegistry, formData]);
|
|
619
|
+
const handleSubmitWithValidation = React3.useCallback(async () => {
|
|
620
|
+
const allErrors = {};
|
|
621
|
+
let isValid = true;
|
|
622
|
+
let firstErrorTabIndex = -1;
|
|
623
|
+
for (const [field, validation] of Object.entries(validationRegistry)) {
|
|
624
|
+
if (validation && typeof validation.parse === "function") {
|
|
625
|
+
try {
|
|
626
|
+
validation.parse(formData[field]);
|
|
627
|
+
} catch (error) {
|
|
628
|
+
if (error instanceof zod.z.ZodError) {
|
|
629
|
+
allErrors[field] = error.issues[0]?.message || `Invalid ${field}`;
|
|
630
|
+
isValid = false;
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
setErrors(allErrors);
|
|
636
|
+
if (isValid) {
|
|
637
|
+
await submitForm();
|
|
638
|
+
} else {
|
|
639
|
+
setValidationErrorTabs(/* @__PURE__ */ new Set());
|
|
640
|
+
for (let tabIndex = 0; tabIndex < tabs.length; tabIndex++) {
|
|
641
|
+
const tabFieldsInTab = getCombinedTabFields(tabIndex);
|
|
642
|
+
const hasErrorsInTab = tabFieldsInTab.some((field) => allErrors[field]);
|
|
643
|
+
if (hasErrorsInTab) {
|
|
644
|
+
setValidationErrorTabs((prev) => /* @__PURE__ */ new Set([...prev, tabIndex]));
|
|
645
|
+
if (firstErrorTabIndex === -1) {
|
|
646
|
+
firstErrorTabIndex = tabIndex;
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
if (firstErrorTabIndex !== -1) {
|
|
651
|
+
onTabChange(firstErrorTabIndex);
|
|
652
|
+
setTimeout(() => {
|
|
653
|
+
const tabFieldsInTab = getCombinedTabFields(firstErrorTabIndex);
|
|
654
|
+
const firstErrorField = tabFieldsInTab.find((field) => allErrors[field]);
|
|
655
|
+
if (firstErrorField) {
|
|
656
|
+
const element = document.querySelector(`[data-field="${firstErrorField}"]`);
|
|
657
|
+
if (element) {
|
|
658
|
+
element.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
659
|
+
element.focus();
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
}, 100);
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
}, [submitForm, getCombinedTabFields, onTabChange, tabs.length, validationRegistry, formData, setErrors, setValidationErrorTabs]);
|
|
666
|
+
const activeTabValue = tabs[activeTab] || tabs[0] || "";
|
|
667
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
668
|
+
/* @__PURE__ */ jsxRuntime.jsxs(Tabs, { value: activeTabValue, onValueChange: (value) => {
|
|
669
|
+
const newIndex = tabs.indexOf(value);
|
|
670
|
+
if (newIndex !== -1) {
|
|
671
|
+
handleTabChangeWithErrorCheck(newIndex);
|
|
672
|
+
}
|
|
673
|
+
}, className: "w-full", children: [
|
|
674
|
+
/* @__PURE__ */ jsxRuntime.jsx(TabsList, { className: `grid w-full mb-8`, style: { gridTemplateColumns: `repeat(${tabs.length}, 1fr)` }, children: tabs.map((tab, index) => /* @__PURE__ */ jsxRuntime.jsxs(TabsTrigger, { value: tab, className: "flex items-center gap-2", children: [
|
|
675
|
+
config.showTabNumbers && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
676
|
+
index + 1,
|
|
677
|
+
"."
|
|
678
|
+
] }),
|
|
679
|
+
tab,
|
|
680
|
+
completedTabs.has(index) && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-4 w-4 text-green-600" }),
|
|
681
|
+
validationErrorTabs.has(index) && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4 text-red-600" })
|
|
682
|
+
] }, tab)) }),
|
|
683
|
+
React3__default.default.Children.map(children, (child, index) => {
|
|
684
|
+
if (React3__default.default.isValidElement(child) && child.type === Tab) {
|
|
685
|
+
const tabProps = child.props;
|
|
686
|
+
return /* @__PURE__ */ jsxRuntime.jsx(TabsContent, { value: tabProps.title, children: /* @__PURE__ */ jsxRuntime.jsx(TabIndexProvider, { tabIndex: index, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
687
|
+
"div",
|
|
688
|
+
{
|
|
689
|
+
ref: (el) => {
|
|
690
|
+
contentRefs.current[index] = el;
|
|
691
|
+
},
|
|
692
|
+
className: "space-y-6",
|
|
693
|
+
style: { minHeight: maxContentHeight > 0 ? `${maxContentHeight}px` : void 0 },
|
|
694
|
+
children: tabProps.children
|
|
695
|
+
}
|
|
696
|
+
) }) }, index);
|
|
697
|
+
}
|
|
698
|
+
return null;
|
|
699
|
+
}),
|
|
700
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { position: "absolute", left: "-9999px", top: "-9999px", visibility: "hidden" }, children: React3__default.default.Children.map(children, (child, index) => {
|
|
701
|
+
if (React3__default.default.isValidElement(child) && child.type === Tab) {
|
|
702
|
+
const tabProps = child.props;
|
|
703
|
+
return /* @__PURE__ */ jsxRuntime.jsx(TabIndexProvider, { tabIndex: index, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
704
|
+
"div",
|
|
705
|
+
{
|
|
706
|
+
ref: (el) => {
|
|
707
|
+
contentRefs.current[index] = el;
|
|
708
|
+
},
|
|
709
|
+
className: "space-y-6",
|
|
710
|
+
children: tabProps.children
|
|
711
|
+
}
|
|
712
|
+
) }, `hidden-${index}`);
|
|
713
|
+
}
|
|
714
|
+
return null;
|
|
715
|
+
}) })
|
|
716
|
+
] }),
|
|
717
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
718
|
+
NavigationButtonsWrapper,
|
|
719
|
+
{
|
|
720
|
+
activeTab,
|
|
721
|
+
totalTabs: tabs.length,
|
|
722
|
+
onPrevious,
|
|
723
|
+
onNext: handleNextWithValidation,
|
|
724
|
+
onSubmit: handleSubmitWithValidation,
|
|
725
|
+
onSaveDraft: config.allowSaveDraft ? saveDraft : void 0,
|
|
726
|
+
onReset: config.showReset || config.enableLocalStorage ? resetForm : void 0,
|
|
727
|
+
isLoading,
|
|
728
|
+
isDraftSaving,
|
|
729
|
+
config
|
|
730
|
+
}
|
|
731
|
+
),
|
|
732
|
+
footerChildren.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-4", children: footerChildren }),
|
|
733
|
+
config.showProgressBar && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-6", children: [
|
|
734
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between text-sm text-muted-foreground mb-2", children: [
|
|
735
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Progress" }),
|
|
736
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
737
|
+
Math.round((activeTab + 1) / tabs.length * 100),
|
|
738
|
+
"%"
|
|
739
|
+
] })
|
|
740
|
+
] }),
|
|
741
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full bg-muted rounded-full h-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
742
|
+
"div",
|
|
743
|
+
{
|
|
744
|
+
className: "bg-primary h-2 rounded-full transition-all duration-300",
|
|
745
|
+
style: { width: `${(activeTab + 1) / tabs.length * 100}%` }
|
|
746
|
+
}
|
|
747
|
+
) })
|
|
748
|
+
] })
|
|
749
|
+
] });
|
|
750
|
+
};
|
|
751
|
+
|
|
752
|
+
// src/hooks/useFormWrapper.ts
|
|
753
|
+
var useFormWrapper = () => {
|
|
754
|
+
return chunkYV7RVYMD_cjs.useSmartForm();
|
|
755
|
+
};
|
|
756
|
+
var useExternalFormRegistration = () => {
|
|
757
|
+
const context = React3.useContext(ExternalFormContext);
|
|
758
|
+
if (!context) {
|
|
759
|
+
throw new Error("useExternalFormRegistration must be used within a MultiTabSmartForm");
|
|
760
|
+
}
|
|
761
|
+
return context;
|
|
762
|
+
};
|
|
763
|
+
var useExternalFormFields = (fields, tabIndex) => {
|
|
764
|
+
const { registerTabFields } = useExternalFormRegistration();
|
|
765
|
+
const stableFields = React3.useMemo(() => fields, [fields.join(",")]);
|
|
766
|
+
React3.useEffect(() => {
|
|
767
|
+
if (stableFields.length > 0) {
|
|
768
|
+
registerTabFields(tabIndex, stableFields);
|
|
769
|
+
}
|
|
770
|
+
}, [stableFields, tabIndex, registerTabFields]);
|
|
771
|
+
};
|
|
772
|
+
var ExternalFieldProvider = ({
|
|
773
|
+
children,
|
|
774
|
+
registerField
|
|
775
|
+
}) => {
|
|
776
|
+
return /* @__PURE__ */ jsxRuntime.jsx(chunkYV7RVYMD_cjs.FieldDetectionContext.Provider, { value: { registerField }, children });
|
|
777
|
+
};
|
|
778
|
+
|
|
779
|
+
// src/useAutoDetectFields.tsx
|
|
780
|
+
var useAutoDetectFields = (tabIndex) => {
|
|
781
|
+
const { registerTabFields } = useExternalFormRegistration();
|
|
782
|
+
const hasRegistered = React3.useRef(false);
|
|
783
|
+
const detectedFields = React3.useRef(/* @__PURE__ */ new Set());
|
|
784
|
+
const registerField = React3.useCallback((fieldName) => {
|
|
785
|
+
detectedFields.current.add(fieldName);
|
|
786
|
+
if (!hasRegistered.current) {
|
|
787
|
+
const fieldsArray = Array.from(detectedFields.current);
|
|
788
|
+
registerTabFields(tabIndex, fieldsArray);
|
|
789
|
+
hasRegistered.current = true;
|
|
790
|
+
}
|
|
791
|
+
}, [tabIndex, registerTabFields]);
|
|
792
|
+
return { registerField, ExternalFieldProvider };
|
|
793
|
+
};
|
|
794
|
+
var useExternalTab = () => {
|
|
795
|
+
const { registerTabFields } = useExternalFormRegistration();
|
|
796
|
+
const tabIndexContext = useTabIndex();
|
|
797
|
+
const detectedFields = React3.useRef(/* @__PURE__ */ new Set());
|
|
798
|
+
const registrationTimeout = React3.useRef(null);
|
|
799
|
+
const hasRegistered = React3.useRef(false);
|
|
800
|
+
const tabIndex = tabIndexContext?.tabIndex ?? 0;
|
|
801
|
+
const registerField = React3.useCallback((fieldName) => {
|
|
802
|
+
detectedFields.current.add(fieldName);
|
|
803
|
+
if (registrationTimeout.current) {
|
|
804
|
+
clearTimeout(registrationTimeout.current);
|
|
805
|
+
}
|
|
806
|
+
registrationTimeout.current = setTimeout(() => {
|
|
807
|
+
if (!hasRegistered.current) {
|
|
808
|
+
const fieldsArray = Array.from(detectedFields.current);
|
|
809
|
+
if (fieldsArray.length > 0) {
|
|
810
|
+
registerTabFields(tabIndex, fieldsArray);
|
|
811
|
+
hasRegistered.current = true;
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
}, 200);
|
|
815
|
+
}, [tabIndex, registerTabFields]);
|
|
816
|
+
React3.useEffect(() => {
|
|
817
|
+
const forceRegistrationTimeout = setTimeout(() => {
|
|
818
|
+
if (!hasRegistered.current) {
|
|
819
|
+
const fieldsArray = Array.from(detectedFields.current);
|
|
820
|
+
if (fieldsArray.length > 0) {
|
|
821
|
+
registerTabFields(tabIndex, fieldsArray);
|
|
822
|
+
hasRegistered.current = true;
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
}, 1e3);
|
|
826
|
+
return () => {
|
|
827
|
+
clearTimeout(forceRegistrationTimeout);
|
|
828
|
+
if (registrationTimeout.current) {
|
|
829
|
+
clearTimeout(registrationTimeout.current);
|
|
830
|
+
}
|
|
831
|
+
};
|
|
832
|
+
}, [tabIndex, registerTabFields]);
|
|
833
|
+
return { registerField, ExternalFieldProvider };
|
|
834
|
+
};
|
|
835
|
+
var FormFieldGroup = ({
|
|
836
|
+
children,
|
|
837
|
+
className = ""
|
|
838
|
+
}) => {
|
|
839
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex flex-wrap gap-2 md:gap-4 mb-4 ${className}`, children });
|
|
840
|
+
};
|
|
841
|
+
|
|
842
|
+
Object.defineProperty(exports, "SmartCheckbox", {
|
|
843
|
+
enumerable: true,
|
|
844
|
+
get: function () { return chunkY6NGPMDH_cjs.SmartCheckbox; }
|
|
845
|
+
});
|
|
846
|
+
Object.defineProperty(exports, "SmartDatePicker", {
|
|
847
|
+
enumerable: true,
|
|
848
|
+
get: function () { return chunkY6NGPMDH_cjs.SmartDatePicker; }
|
|
849
|
+
});
|
|
850
|
+
Object.defineProperty(exports, "SmartRadioGroup", {
|
|
851
|
+
enumerable: true,
|
|
852
|
+
get: function () { return chunkY6NGPMDH_cjs.SmartRadioGroup; }
|
|
853
|
+
});
|
|
854
|
+
Object.defineProperty(exports, "SmartSelect", {
|
|
855
|
+
enumerable: true,
|
|
856
|
+
get: function () { return chunkY6NGPMDH_cjs.SmartSelect; }
|
|
857
|
+
});
|
|
858
|
+
Object.defineProperty(exports, "SmartTags", {
|
|
859
|
+
enumerable: true,
|
|
860
|
+
get: function () { return chunkY6NGPMDH_cjs.SmartTags; }
|
|
861
|
+
});
|
|
862
|
+
Object.defineProperty(exports, "SmartFormProvider", {
|
|
863
|
+
enumerable: true,
|
|
864
|
+
get: function () { return chunkYV7RVYMD_cjs.SmartFormProvider; }
|
|
865
|
+
});
|
|
866
|
+
Object.defineProperty(exports, "SmartInput", {
|
|
867
|
+
enumerable: true,
|
|
868
|
+
get: function () { return chunkYV7RVYMD_cjs.SmartInput; }
|
|
869
|
+
});
|
|
870
|
+
Object.defineProperty(exports, "useFieldDetection", {
|
|
871
|
+
enumerable: true,
|
|
872
|
+
get: function () { return chunkYV7RVYMD_cjs.useFieldDetection; }
|
|
873
|
+
});
|
|
874
|
+
Object.defineProperty(exports, "useFormField", {
|
|
875
|
+
enumerable: true,
|
|
876
|
+
get: function () { return chunkYV7RVYMD_cjs.useFormField; }
|
|
877
|
+
});
|
|
878
|
+
Object.defineProperty(exports, "useSmartForm", {
|
|
879
|
+
enumerable: true,
|
|
880
|
+
get: function () { return chunkYV7RVYMD_cjs.useSmartForm; }
|
|
881
|
+
});
|
|
882
|
+
exports.BaseSmartForm = BaseSmartForm;
|
|
883
|
+
exports.DraftSaveButton = DraftSaveButton;
|
|
884
|
+
exports.ExternalFieldProvider = ExternalFieldProvider;
|
|
885
|
+
exports.Footer = Footer;
|
|
886
|
+
exports.FormFieldGroup = FormFieldGroup;
|
|
887
|
+
exports.FormHeader = FormHeader;
|
|
888
|
+
exports.LoadingSpinner = LoadingSpinner;
|
|
889
|
+
exports.MultiTabSmartForm = MultiTabSmartForm;
|
|
890
|
+
exports.NavigationButtons = NavigationButtons;
|
|
891
|
+
exports.ResetButton = ResetButton;
|
|
892
|
+
exports.Section = Section;
|
|
893
|
+
exports.SimpleFormButtons = SimpleFormButtons;
|
|
894
|
+
exports.SmartForm = SmartForm;
|
|
895
|
+
exports.SubmitButton = SubmitButton;
|
|
896
|
+
exports.Tab = Tab;
|
|
897
|
+
exports.TabIndexProvider = TabIndexProvider;
|
|
898
|
+
exports.ToastContainerWrapper = ToastContainerWrapper;
|
|
899
|
+
exports.useAutoDetectFields = useAutoDetectFields;
|
|
900
|
+
exports.useExternalFormFields = useExternalFormFields;
|
|
901
|
+
exports.useExternalFormRegistration = useExternalFormRegistration;
|
|
902
|
+
exports.useExternalTab = useExternalTab;
|
|
903
|
+
exports.useFormWrapper = useFormWrapper;
|
|
904
|
+
exports.useTabIndex = useTabIndex;
|
|
905
|
+
//# sourceMappingURL=index.cjs.map
|
|
906
|
+
//# sourceMappingURL=index.cjs.map
|