@algodomain/smart-forms 0.1.7 → 0.1.9

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/dist/index.cjs CHANGED
@@ -1,15 +1,14 @@
1
1
  'use strict';
2
2
 
3
- var chunkNVGQPR3P_cjs = require('./chunk-NVGQPR3P.cjs');
4
- var chunkWIBCOQPP_cjs = require('./chunk-WIBCOQPP.cjs');
3
+ var chunkDRMVY7TX_cjs = require('./chunk-DRMVY7TX.cjs');
4
+ var chunkWUYS7DMR_cjs = require('./chunk-WUYS7DMR.cjs');
5
5
  var React3 = require('react');
6
6
  var reactToastify = require('react-toastify');
7
7
  var jsxRuntime = require('react/jsx-runtime');
8
8
  var lucideReact = require('lucide-react');
9
9
  var zod = require('zod');
10
10
  var TabsPrimitive = require('@radix-ui/react-tabs');
11
-
12
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
11
+ var react = require('motion/react');
13
12
 
14
13
  function _interopNamespace(e) {
15
14
  if (e && e.__esModule) return e;
@@ -29,7 +28,7 @@ function _interopNamespace(e) {
29
28
  return Object.freeze(n);
30
29
  }
31
30
 
32
- var React3__default = /*#__PURE__*/_interopDefault(React3);
31
+ var React3__namespace = /*#__PURE__*/_interopNamespace(React3);
33
32
  var TabsPrimitive__namespace = /*#__PURE__*/_interopNamespace(TabsPrimitive);
34
33
 
35
34
  var ToastContainerWrapper = () => /* @__PURE__ */ jsxRuntime.jsx(
@@ -120,7 +119,7 @@ var BaseSmartForm = ({
120
119
  queryParamsToInclude,
121
120
  submitDisabled
122
121
  };
123
- return /* @__PURE__ */ jsxRuntime.jsx(chunkWIBCOQPP_cjs.SmartFormProvider, { config, initialData, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className, children: [
122
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkWUYS7DMR_cjs.SmartFormProvider, { config, initialData, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className, children: [
124
123
  /* @__PURE__ */ jsxRuntime.jsx(ToastContainerWrapper, {}),
125
124
  /* @__PURE__ */ jsxRuntime.jsx(FormHeader, { title, subTitle, logo }),
126
125
  children,
@@ -128,15 +127,15 @@ var BaseSmartForm = ({
128
127
  ] }) });
129
128
  };
130
129
  var LoadingSpinner = ({ className = "h-4 w-4" }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: `animate-spin rounded-full border-b-2 border-current ${className}` });
131
- var SubmitButton = ({ onClick, disabled, isLoading, children, className }) => /* @__PURE__ */ jsxRuntime.jsx(chunkNVGQPR3P_cjs.Button, { onClick, disabled, className, children: isLoading ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
130
+ var SubmitButton = ({ onClick, disabled, isLoading, children, className }) => /* @__PURE__ */ jsxRuntime.jsx(chunkDRMVY7TX_cjs.Button, { onClick, disabled, className, children: isLoading ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
132
131
  /* @__PURE__ */ jsxRuntime.jsx(LoadingSpinner, {}),
133
132
  "Submitting..."
134
133
  ] }) : children });
135
- var DraftSaveButton = ({ onClick, disabled }) => /* @__PURE__ */ jsxRuntime.jsx(chunkNVGQPR3P_cjs.Button, { onClick, disabled, variant: "secondary", children: disabled ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
134
+ var DraftSaveButton = ({ onClick, disabled }) => /* @__PURE__ */ jsxRuntime.jsx(chunkDRMVY7TX_cjs.Button, { onClick, disabled, variant: "secondary", children: disabled ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
136
135
  /* @__PURE__ */ jsxRuntime.jsx(LoadingSpinner, {}),
137
136
  "Saving..."
138
137
  ] }) : "Save Draft" });
139
- var ResetButton = ({ onClick }) => /* @__PURE__ */ jsxRuntime.jsx(chunkNVGQPR3P_cjs.Button, { onClick, variant: "secondary", children: "Reset Form" });
138
+ var ResetButton = ({ onClick }) => /* @__PURE__ */ jsxRuntime.jsx(chunkDRMVY7TX_cjs.Button, { onClick, variant: "secondary", children: "Reset Form" });
140
139
  var NavigationButtons = ({
141
140
  onPrevious,
142
141
  onNext,
@@ -147,9 +146,10 @@ var NavigationButtons = ({
147
146
  isDraftSaving,
148
147
  config,
149
148
  isFirstTab = false,
150
- isLastTab = false
149
+ isLastTab = false,
150
+ disabled = false
151
151
  }) => {
152
- const { formData, config: formConfig } = chunkWIBCOQPP_cjs.useSmartForm();
152
+ const { formData, config: formConfig } = chunkWUYS7DMR_cjs.useSmartForm();
153
153
  const isSubmitDisabled = typeof formConfig.submitDisabled === "function" ? formConfig.submitDisabled(formData) : formConfig.submitDisabled || false;
154
154
  const hasResetButton = !!onReset;
155
155
  const hasDraftButton = config.allowSaveDraft && !!onSaveDraft;
@@ -159,10 +159,10 @@ var NavigationButtons = ({
159
159
  const isSingleButton = rightSectionButtons === 1 && !hasPreviousButton;
160
160
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-between items-center mt-8 pt-6 border-t border-gray-200", children: [
161
161
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex gap-4", children: onPrevious && /* @__PURE__ */ jsxRuntime.jsxs(
162
- chunkNVGQPR3P_cjs.Button,
162
+ chunkDRMVY7TX_cjs.Button,
163
163
  {
164
164
  onClick: onPrevious,
165
- disabled: isFirstTab,
165
+ disabled: isFirstTab || disabled,
166
166
  variant: "secondary",
167
167
  children: [
168
168
  /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronLeft, { className: "h-4 w-4" }),
@@ -171,13 +171,13 @@ var NavigationButtons = ({
171
171
  }
172
172
  ) }),
173
173
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: isSingleButton ? "w-full" : "flex gap-4", children: [
174
- onReset && /* @__PURE__ */ jsxRuntime.jsx(ResetButton, { onClick: onReset }),
175
- config.allowSaveDraft && onSaveDraft && /* @__PURE__ */ jsxRuntime.jsx(DraftSaveButton, { onClick: onSaveDraft, disabled: isDraftSaving }),
174
+ onReset && /* @__PURE__ */ jsxRuntime.jsx(chunkDRMVY7TX_cjs.Button, { onClick: onReset, disabled, variant: "secondary", children: "Reset Form" }),
175
+ config.allowSaveDraft && onSaveDraft && /* @__PURE__ */ jsxRuntime.jsx(DraftSaveButton, { onClick: onSaveDraft, disabled: isDraftSaving || disabled }),
176
176
  isLastTab ? /* @__PURE__ */ jsxRuntime.jsxs(
177
177
  SubmitButton,
178
178
  {
179
179
  onClick: onSubmit,
180
- disabled: isLoading || isSubmitDisabled,
180
+ disabled: isLoading || isSubmitDisabled || disabled,
181
181
  isLoading,
182
182
  className: isSingleButton ? "w-full" : "",
183
183
  children: [
@@ -186,9 +186,10 @@ var NavigationButtons = ({
186
186
  ]
187
187
  }
188
188
  ) : onNext && /* @__PURE__ */ jsxRuntime.jsxs(
189
- chunkNVGQPR3P_cjs.Button,
189
+ chunkDRMVY7TX_cjs.Button,
190
190
  {
191
191
  onClick: onNext,
192
+ disabled,
192
193
  className: isSingleButton ? "w-full" : "",
193
194
  children: [
194
195
  "Next",
@@ -207,7 +208,7 @@ var SimpleFormButtons = ({
207
208
  isDraftSaving,
208
209
  config
209
210
  }) => {
210
- const { formData, config: formConfig } = chunkWIBCOQPP_cjs.useSmartForm();
211
+ const { formData, config: formConfig } = chunkWUYS7DMR_cjs.useSmartForm();
211
212
  const isSubmitDisabled = typeof formConfig.submitDisabled === "function" ? formConfig.submitDisabled(formData) : formConfig.submitDisabled || false;
212
213
  const hasResetButton = !!onReset;
213
214
  const hasDraftButton = config.allowSaveDraft && !!onSaveDraft;
@@ -233,7 +234,7 @@ var SimpleFormButtons = ({
233
234
  ] }) });
234
235
  };
235
236
  var SubmitButton2 = () => {
236
- const { isLoading, isDraftSaving, submitForm, saveDraft, resetForm, config } = chunkWIBCOQPP_cjs.useSmartForm();
237
+ const { isLoading, isDraftSaving, submitForm, saveDraft, resetForm, config } = chunkWUYS7DMR_cjs.useSmartForm();
237
238
  const shouldShowReset = config.showReset || config.enableLocalStorage;
238
239
  return /* @__PURE__ */ jsxRuntime.jsx(
239
240
  SimpleFormButtons,
@@ -249,7 +250,7 @@ var SubmitButton2 = () => {
249
250
  };
250
251
  var SmartForm = (props) => {
251
252
  const { children, ...otherProps } = props;
252
- const childArray = React3__default.default.Children.toArray(children);
253
+ const childArray = React3__namespace.default.Children.toArray(children);
253
254
  const footerChildren = [];
254
255
  const regularChildren = [];
255
256
  childArray.forEach((child) => {
@@ -265,28 +266,471 @@ var SmartForm = (props) => {
265
266
  footerChildren.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-4", children: footerChildren })
266
267
  ] });
267
268
  };
269
+ var MotionHighlightContext = React3__namespace.createContext(void 0);
270
+ function useMotionHighlight() {
271
+ const context = React3__namespace.useContext(MotionHighlightContext);
272
+ if (!context) {
273
+ throw new Error("useMotionHighlight must be used within a MotionHighlightProvider");
274
+ }
275
+ return context;
276
+ }
277
+ function MotionHighlight({ ref, ...props }) {
278
+ const {
279
+ children,
280
+ value,
281
+ defaultValue,
282
+ onValueChange,
283
+ className,
284
+ transition = { type: "spring", stiffness: 350, damping: 35 },
285
+ hover = false,
286
+ enabled = true,
287
+ controlledItems,
288
+ disabled = false,
289
+ exitDelay = 0.2,
290
+ mode = "children"
291
+ } = props;
292
+ const localRef = React3__namespace.useRef(null);
293
+ React3__namespace.useImperativeHandle(ref, () => localRef.current);
294
+ const [activeValue, setActiveValue] = React3__namespace.useState(value ?? defaultValue ?? null);
295
+ const [boundsState, setBoundsState] = React3__namespace.useState(null);
296
+ const [activeClassNameState, setActiveClassNameState] = React3__namespace.useState("");
297
+ const safeSetActiveValue = React3__namespace.useCallback(
298
+ (id2) => {
299
+ setActiveValue((prev) => prev === id2 ? prev : id2);
300
+ if (id2 !== activeValue) onValueChange?.(id2);
301
+ },
302
+ [activeValue, onValueChange]
303
+ );
304
+ const safeSetBounds = React3__namespace.useCallback(
305
+ (bounds) => {
306
+ if (!localRef.current) return;
307
+ const boundsOffset = props?.boundsOffset ?? {
308
+ top: 0,
309
+ left: 0,
310
+ width: 0,
311
+ height: 0
312
+ };
313
+ const containerRect = localRef.current.getBoundingClientRect();
314
+ const newBounds = {
315
+ top: bounds.top - containerRect.top + (boundsOffset.top ?? 0),
316
+ left: bounds.left - containerRect.left + (boundsOffset.left ?? 0),
317
+ width: bounds.width + (boundsOffset.width ?? 0),
318
+ height: bounds.height + (boundsOffset.height ?? 0)
319
+ };
320
+ setBoundsState((prev) => {
321
+ if (prev && prev.top === newBounds.top && prev.left === newBounds.left && prev.width === newBounds.width && prev.height === newBounds.height) {
322
+ return prev;
323
+ }
324
+ return newBounds;
325
+ });
326
+ },
327
+ [props]
328
+ );
329
+ const clearBounds = React3__namespace.useCallback(() => {
330
+ setBoundsState((prev) => prev === null ? prev : null);
331
+ }, []);
332
+ React3__namespace.useEffect(() => {
333
+ if (value !== void 0) setActiveValue(value);
334
+ else if (defaultValue !== void 0) setActiveValue(defaultValue);
335
+ }, [value, defaultValue]);
336
+ const id = React3__namespace.useId();
337
+ React3__namespace.useEffect(() => {
338
+ if (mode !== "parent") return;
339
+ const container = localRef.current;
340
+ if (!container) return;
341
+ const onScroll = () => {
342
+ if (!activeValue) return;
343
+ const activeEl = container.querySelector(`[data-value="${activeValue}"][data-highlight="true"]`);
344
+ if (activeEl) safeSetBounds(activeEl.getBoundingClientRect());
345
+ };
346
+ container.addEventListener("scroll", onScroll, { passive: true });
347
+ return () => container.removeEventListener("scroll", onScroll);
348
+ }, [mode, activeValue, safeSetBounds]);
349
+ const render = React3__namespace.useCallback(
350
+ (children2) => {
351
+ if (mode === "parent") {
352
+ return /* @__PURE__ */ jsxRuntime.jsxs(
353
+ "div",
354
+ {
355
+ ref: localRef,
356
+ "data-slot": "motion-highlight-container",
357
+ className: chunkWUYS7DMR_cjs.cn("relative", props?.containerClassName),
358
+ children: [
359
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { initial: false, children: boundsState && /* @__PURE__ */ jsxRuntime.jsx(
360
+ react.motion.div,
361
+ {
362
+ "data-slot": "motion-highlight",
363
+ animate: {
364
+ top: boundsState.top,
365
+ left: boundsState.left,
366
+ width: boundsState.width,
367
+ height: boundsState.height,
368
+ opacity: 1
369
+ },
370
+ initial: {
371
+ top: boundsState.top,
372
+ left: boundsState.left,
373
+ width: boundsState.width,
374
+ height: boundsState.height,
375
+ opacity: 0
376
+ },
377
+ exit: {
378
+ opacity: 0,
379
+ transition: {
380
+ ...transition,
381
+ delay: (transition?.delay ?? 0) + (exitDelay ?? 0)
382
+ }
383
+ },
384
+ transition,
385
+ className: chunkWUYS7DMR_cjs.cn("bg-muted absolute z-0", className, activeClassNameState)
386
+ }
387
+ ) }),
388
+ children2
389
+ ]
390
+ }
391
+ );
392
+ }
393
+ return children2;
394
+ },
395
+ [mode, props, boundsState, transition, exitDelay, className, activeClassNameState]
396
+ );
397
+ return /* @__PURE__ */ jsxRuntime.jsx(
398
+ MotionHighlightContext.Provider,
399
+ {
400
+ value: {
401
+ mode,
402
+ activeValue,
403
+ setActiveValue: safeSetActiveValue,
404
+ id,
405
+ hover,
406
+ className,
407
+ transition,
408
+ disabled,
409
+ enabled,
410
+ exitDelay,
411
+ setBounds: safeSetBounds,
412
+ clearBounds,
413
+ activeClassName: activeClassNameState,
414
+ setActiveClassName: setActiveClassNameState,
415
+ forceUpdateBounds: props?.forceUpdateBounds
416
+ },
417
+ children: enabled ? controlledItems ? render(children) : render(
418
+ React3__namespace.Children.map(children, (child, index) => /* @__PURE__ */ jsxRuntime.jsx(MotionHighlightItem, { className: props?.itemsClassName, children: child }, index))
419
+ ) : children
420
+ }
421
+ );
422
+ }
423
+ function getNonOverridingDataAttributes(element, dataAttributes) {
424
+ return Object.keys(dataAttributes).reduce((acc, key) => {
425
+ if (element.props[key] === void 0) {
426
+ acc[key] = dataAttributes[key];
427
+ }
428
+ return acc;
429
+ }, {});
430
+ }
431
+ function MotionHighlightItem({
432
+ ref,
433
+ children,
434
+ id,
435
+ value,
436
+ className,
437
+ transition,
438
+ disabled = false,
439
+ activeClassName,
440
+ exitDelay,
441
+ asChild = false,
442
+ forceUpdateBounds,
443
+ ...props
444
+ }) {
445
+ const itemId = React3__namespace.useId();
446
+ const {
447
+ activeValue,
448
+ setActiveValue,
449
+ mode,
450
+ setBounds,
451
+ clearBounds,
452
+ hover,
453
+ enabled,
454
+ className: contextClassName,
455
+ transition: contextTransition,
456
+ id: contextId,
457
+ disabled: contextDisabled,
458
+ exitDelay: contextExitDelay,
459
+ forceUpdateBounds: contextForceUpdateBounds,
460
+ setActiveClassName
461
+ } = useMotionHighlight();
462
+ const element = children;
463
+ const childValue = id ?? value ?? element.props?.["data-value"] ?? element.props?.id ?? itemId;
464
+ const isActive = activeValue === childValue;
465
+ const isDisabled = disabled === void 0 ? contextDisabled : disabled;
466
+ const itemTransition = transition ?? contextTransition;
467
+ const localRef = React3__namespace.useRef(null);
468
+ React3__namespace.useImperativeHandle(ref, () => localRef.current);
469
+ React3__namespace.useEffect(() => {
470
+ if (mode !== "parent") return;
471
+ let rafId;
472
+ let previousBounds = null;
473
+ const shouldUpdateBounds = forceUpdateBounds === true || contextForceUpdateBounds && forceUpdateBounds !== false;
474
+ const updateBounds = () => {
475
+ if (!localRef.current) return;
476
+ const bounds = localRef.current.getBoundingClientRect();
477
+ if (shouldUpdateBounds) {
478
+ if (previousBounds && previousBounds.top === bounds.top && previousBounds.left === bounds.left && previousBounds.width === bounds.width && previousBounds.height === bounds.height) {
479
+ rafId = requestAnimationFrame(updateBounds);
480
+ return;
481
+ }
482
+ previousBounds = bounds;
483
+ rafId = requestAnimationFrame(updateBounds);
484
+ }
485
+ setBounds(bounds);
486
+ };
487
+ if (isActive) {
488
+ updateBounds();
489
+ setActiveClassName(activeClassName ?? "");
490
+ } else if (!activeValue) clearBounds();
491
+ if (shouldUpdateBounds) return () => cancelAnimationFrame(rafId);
492
+ }, [
493
+ mode,
494
+ isActive,
495
+ activeValue,
496
+ setBounds,
497
+ clearBounds,
498
+ activeClassName,
499
+ setActiveClassName,
500
+ forceUpdateBounds,
501
+ contextForceUpdateBounds
502
+ ]);
503
+ if (!React3__namespace.isValidElement(children)) return children;
504
+ const dataAttributes = {
505
+ "data-active": isActive ? "true" : "false",
506
+ "aria-selected": isActive,
507
+ "data-disabled": isDisabled,
508
+ "data-value": childValue,
509
+ "data-highlight": true
510
+ };
511
+ const commonHandlers = hover ? {
512
+ onMouseEnter: (e) => {
513
+ setActiveValue(childValue);
514
+ element.props.onMouseEnter?.(e);
515
+ },
516
+ onMouseLeave: (e) => {
517
+ setActiveValue(null);
518
+ element.props.onMouseLeave?.(e);
519
+ }
520
+ } : {
521
+ onClick: (e) => {
522
+ setActiveValue(childValue);
523
+ element.props.onClick?.(e);
524
+ }
525
+ };
526
+ if (asChild) {
527
+ if (mode === "children") {
528
+ return React3__namespace.cloneElement(
529
+ element,
530
+ {
531
+ key: childValue,
532
+ ref: localRef,
533
+ className: chunkWUYS7DMR_cjs.cn("relative", element.props.className),
534
+ ...getNonOverridingDataAttributes(element, {
535
+ ...dataAttributes,
536
+ "data-slot": "motion-highlight-item-container"
537
+ }),
538
+ ...commonHandlers,
539
+ ...props
540
+ },
541
+ /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
542
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { initial: false, children: isActive && !isDisabled && /* @__PURE__ */ jsxRuntime.jsx(
543
+ react.motion.div,
544
+ {
545
+ layoutId: `transition-background-${contextId}`,
546
+ "data-slot": "motion-highlight",
547
+ className: chunkWUYS7DMR_cjs.cn("bg-muted absolute inset-0 z-0", contextClassName, activeClassName),
548
+ transition: itemTransition,
549
+ initial: { opacity: 0 },
550
+ animate: { opacity: 1 },
551
+ exit: {
552
+ opacity: 0,
553
+ transition: {
554
+ ...itemTransition,
555
+ delay: (itemTransition?.delay ?? 0) + (exitDelay ?? contextExitDelay ?? 0)
556
+ }
557
+ },
558
+ ...dataAttributes
559
+ }
560
+ ) }),
561
+ /* @__PURE__ */ jsxRuntime.jsx("div", { "data-slot": "motion-highlight-item", className: chunkWUYS7DMR_cjs.cn("relative z-[1]", className), ...dataAttributes, children })
562
+ ] })
563
+ );
564
+ }
565
+ return React3__namespace.cloneElement(element, {
566
+ ref: localRef,
567
+ ...getNonOverridingDataAttributes(element, {
568
+ ...dataAttributes,
569
+ "data-slot": "motion-highlight-item"
570
+ }),
571
+ ...commonHandlers
572
+ });
573
+ }
574
+ return enabled ? /* @__PURE__ */ jsxRuntime.jsxs(
575
+ "div",
576
+ {
577
+ ref: localRef,
578
+ "data-slot": "motion-highlight-item-container",
579
+ className: chunkWUYS7DMR_cjs.cn(mode === "children" && "relative", className),
580
+ ...dataAttributes,
581
+ ...props,
582
+ ...commonHandlers,
583
+ children: [
584
+ mode === "children" && /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { initial: false, children: isActive && !isDisabled && /* @__PURE__ */ jsxRuntime.jsx(
585
+ react.motion.div,
586
+ {
587
+ layoutId: `transition-background-${contextId}`,
588
+ "data-slot": "motion-highlight",
589
+ className: chunkWUYS7DMR_cjs.cn("bg-muted absolute inset-0 z-0", contextClassName, activeClassName),
590
+ transition: itemTransition,
591
+ initial: { opacity: 0 },
592
+ animate: { opacity: 1 },
593
+ exit: {
594
+ opacity: 0,
595
+ transition: {
596
+ ...itemTransition,
597
+ delay: (itemTransition?.delay ?? 0) + (exitDelay ?? contextExitDelay ?? 0)
598
+ }
599
+ },
600
+ ...dataAttributes
601
+ }
602
+ ) }),
603
+ React3__namespace.cloneElement(element, {
604
+ className: chunkWUYS7DMR_cjs.cn("relative z-[1]", element.props.className),
605
+ ...getNonOverridingDataAttributes(element, {
606
+ ...dataAttributes,
607
+ "data-slot": "motion-highlight-item"
608
+ })
609
+ })
610
+ ]
611
+ },
612
+ childValue
613
+ ) : children;
614
+ }
615
+ var TabsConfigContext = React3__namespace.createContext({});
616
+ function useTabsConfig() {
617
+ return React3__namespace.useContext(TabsConfigContext);
618
+ }
619
+ var TabsContext = React3__namespace.createContext(void 0);
620
+ function useTabs() {
621
+ const context = React3__namespace.useContext(TabsContext);
622
+ if (!context) {
623
+ throw new Error("useTabs must be used within a TabsProvider");
624
+ }
625
+ return context;
626
+ }
268
627
  function Tabs({
269
628
  className,
629
+ animate = false,
630
+ type = "default",
270
631
  ...props
271
632
  }) {
272
- return /* @__PURE__ */ jsxRuntime.jsx(
633
+ const config = React3__namespace.useMemo(() => ({ animate, type }), [animate, type]);
634
+ if (type === "default" && animate) {
635
+ const [activeValue, setActiveValue] = React3__namespace.useState(
636
+ props.defaultValue ?? void 0
637
+ );
638
+ const triggersRef = React3__namespace.useRef(/* @__PURE__ */ new Map());
639
+ const initialSet = React3__namespace.useRef(false);
640
+ const isControlled = props.value !== void 0;
641
+ React3__namespace.useEffect(() => {
642
+ if (!isControlled && activeValue === void 0 && triggersRef.current.size > 0 && !initialSet.current) {
643
+ const firstTab = Array.from(triggersRef.current.keys())[0];
644
+ setActiveValue(firstTab);
645
+ initialSet.current = true;
646
+ }
647
+ }, [activeValue, isControlled]);
648
+ const registerTrigger = (value, node) => {
649
+ if (node) {
650
+ triggersRef.current.set(value, node);
651
+ if (!isControlled && activeValue === void 0 && !initialSet.current) {
652
+ setActiveValue(value);
653
+ initialSet.current = true;
654
+ }
655
+ } else {
656
+ triggersRef.current.delete(value);
657
+ }
658
+ };
659
+ const handleValueChange = (val) => {
660
+ if (!isControlled) setActiveValue(val);
661
+ else props.onValueChange?.(val);
662
+ };
663
+ return /* @__PURE__ */ jsxRuntime.jsx(TabsConfigContext.Provider, { value: config, children: /* @__PURE__ */ jsxRuntime.jsx(
664
+ TabsContext.Provider,
665
+ {
666
+ value: {
667
+ activeValue: props.value ?? activeValue,
668
+ handleValueChange,
669
+ registerTrigger
670
+ },
671
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { "data-slot": "tabs", className: chunkWUYS7DMR_cjs.cn("flex flex-col gap-2", className), ...props, children: props.children })
672
+ }
673
+ ) });
674
+ }
675
+ return /* @__PURE__ */ jsxRuntime.jsx(TabsConfigContext.Provider, { value: config, children: /* @__PURE__ */ jsxRuntime.jsx(
273
676
  TabsPrimitive__namespace.Root,
274
677
  {
275
678
  "data-slot": "tabs",
276
- className: chunkWIBCOQPP_cjs.cn("flex flex-col gap-2", className),
679
+ className: chunkWUYS7DMR_cjs.cn("flex flex-col gap-2", className),
277
680
  ...props
278
681
  }
279
- );
682
+ ) });
280
683
  }
281
684
  function TabsList({
282
685
  className,
686
+ activeClassName,
687
+ transition = {
688
+ type: "spring",
689
+ stiffness: 200,
690
+ damping: 25
691
+ },
283
692
  ...props
284
693
  }) {
694
+ const { animate, type } = useTabsConfig();
695
+ if (type === "default" && animate) {
696
+ const { activeValue } = useTabs();
697
+ return /* @__PURE__ */ jsxRuntime.jsx(
698
+ MotionHighlight,
699
+ {
700
+ controlledItems: true,
701
+ className: chunkWUYS7DMR_cjs.cn("bg-background rounded-sm shadow-sm", activeClassName),
702
+ value: activeValue,
703
+ transition,
704
+ children: /* @__PURE__ */ jsxRuntime.jsx(
705
+ "div",
706
+ {
707
+ role: "tablist",
708
+ "data-slot": "tabs-list",
709
+ className: chunkWUYS7DMR_cjs.cn(
710
+ "bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]",
711
+ className
712
+ ),
713
+ ...props,
714
+ children: props.children
715
+ }
716
+ )
717
+ }
718
+ );
719
+ }
720
+ if (type === "underline") {
721
+ return /* @__PURE__ */ jsxRuntime.jsx(
722
+ UnderlineTabsList,
723
+ {
724
+ className,
725
+ ...props
726
+ }
727
+ );
728
+ }
285
729
  return /* @__PURE__ */ jsxRuntime.jsx(
286
730
  TabsPrimitive__namespace.List,
287
731
  {
288
732
  "data-slot": "tabs-list",
289
- className: chunkWIBCOQPP_cjs.cn(
733
+ className: chunkWUYS7DMR_cjs.cn(
290
734
  "bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]",
291
735
  className
292
736
  ),
@@ -294,15 +738,203 @@ function TabsList({
294
738
  }
295
739
  );
296
740
  }
741
+ var UnderlineTabsContext = React3__namespace.createContext(void 0);
742
+ function useUnderlineTabs() {
743
+ const context = React3__namespace.useContext(UnderlineTabsContext);
744
+ if (!context) {
745
+ return { registerTrigger: () => {
746
+ }, activeValue: void 0 };
747
+ }
748
+ return context;
749
+ }
750
+ function UnderlineTabsList({
751
+ children,
752
+ className,
753
+ ...props
754
+ }) {
755
+ const { animate } = useTabsConfig();
756
+ const tabRefs = React3__namespace.useRef([]);
757
+ const [underlineStyle, setUnderlineStyle] = React3__namespace.useState({ left: 0, width: 0 });
758
+ const listRef = React3__namespace.useRef(null);
759
+ const registerTrigger = React3__namespace.useCallback((index, element) => {
760
+ tabRefs.current[index] = element;
761
+ }, []);
762
+ const updateUnderline = React3__namespace.useCallback(() => {
763
+ const activeElement = tabRefs.current.find((el) => {
764
+ if (!el) return false;
765
+ return el.getAttribute("data-state") === "active";
766
+ });
767
+ if (activeElement && listRef.current) {
768
+ const listRect = listRef.current.getBoundingClientRect();
769
+ const activeRect = activeElement.getBoundingClientRect();
770
+ const left = activeRect.left - listRect.left;
771
+ const width = activeRect.width;
772
+ setUnderlineStyle({ left, width });
773
+ }
774
+ }, []);
775
+ React3__namespace.useLayoutEffect(() => {
776
+ updateUnderline();
777
+ }, [updateUnderline]);
778
+ React3__namespace.useEffect(() => {
779
+ if (!listRef.current) return;
780
+ const observers = [];
781
+ const setupObservers = () => {
782
+ observers.forEach((obs) => obs.disconnect());
783
+ observers.length = 0;
784
+ tabRefs.current.forEach((el) => {
785
+ if (el) {
786
+ const observer = new MutationObserver(() => {
787
+ updateUnderline();
788
+ });
789
+ observer.observe(el, { attributes: true, attributeFilter: ["data-state"] });
790
+ observers.push(observer);
791
+ }
792
+ });
793
+ };
794
+ setupObservers();
795
+ const listObserver = new MutationObserver(() => {
796
+ setupObservers();
797
+ updateUnderline();
798
+ });
799
+ if (listRef.current) {
800
+ listObserver.observe(listRef.current, {
801
+ childList: true,
802
+ subtree: true
803
+ });
804
+ observers.push(listObserver);
805
+ }
806
+ return () => {
807
+ observers.forEach((obs) => obs.disconnect());
808
+ };
809
+ }, [updateUnderline]);
810
+ const contextValue = React3__namespace.useMemo(
811
+ () => ({ registerTrigger, activeValue: void 0 }),
812
+ [registerTrigger]
813
+ );
814
+ return /* @__PURE__ */ jsxRuntime.jsx(UnderlineTabsContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: listRef, className: "relative", children: [
815
+ /* @__PURE__ */ jsxRuntime.jsx(
816
+ TabsPrimitive__namespace.List,
817
+ {
818
+ "data-slot": "tabs-list",
819
+ className: chunkWUYS7DMR_cjs.cn(
820
+ "bg-background relative rounded-none border-b p-0",
821
+ className
822
+ ),
823
+ ...props,
824
+ children
825
+ }
826
+ ),
827
+ animate && /* @__PURE__ */ jsxRuntime.jsx(
828
+ react.motion.div,
829
+ {
830
+ className: "bg-primary absolute bottom-0 z-20 h-0.5",
831
+ layoutId: "underline",
832
+ style: {
833
+ left: underlineStyle.left,
834
+ width: underlineStyle.width
835
+ },
836
+ transition: {
837
+ type: "spring",
838
+ stiffness: 400,
839
+ damping: 40
840
+ }
841
+ }
842
+ ),
843
+ !animate && underlineStyle.width > 0 && /* @__PURE__ */ jsxRuntime.jsx(
844
+ "div",
845
+ {
846
+ className: "bg-primary absolute bottom-0 z-20 h-0.5 transition-all duration-200",
847
+ style: {
848
+ left: underlineStyle.left,
849
+ width: underlineStyle.width
850
+ }
851
+ }
852
+ )
853
+ ] }) });
854
+ }
297
855
  function TabsTrigger({
298
856
  className,
299
857
  ...props
300
858
  }) {
859
+ const { animate, type } = useTabsConfig();
860
+ if (type === "default" && animate) {
861
+ const { activeValue, handleValueChange, registerTrigger } = useTabs();
862
+ const localRef = React3__namespace.useRef(null);
863
+ React3__namespace.useEffect(() => {
864
+ if (props.value) {
865
+ registerTrigger(props.value, localRef.current);
866
+ return () => registerTrigger(props.value, null);
867
+ }
868
+ }, [props.value, registerTrigger]);
869
+ const {
870
+ onDrag,
871
+ onDragStart,
872
+ onDragEnd,
873
+ onDragEnter,
874
+ onDragExit,
875
+ onDragLeave,
876
+ onDragOver,
877
+ onDrop,
878
+ onAnimationStart,
879
+ onAnimationEnd,
880
+ onAnimationIteration,
881
+ onTransitionEnd,
882
+ ...motionButtonProps
883
+ } = props;
884
+ return /* @__PURE__ */ jsxRuntime.jsx(MotionHighlightItem, { value: props.value, className: "size-full", children: /* @__PURE__ */ jsxRuntime.jsx(
885
+ react.motion.button,
886
+ {
887
+ ref: localRef,
888
+ "data-slot": "tabs-trigger",
889
+ role: "tab",
890
+ onClick: () => handleValueChange(props.value),
891
+ "data-state": activeValue === props.value ? "active" : "inactive",
892
+ className: chunkWUYS7DMR_cjs.cn(
893
+ "ring-offset-background focus-visible:ring-ring data-[state=active]:text-foreground z-10 inline-flex size-full cursor-pointer items-center justify-center rounded-sm px-2 py-1 text-sm font-medium whitespace-nowrap transition-transform focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50",
894
+ className
895
+ ),
896
+ ...motionButtonProps,
897
+ children: props.children
898
+ }
899
+ ) });
900
+ }
901
+ if (type === "underline") {
902
+ const { registerTrigger } = useUnderlineTabs();
903
+ const [index, setIndex] = React3__namespace.useState(-1);
904
+ const localRef = React3__namespace.useRef(null);
905
+ React3__namespace.useEffect(() => {
906
+ if (localRef.current && localRef.current.parentElement) {
907
+ const siblings = Array.from(localRef.current.parentElement.children);
908
+ const idx = siblings.indexOf(localRef.current);
909
+ if (idx >= 0) {
910
+ setIndex(idx);
911
+ registerTrigger(idx, localRef.current);
912
+ }
913
+ }
914
+ return () => {
915
+ if (index >= 0) {
916
+ registerTrigger(index, null);
917
+ }
918
+ };
919
+ }, [registerTrigger, index]);
920
+ return /* @__PURE__ */ jsxRuntime.jsx(
921
+ TabsPrimitive__namespace.Trigger,
922
+ {
923
+ ref: localRef,
924
+ "data-slot": "tabs-trigger",
925
+ className: chunkWUYS7DMR_cjs.cn(
926
+ "bg-background dark:data-[state=active]:bg-background relative z-10 pl-10 pr-10 rounded-none border-0 data-[state=active]:shadow-none cursor-pointer",
927
+ className
928
+ ),
929
+ ...props
930
+ }
931
+ );
932
+ }
301
933
  return /* @__PURE__ */ jsxRuntime.jsx(
302
934
  TabsPrimitive__namespace.Trigger,
303
935
  {
304
936
  "data-slot": "tabs-trigger",
305
- className: chunkWIBCOQPP_cjs.cn(
937
+ className: chunkWUYS7DMR_cjs.cn(
306
938
  "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",
307
939
  className
308
940
  ),
@@ -310,20 +942,73 @@ function TabsTrigger({
310
942
  }
311
943
  );
312
944
  }
945
+ var visitedTabsSet = /* @__PURE__ */ new Set();
313
946
  function TabsContent({
314
947
  className,
315
948
  ...props
316
949
  }) {
950
+ const { animate, type } = useTabsConfig();
951
+ if (type === "default" && animate) {
952
+ const { activeValue } = useTabs();
953
+ const isActive = activeValue === props.value;
954
+ const value = props.value;
955
+ React3__namespace.useEffect(() => {
956
+ if (value && isActive) {
957
+ visitedTabsSet.add(value);
958
+ }
959
+ }, [value, isActive]);
960
+ const shouldRender = visitedTabsSet.has(value) || isActive;
961
+ if (!shouldRender) {
962
+ return null;
963
+ }
964
+ const {
965
+ onDrag,
966
+ onDragStart,
967
+ onDragEnd,
968
+ onDragEnter,
969
+ onDragExit,
970
+ onDragLeave,
971
+ onDragOver,
972
+ onDrop,
973
+ onAnimationStart,
974
+ onAnimationEnd,
975
+ onAnimationIteration,
976
+ onTransitionEnd,
977
+ ...motionDivProps
978
+ } = props;
979
+ return /* @__PURE__ */ jsxRuntime.jsx(
980
+ react.motion.div,
981
+ {
982
+ role: "tabpanel",
983
+ "data-slot": "tabs-content",
984
+ className: chunkWUYS7DMR_cjs.cn("overflow-hidden", className),
985
+ initial: { filter: "blur(0px)" },
986
+ animate: { filter: isActive ? "blur(0px)" : "blur(2px)" },
987
+ exit: { filter: "blur(0px)" },
988
+ transition: { type: "spring", stiffness: 300, damping: 20 },
989
+ style: {
990
+ visibility: isActive ? "visible" : "hidden",
991
+ position: isActive ? "static" : "absolute",
992
+ width: isActive ? "100%" : "0",
993
+ height: isActive ? "auto" : "0",
994
+ overflow: isActive ? "visible" : "hidden"
995
+ },
996
+ "aria-hidden": !isActive,
997
+ ...motionDivProps,
998
+ children: props.children
999
+ }
1000
+ );
1001
+ }
317
1002
  return /* @__PURE__ */ jsxRuntime.jsx(
318
1003
  TabsPrimitive__namespace.Content,
319
1004
  {
320
1005
  "data-slot": "tabs-content",
321
- className: chunkWIBCOQPP_cjs.cn("flex-1 outline-none", className),
1006
+ className: chunkWUYS7DMR_cjs.cn("flex-1 outline-none", className),
322
1007
  ...props
323
1008
  }
324
1009
  );
325
1010
  }
326
- var TabIndexContext = React3__default.default.createContext(null);
1011
+ var TabIndexContext = React3__namespace.default.createContext(null);
327
1012
  var useTabIndex = () => {
328
1013
  const context = React3.useContext(TabIndexContext);
329
1014
  return context;
@@ -348,30 +1033,47 @@ var NavigationButtonsWrapper = ({
348
1033
  onReset,
349
1034
  isLoading,
350
1035
  isDraftSaving,
351
- config
1036
+ config,
1037
+ isProcessing = false,
1038
+ processingError = null
352
1039
  }) => {
353
1040
  const isLastTab = activeTab === totalTabs - 1;
354
1041
  const isFirstTab = activeTab === 0;
355
- return /* @__PURE__ */ jsxRuntime.jsx(
356
- NavigationButtons,
357
- {
358
- onPrevious,
359
- onNext,
360
- onSubmit,
361
- onSaveDraft,
362
- onReset,
363
- isLoading,
364
- isDraftSaving,
365
- config,
366
- isFirstTab,
367
- isLastTab
368
- }
369
- );
1042
+ const handlePrevious = isProcessing ? () => {
1043
+ } : onPrevious;
1044
+ const handleNext = isProcessing ? () => {
1045
+ } : onNext;
1046
+ const handleSubmit = isProcessing ? () => {
1047
+ } : onSubmit;
1048
+ const handleSaveDraft = isProcessing ? void 0 : onSaveDraft;
1049
+ const handleReset = isProcessing ? void 0 : onReset;
1050
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1051
+ /* @__PURE__ */ jsxRuntime.jsx(
1052
+ NavigationButtons,
1053
+ {
1054
+ onPrevious: handlePrevious,
1055
+ onNext: handleNext,
1056
+ onSubmit: handleSubmit,
1057
+ onSaveDraft: handleSaveDraft,
1058
+ onReset: handleReset,
1059
+ isLoading,
1060
+ isDraftSaving,
1061
+ config,
1062
+ isFirstTab,
1063
+ isLastTab,
1064
+ disabled: isProcessing
1065
+ }
1066
+ ),
1067
+ processingError && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-4 p-3 bg-red-50 border border-red-200 rounded-md text-red-700 text-sm", children: processingError })
1068
+ ] });
370
1069
  };
371
1070
  var MultiTabSmartForm = ({
372
1071
  children,
373
1072
  showProgressBar = true,
374
1073
  showTabNumbers = true,
1074
+ animateTabs = false,
1075
+ tabType = "default",
1076
+ disableManualTabSwitch = false,
375
1077
  ...baseProps
376
1078
  }) => {
377
1079
  const [activeTab, setActiveTab] = React3.useState(0);
@@ -379,8 +1081,10 @@ var MultiTabSmartForm = ({
379
1081
  const [completedTabs, setCompletedTabs] = React3.useState(/* @__PURE__ */ new Set());
380
1082
  const [validationErrorTabs, setValidationErrorTabs] = React3.useState(/* @__PURE__ */ new Set());
381
1083
  const [externalTabFields, setExternalTabFields] = React3.useState({});
1084
+ const [processingTab, setProcessingTab] = React3.useState(null);
1085
+ const [processingError, setProcessingError] = React3.useState(null);
382
1086
  const { footerChildren, regularChildren } = React3.useMemo(() => {
383
- const childArray = React3__default.default.Children.toArray(children);
1087
+ const childArray = React3__namespace.default.Children.toArray(children);
384
1088
  const footerChildren2 = [];
385
1089
  const regularChildren2 = [];
386
1090
  childArray.forEach((child) => {
@@ -393,8 +1097,8 @@ var MultiTabSmartForm = ({
393
1097
  return { footerChildren: footerChildren2, regularChildren: regularChildren2 };
394
1098
  }, [children]);
395
1099
  const tabs = [];
396
- React3__default.default.Children.forEach(regularChildren, (child) => {
397
- if (React3__default.default.isValidElement(child) && child.type === Tab) {
1100
+ React3__namespace.default.Children.forEach(regularChildren, (child) => {
1101
+ if (React3__namespace.default.isValidElement(child) && child.type === Tab) {
398
1102
  const props = child.props;
399
1103
  if (props.title) {
400
1104
  tabs.push(props.title);
@@ -403,8 +1107,8 @@ var MultiTabSmartForm = ({
403
1107
  });
404
1108
  const findSmartInputs = React3.useCallback((children2) => {
405
1109
  const fields = [];
406
- React3__default.default.Children.forEach(children2, (child) => {
407
- if (React3__default.default.isValidElement(child)) {
1110
+ React3__namespace.default.Children.forEach(children2, (child) => {
1111
+ if (React3__namespace.default.isValidElement(child)) {
408
1112
  const fieldProps = child.props;
409
1113
  if (fieldProps && typeof fieldProps === "object" && "field" in fieldProps && fieldProps.field) {
410
1114
  fields.push(fieldProps.field);
@@ -422,10 +1126,10 @@ var MultiTabSmartForm = ({
422
1126
  [tabIndex]: fields
423
1127
  }));
424
1128
  }, []);
425
- React3__default.default.useEffect(() => {
1129
+ React3__namespace.default.useEffect(() => {
426
1130
  const fields = [];
427
- React3__default.default.Children.forEach(regularChildren, (child) => {
428
- if (React3__default.default.isValidElement(child) && child.type === Tab) {
1131
+ React3__namespace.default.Children.forEach(regularChildren, (child) => {
1132
+ if (React3__namespace.default.isValidElement(child) && child.type === Tab) {
429
1133
  const tabFieldsInTab = findSmartInputs(child.props.children);
430
1134
  fields.push(tabFieldsInTab);
431
1135
  }
@@ -437,6 +1141,19 @@ var MultiTabSmartForm = ({
437
1141
  const externalFields = externalTabFields[tabIndex] || [];
438
1142
  return [...internalFields, ...externalFields];
439
1143
  }, [tabFields, externalTabFields]);
1144
+ const tabCallbacks = React3.useMemo(() => {
1145
+ const callbacks = [];
1146
+ React3__namespace.default.Children.forEach(regularChildren, (child) => {
1147
+ if (React3__namespace.default.isValidElement(child) && child.type === Tab) {
1148
+ const props = child.props;
1149
+ callbacks.push({
1150
+ onNext: props.onNext,
1151
+ processingOverlay: props.processingOverlay
1152
+ });
1153
+ }
1154
+ });
1155
+ return callbacks;
1156
+ }, [regularChildren]);
440
1157
  const config = {
441
1158
  ...baseProps,
442
1159
  showProgressBar,
@@ -474,6 +1191,14 @@ var MultiTabSmartForm = ({
474
1191
  validationErrorTabs,
475
1192
  setValidationErrorTabs,
476
1193
  footerChildren,
1194
+ animateTabs,
1195
+ tabType,
1196
+ tabCallbacks,
1197
+ processingTab,
1198
+ setProcessingTab,
1199
+ processingError,
1200
+ setProcessingError,
1201
+ disableManualTabSwitch,
477
1202
  children: regularChildren
478
1203
  }
479
1204
  ) }) });
@@ -491,11 +1216,17 @@ var MultiTabFormContent = ({
491
1216
  validationErrorTabs,
492
1217
  setValidationErrorTabs,
493
1218
  footerChildren,
494
- children
1219
+ children,
1220
+ animateTabs,
1221
+ tabType,
1222
+ tabCallbacks,
1223
+ processingTab,
1224
+ setProcessingTab,
1225
+ processingError,
1226
+ setProcessingError,
1227
+ disableManualTabSwitch = false
495
1228
  }) => {
496
- const { isLoading, isDraftSaving, submitForm, saveDraft, resetForm, validateFields, formData, validationRegistry, setErrors } = chunkWIBCOQPP_cjs.useSmartForm();
497
- const [maxContentHeight, setMaxContentHeight] = React3.useState(0);
498
- const contentRefs = React3.useRef([]);
1229
+ const { isLoading, isDraftSaving, submitForm, saveDraft, resetForm, validateFields, formData, validationRegistry, setErrors } = chunkWUYS7DMR_cjs.useSmartForm();
499
1230
  const debounce = (func, wait) => {
500
1231
  let timeout;
501
1232
  return function executedFunction(...args) {
@@ -507,27 +1238,7 @@ var MultiTabFormContent = ({
507
1238
  timeout = setTimeout(later, wait);
508
1239
  };
509
1240
  };
510
- React3__default.default.useEffect(() => {
511
- const calculateMaxHeight = () => {
512
- let maxHeight = 0;
513
- contentRefs.current.forEach((ref) => {
514
- if (ref) {
515
- const height = ref.scrollHeight;
516
- maxHeight = Math.max(maxHeight, height);
517
- }
518
- });
519
- if (maxHeight > 0) {
520
- setMaxContentHeight(maxHeight);
521
- }
522
- };
523
- const timeoutId = setTimeout(calculateMaxHeight, 100);
524
- window.addEventListener("resize", calculateMaxHeight);
525
- return () => {
526
- clearTimeout(timeoutId);
527
- window.removeEventListener("resize", calculateMaxHeight);
528
- };
529
- }, [children, activeTab]);
530
- React3__default.default.useEffect(() => {
1241
+ React3__namespace.default.useEffect(() => {
531
1242
  const checkTabCompletion = debounce(() => {
532
1243
  tabs.forEach((_, tabIndex) => {
533
1244
  const tabFieldsInTab = getCombinedTabFields(tabIndex);
@@ -577,9 +1288,12 @@ var MultiTabFormContent = ({
577
1288
  checkTabCompletion();
578
1289
  }, [formData, validationRegistry, getCombinedTabFields, tabs, setCompletedTabs, setValidationErrorTabs]);
579
1290
  const handleTabChangeWithErrorCheck = React3.useCallback((index) => {
1291
+ if (disableManualTabSwitch && index > activeTab) {
1292
+ return;
1293
+ }
580
1294
  onTabChange(index);
581
- }, [onTabChange]);
582
- const handleNextWithValidation = React3.useCallback(() => {
1295
+ }, [onTabChange, disableManualTabSwitch, activeTab]);
1296
+ const handleNextWithValidation = React3.useCallback(async () => {
583
1297
  const currentTabFields = getCombinedTabFields(activeTab);
584
1298
  if (currentTabFields.length > 0) {
585
1299
  const allErrors = {};
@@ -604,7 +1318,26 @@ var MultiTabFormContent = ({
604
1318
  newSet.delete(activeTab);
605
1319
  return newSet;
606
1320
  });
607
- onNext();
1321
+ const currentTabCallback = tabCallbacks[activeTab];
1322
+ if (currentTabCallback?.onNext) {
1323
+ try {
1324
+ setProcessingTab(activeTab);
1325
+ setProcessingError(null);
1326
+ const result = currentTabCallback.onNext();
1327
+ if (result instanceof Promise) {
1328
+ await result;
1329
+ }
1330
+ setProcessingTab(null);
1331
+ setProcessingError(null);
1332
+ onNext();
1333
+ } catch (error) {
1334
+ setProcessingTab(null);
1335
+ const errorMessage = error instanceof Error ? error.message : "An error occurred while processing";
1336
+ setProcessingError(errorMessage);
1337
+ }
1338
+ } else {
1339
+ onNext();
1340
+ }
608
1341
  } else {
609
1342
  setCompletedTabs((prev) => {
610
1343
  const newSet = new Set(prev);
@@ -625,9 +1358,28 @@ var MultiTabFormContent = ({
625
1358
  }
626
1359
  }
627
1360
  } else {
628
- onNext();
1361
+ const currentTabCallback = tabCallbacks[activeTab];
1362
+ if (currentTabCallback?.onNext) {
1363
+ try {
1364
+ setProcessingTab(activeTab);
1365
+ setProcessingError(null);
1366
+ const result = currentTabCallback.onNext();
1367
+ if (result instanceof Promise) {
1368
+ await result;
1369
+ }
1370
+ setProcessingTab(null);
1371
+ setProcessingError(null);
1372
+ onNext();
1373
+ } catch (error) {
1374
+ setProcessingTab(null);
1375
+ const errorMessage = error instanceof Error ? error.message : "An error occurred while processing";
1376
+ setProcessingError(errorMessage);
1377
+ }
1378
+ } else {
1379
+ onNext();
1380
+ }
629
1381
  }
630
- }, [activeTab, getCombinedTabFields, validateFields, onNext, setCompletedTabs, setValidationErrorTabs, validationRegistry, formData]);
1382
+ }, [activeTab, getCombinedTabFields, validateFields, onNext, setCompletedTabs, setValidationErrorTabs, validationRegistry, formData, tabCallbacks, setProcessingTab, setProcessingError]);
631
1383
  const handleSubmitWithValidation = React3.useCallback(async () => {
632
1384
  const allErrors = {};
633
1385
  let isValid = true;
@@ -677,55 +1429,70 @@ var MultiTabFormContent = ({
677
1429
  }, [submitForm, getCombinedTabFields, onTabChange, tabs.length, validationRegistry, formData, setErrors, setValidationErrorTabs]);
678
1430
  const activeTabValue = tabs[activeTab] || tabs[0] || "";
679
1431
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
680
- /* @__PURE__ */ jsxRuntime.jsxs(Tabs, { value: activeTabValue, onValueChange: (value) => {
681
- const newIndex = tabs.indexOf(value);
682
- if (newIndex !== -1) {
683
- handleTabChangeWithErrorCheck(newIndex);
684
- }
685
- }, className: "w-full", children: [
686
- /* @__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: [
687
- config.showTabNumbers && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
688
- index + 1,
689
- "."
690
- ] }),
691
- tab,
692
- completedTabs.has(index) && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-4 w-4 text-green-600" }),
693
- validationErrorTabs.has(index) && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4 text-red-600" })
694
- ] }, tab)) }),
695
- React3__default.default.Children.map(children, (child, index) => {
696
- if (React3__default.default.isValidElement(child) && child.type === Tab) {
697
- const tabProps = child.props;
698
- return /* @__PURE__ */ jsxRuntime.jsx(TabsContent, { value: tabProps.title, children: /* @__PURE__ */ jsxRuntime.jsx(TabIndexProvider, { tabIndex: index, children: /* @__PURE__ */ jsxRuntime.jsx(
699
- "div",
700
- {
701
- ref: (el) => {
702
- contentRefs.current[index] = el;
1432
+ /* @__PURE__ */ jsxRuntime.jsxs(
1433
+ Tabs,
1434
+ {
1435
+ value: activeTabValue,
1436
+ onValueChange: (value) => {
1437
+ const newIndex = tabs.indexOf(value);
1438
+ if (newIndex !== -1) {
1439
+ handleTabChangeWithErrorCheck(newIndex);
1440
+ }
1441
+ },
1442
+ className: "w-full",
1443
+ animate: animateTabs,
1444
+ type: tabType,
1445
+ children: [
1446
+ /* @__PURE__ */ jsxRuntime.jsx(TabsList, { className: `grid w-full mb-8`, style: { gridTemplateColumns: `repeat(${tabs.length}, 1fr)` }, children: tabs.map((tab, index) => {
1447
+ const isFutureTab = disableManualTabSwitch && index > activeTab;
1448
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1449
+ TabsTrigger,
1450
+ {
1451
+ value: tab,
1452
+ disabled: isFutureTab,
1453
+ className: `flex items-center gap-2 ${isFutureTab ? "opacity-50 cursor-not-allowed" : ""}`,
1454
+ children: [
1455
+ config.showTabNumbers && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
1456
+ index + 1,
1457
+ "."
1458
+ ] }),
1459
+ tab,
1460
+ completedTabs.has(index) && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Check, { className: "h-4 w-4 text-green-600" }),
1461
+ validationErrorTabs.has(index) && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.X, { className: "h-4 w-4 text-red-600" })
1462
+ ]
703
1463
  },
704
- className: "space-y-6",
705
- style: { minHeight: maxContentHeight > 0 ? `${maxContentHeight}px` : void 0 },
706
- children: tabProps.children
1464
+ tab
1465
+ );
1466
+ }) }),
1467
+ React3__namespace.default.Children.map(children, (child, index) => {
1468
+ if (React3__namespace.default.isValidElement(child) && child.type === Tab) {
1469
+ const tabProps = child.props;
1470
+ const isCurrentlyProcessing = processingTab === index;
1471
+ const hasProcessingOverlay = tabCallbacks[index]?.processingOverlay;
1472
+ return /* @__PURE__ */ jsxRuntime.jsx(TabsContent, { value: tabProps.title, children: /* @__PURE__ */ jsxRuntime.jsx(TabIndexProvider, { tabIndex: index, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-6 relative", children: [
1473
+ tabProps.children,
1474
+ isCurrentlyProcessing && hasProcessingOverlay && /* @__PURE__ */ jsxRuntime.jsx(
1475
+ "div",
1476
+ {
1477
+ className: "absolute inset-0 bg-white/80 backdrop-blur-sm z-50 flex items-center justify-center pointer-events-none",
1478
+ style: { minHeight: "200px" },
1479
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-auto", children: tabCallbacks[index].processingOverlay })
1480
+ }
1481
+ )
1482
+ ] }) }) }, index);
707
1483
  }
708
- ) }) }, index);
709
- }
710
- return null;
711
- }),
712
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { position: "absolute", left: "-9999px", top: "-9999px", visibility: "hidden" }, children: React3__default.default.Children.map(children, (child, index) => {
713
- if (React3__default.default.isValidElement(child) && child.type === Tab) {
714
- const tabProps = child.props;
715
- return /* @__PURE__ */ jsxRuntime.jsx(TabIndexProvider, { tabIndex: index, children: /* @__PURE__ */ jsxRuntime.jsx(
716
- "div",
717
- {
718
- ref: (el) => {
719
- contentRefs.current[index] = el;
720
- },
721
- className: "space-y-6",
722
- children: tabProps.children
1484
+ return null;
1485
+ }),
1486
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { position: "absolute", left: "-9999px", top: "-9999px", visibility: "hidden" }, children: React3__namespace.default.Children.map(children, (child, index) => {
1487
+ if (React3__namespace.default.isValidElement(child) && child.type === Tab) {
1488
+ const tabProps = child.props;
1489
+ return /* @__PURE__ */ jsxRuntime.jsx(TabIndexProvider, { tabIndex: index, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-6", children: tabProps.children }) }, `hidden-${index}`);
723
1490
  }
724
- ) }, `hidden-${index}`);
725
- }
726
- return null;
727
- }) })
728
- ] }),
1491
+ return null;
1492
+ }) })
1493
+ ]
1494
+ }
1495
+ ),
729
1496
  /* @__PURE__ */ jsxRuntime.jsx(
730
1497
  NavigationButtonsWrapper,
731
1498
  {
@@ -738,7 +1505,9 @@ var MultiTabFormContent = ({
738
1505
  onReset: config.showReset || config.enableLocalStorage ? resetForm : void 0,
739
1506
  isLoading,
740
1507
  isDraftSaving,
741
- config
1508
+ config,
1509
+ isProcessing: processingTab === activeTab,
1510
+ processingError
742
1511
  }
743
1512
  ),
744
1513
  footerChildren.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-4", children: footerChildren }),
@@ -763,7 +1532,7 @@ var MultiTabFormContent = ({
763
1532
 
764
1533
  // src/hooks/useFormWrapper.ts
765
1534
  var useFormWrapper = () => {
766
- return chunkWIBCOQPP_cjs.useSmartForm();
1535
+ return chunkWUYS7DMR_cjs.useSmartForm();
767
1536
  };
768
1537
  var useExternalFormRegistration = () => {
769
1538
  const context = React3.useContext(ExternalFormContext);
@@ -785,7 +1554,7 @@ var ExternalFieldProvider = ({
785
1554
  children,
786
1555
  registerField
787
1556
  }) => {
788
- return /* @__PURE__ */ jsxRuntime.jsx(chunkWIBCOQPP_cjs.FieldDetectionContext.Provider, { value: { registerField }, children });
1557
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkWUYS7DMR_cjs.FieldDetectionContext.Provider, { value: { registerField }, children });
789
1558
  };
790
1559
 
791
1560
  // src/useAutoDetectFields.tsx
@@ -850,50 +1619,177 @@ var FormFieldGroup = ({
850
1619
  }) => {
851
1620
  return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `flex flex-wrap gap-2 md:gap-4 mb-4 ${className}`, children });
852
1621
  };
1622
+ var SmartTextArea = ({
1623
+ field,
1624
+ label,
1625
+ rows = 4,
1626
+ placeholder,
1627
+ validation,
1628
+ className = "",
1629
+ required = false,
1630
+ defaultValue,
1631
+ syncValue,
1632
+ info,
1633
+ subLabel,
1634
+ disabled,
1635
+ hidden,
1636
+ charSize,
1637
+ autoFocus,
1638
+ autoComplete,
1639
+ autoCorrect,
1640
+ autoCapitalize,
1641
+ spellCheck,
1642
+ readOnly,
1643
+ wrap,
1644
+ cols,
1645
+ maxLength,
1646
+ minLength,
1647
+ name,
1648
+ dirName,
1649
+ form
1650
+ }) => {
1651
+ const { formData } = chunkWUYS7DMR_cjs.useSmartForm();
1652
+ const { value, error, onChange, fieldRef, registerValidation } = chunkWUYS7DMR_cjs.useFormField(field);
1653
+ const fieldDetection = chunkWUYS7DMR_cjs.useFieldDetection();
1654
+ const hasRegistered = React3.useRef(false);
1655
+ const hasSetDefault = React3.useRef(false);
1656
+ const isDisabled = typeof disabled === "function" ? disabled(formData) : disabled || false;
1657
+ const isHidden = typeof hidden === "function" ? hidden(formData) : hidden || false;
1658
+ if (isHidden) return null;
1659
+ React3.useEffect(() => {
1660
+ if (validation && !hasRegistered.current) {
1661
+ hasRegistered.current = true;
1662
+ registerValidation(field, validation);
1663
+ }
1664
+ }, [validation, field, registerValidation]);
1665
+ React3.useEffect(() => {
1666
+ if (fieldDetection?.registerField) {
1667
+ fieldDetection.registerField(field);
1668
+ }
1669
+ }, [field, fieldDetection]);
1670
+ React3.useEffect(() => {
1671
+ if (defaultValue !== void 0 && !hasSetDefault.current && (value === void 0 || value === null || value === "")) {
1672
+ onChange(defaultValue);
1673
+ hasSetDefault.current = true;
1674
+ }
1675
+ }, [defaultValue, value, onChange]);
1676
+ const prevSyncValue = React3.useRef(syncValue);
1677
+ React3.useEffect(() => {
1678
+ if (syncValue !== void 0 && syncValue !== prevSyncValue.current) {
1679
+ onChange(syncValue);
1680
+ prevSyncValue.current = syncValue;
1681
+ }
1682
+ }, [syncValue, onChange]);
1683
+ const getPlaceholder = () => {
1684
+ if (placeholder) return placeholder;
1685
+ if (!label) return `Enter ${field}`;
1686
+ return `Enter ${label.toLowerCase()}`;
1687
+ };
1688
+ const currentLength = value ? String(value).length : 0;
1689
+ const maxChars = charSize || maxLength;
1690
+ const showCharCount = maxChars !== void 0;
1691
+ const handleChange = (e) => {
1692
+ const newValue = e.target.value;
1693
+ if (charSize && newValue.length > charSize) {
1694
+ return;
1695
+ }
1696
+ onChange(newValue);
1697
+ };
1698
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex-1 min-w-0 ${className}`, children: [
1699
+ label && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-1", children: [
1700
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
1701
+ /* @__PURE__ */ jsxRuntime.jsxs(chunkWUYS7DMR_cjs.Label, { className: "text-sm font-medium text-foreground", children: [
1702
+ label,
1703
+ " ",
1704
+ required && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-destructive", children: "*" })
1705
+ ] }),
1706
+ info && /* @__PURE__ */ jsxRuntime.jsx(chunkWUYS7DMR_cjs.TooltipProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(chunkWUYS7DMR_cjs.Tooltip, { children: [
1707
+ /* @__PURE__ */ jsxRuntime.jsx(chunkWUYS7DMR_cjs.TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.InfoIcon, { className: "h-4 w-4 text-muted-foreground cursor-pointer" }) }),
1708
+ /* @__PURE__ */ jsxRuntime.jsx(chunkWUYS7DMR_cjs.TooltipContent, { children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "max-w-xs", children: info }) })
1709
+ ] }) })
1710
+ ] }),
1711
+ subLabel && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground mt-1", children: subLabel })
1712
+ ] }),
1713
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
1714
+ /* @__PURE__ */ jsxRuntime.jsx(
1715
+ chunkWUYS7DMR_cjs.Textarea,
1716
+ {
1717
+ ref: fieldRef,
1718
+ value: value || "",
1719
+ onChange: handleChange,
1720
+ className: `w-full ${error ? "border-destructive" : ""} ${showCharCount ? "pb-8" : ""}`,
1721
+ placeholder: getPlaceholder(),
1722
+ rows,
1723
+ "data-field": field,
1724
+ disabled: isDisabled,
1725
+ autoFocus,
1726
+ autoComplete,
1727
+ autoCorrect,
1728
+ autoCapitalize,
1729
+ spellCheck,
1730
+ readOnly,
1731
+ wrap,
1732
+ cols,
1733
+ maxLength,
1734
+ minLength,
1735
+ name,
1736
+ dirName,
1737
+ form
1738
+ }
1739
+ ),
1740
+ showCharCount && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-2 right-2 pointer-events-none", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { className: `text-xs bg-background/80 px-1.5 py-0.5 rounded ${currentLength > (maxChars || 0) ? "text-destructive" : currentLength > (maxChars || 0) * 0.9 ? "text-yellow-600" : "text-muted-foreground"}`, children: [
1741
+ currentLength,
1742
+ "/",
1743
+ maxChars
1744
+ ] }) })
1745
+ ] }),
1746
+ error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-destructive text-sm mt-1", children: error })
1747
+ ] });
1748
+ };
853
1749
 
854
1750
  Object.defineProperty(exports, "SmartCheckbox", {
855
1751
  enumerable: true,
856
- get: function () { return chunkNVGQPR3P_cjs.SmartCheckbox; }
1752
+ get: function () { return chunkDRMVY7TX_cjs.SmartCheckbox; }
857
1753
  });
858
1754
  Object.defineProperty(exports, "SmartCombobox", {
859
1755
  enumerable: true,
860
- get: function () { return chunkNVGQPR3P_cjs.SmartCombobox; }
1756
+ get: function () { return chunkDRMVY7TX_cjs.SmartCombobox; }
861
1757
  });
862
1758
  Object.defineProperty(exports, "SmartDatePicker", {
863
1759
  enumerable: true,
864
- get: function () { return chunkNVGQPR3P_cjs.SmartDatePicker; }
1760
+ get: function () { return chunkDRMVY7TX_cjs.SmartDatePicker; }
865
1761
  });
866
1762
  Object.defineProperty(exports, "SmartRadioGroup", {
867
1763
  enumerable: true,
868
- get: function () { return chunkNVGQPR3P_cjs.SmartRadioGroup; }
1764
+ get: function () { return chunkDRMVY7TX_cjs.SmartRadioGroup; }
869
1765
  });
870
1766
  Object.defineProperty(exports, "SmartSelect", {
871
1767
  enumerable: true,
872
- get: function () { return chunkNVGQPR3P_cjs.SmartSelect; }
1768
+ get: function () { return chunkDRMVY7TX_cjs.SmartSelect; }
873
1769
  });
874
1770
  Object.defineProperty(exports, "SmartTags", {
875
1771
  enumerable: true,
876
- get: function () { return chunkNVGQPR3P_cjs.SmartTags; }
1772
+ get: function () { return chunkDRMVY7TX_cjs.SmartTags; }
877
1773
  });
878
1774
  Object.defineProperty(exports, "SmartFormProvider", {
879
1775
  enumerable: true,
880
- get: function () { return chunkWIBCOQPP_cjs.SmartFormProvider; }
1776
+ get: function () { return chunkWUYS7DMR_cjs.SmartFormProvider; }
881
1777
  });
882
1778
  Object.defineProperty(exports, "SmartInput", {
883
1779
  enumerable: true,
884
- get: function () { return chunkWIBCOQPP_cjs.SmartInput; }
1780
+ get: function () { return chunkWUYS7DMR_cjs.SmartInput; }
885
1781
  });
886
1782
  Object.defineProperty(exports, "useFieldDetection", {
887
1783
  enumerable: true,
888
- get: function () { return chunkWIBCOQPP_cjs.useFieldDetection; }
1784
+ get: function () { return chunkWUYS7DMR_cjs.useFieldDetection; }
889
1785
  });
890
1786
  Object.defineProperty(exports, "useFormField", {
891
1787
  enumerable: true,
892
- get: function () { return chunkWIBCOQPP_cjs.useFormField; }
1788
+ get: function () { return chunkWUYS7DMR_cjs.useFormField; }
893
1789
  });
894
1790
  Object.defineProperty(exports, "useSmartForm", {
895
1791
  enumerable: true,
896
- get: function () { return chunkWIBCOQPP_cjs.useSmartForm; }
1792
+ get: function () { return chunkWUYS7DMR_cjs.useSmartForm; }
897
1793
  });
898
1794
  exports.BaseSmartForm = BaseSmartForm;
899
1795
  exports.DraftSaveButton = DraftSaveButton;
@@ -908,6 +1804,7 @@ exports.ResetButton = ResetButton;
908
1804
  exports.Section = Section;
909
1805
  exports.SimpleFormButtons = SimpleFormButtons;
910
1806
  exports.SmartForm = SmartForm;
1807
+ exports.SmartTextArea = SmartTextArea;
911
1808
  exports.SubmitButton = SubmitButton;
912
1809
  exports.Tab = Tab;
913
1810
  exports.TabIndexProvider = TabIndexProvider;