@object-ui/plugin-form 2.0.0 → 3.0.1

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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @object-ui/plugin-form@2.0.0 build /home/runner/work/objectui/objectui/packages/plugin-form
2
+ > @object-ui/plugin-form@3.0.1 build /home/runner/work/objectui/objectui/packages/plugin-form
3
3
  > vite build
4
4
 
5
5
  vite v7.3.1 building client environment for production...
@@ -9,13 +9,22 @@ rendering chunks...
9
9
  
10
10
  [vite:dts] Start generate declaration files...
11
11
  computing gzip size...
12
- dist/index.js 53.42 kB gzip: 10.72 kB
13
- [vite:dts] Declaration files built in 19110ms.
12
+ ../../examples/crm/src/objects/contact.object.ts:3:14 - error TS2742: The inferred type of 'ContactObject' cannot be named without a reference to 'examples/crm/node_modules/@objectstack/spec/dist/state-machine.zod-DoC0JvQb'. This is likely not portable. A type annotation is necessary.
13
+
14
+ 3 export const ContactObject = ObjectSchema.create({
15
+    ~~~~~~~~~~~~~
16
+ src/ObjectForm.stories.tsx:4:43 - error TS2307: Cannot find module '@storybook-config/datasource' or its corresponding type declarations.
17
+
18
+ 4 import { createStorybookDataSource } from '@storybook-config/datasource';
19
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
20
+
21
+ dist/index.js 53.50 kB │ gzip: 10.77 kB
22
+ [vite:dts] Declaration files built in 22556ms.
14
23
  
15
24
  No name was provided for external module "@object-ui/core" in "output.globals" – guessing "core".
16
25
  No name was provided for external module "@object-ui/react" in "output.globals" – guessing "react".
17
26
  No name was provided for external module "@object-ui/fields" in "output.globals" – guessing "fields".
18
27
  No name was provided for external module "@object-ui/components" in "output.globals" – guessing "components".
19
28
  No name was provided for external module "lucide-react" in "output.globals" – guessing "lucideReact".
20
- dist/index.umd.cjs 36.10 kB │ gzip: 9.01 kB
21
- ✓ built in 20.60s
29
+ dist/index.umd.cjs 36.18 kB │ gzip: 9.06 kB
30
+ ✓ built in 23.98s
package/CHANGELOG.md CHANGED
@@ -1,5 +1,37 @@
1
1
  # @object-ui/plugin-form
2
2
 
3
+ ## 3.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [adf2cc0]
8
+ - @object-ui/react@3.0.1
9
+ - @object-ui/components@3.0.1
10
+ - @object-ui/fields@3.0.1
11
+ - @object-ui/types@3.0.1
12
+ - @object-ui/core@3.0.1
13
+
14
+ ## 3.0.0
15
+
16
+ ### Minor Changes
17
+
18
+ - 87979c3: Upgrade to @objectstack v3.0.0 and console bundle optimization
19
+ - Upgraded all @objectstack/\* packages from ^2.0.7 to ^3.0.0
20
+ - Breaking change migrations: Hub → Cloud namespace, definePlugin removed, PaginatedResult.value → .records, PaginatedResult.count → .total, client.meta.getObject() → client.meta.getItem()
21
+ - Console bundle optimization: split monolithic 3.7 MB chunk into 17 granular cacheable chunks (95% main entry reduction)
22
+ - Added gzip + brotli pre-compression via vite-plugin-compression2
23
+ - Lazy MSW loading for build:server (~150 KB gzip saved)
24
+ - Added bundle analysis with rollup-plugin-visualizer
25
+
26
+ ### Patch Changes
27
+
28
+ - Updated dependencies [87979c3]
29
+ - @object-ui/types@3.0.0
30
+ - @object-ui/core@3.0.0
31
+ - @object-ui/react@3.0.0
32
+ - @object-ui/components@3.0.0
33
+ - @object-ui/fields@3.0.0
34
+
3
35
  ## 2.0.0
4
36
 
5
37
  ### Major Changes
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import { cn as V, Tabs as je, TabsList as ge, TabsTrigger as we, TabsContent as
6
6
  import { ChevronRight as pe, ChevronDown as ze, Check as Pe, ChevronLeft as Le } from "lucide-react";
7
7
  var ee = { exports: {} }, B = {};
8
8
  var ae;
9
- function Ae() {
9
+ function he() {
10
10
  if (ae) return B;
11
11
  ae = 1;
12
12
  var e = /* @__PURE__ */ Symbol.for("react.transitional.element"), l = /* @__PURE__ */ Symbol.for("react.fragment");
@@ -29,7 +29,7 @@ function Ae() {
29
29
  }
30
30
  var X = {};
31
31
  var de;
32
- function he() {
32
+ function Ae() {
33
33
  return de || (de = 1, process.env.NODE_ENV !== "production" && (function() {
34
34
  function e(r) {
35
35
  if (r == null) return null;
@@ -54,7 +54,7 @@ function he() {
54
54
  switch (typeof r.tag == "number" && console.error(
55
55
  "Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."
56
56
  ), r.$$typeof) {
57
- case h:
57
+ case A:
58
58
  return "Portal";
59
59
  case s:
60
60
  return r.displayName || "Context";
@@ -121,7 +121,7 @@ function he() {
121
121
  }
122
122
  function E(r, m) {
123
123
  function O() {
124
- A || (A = !0, console.error(
124
+ h || (h = !0, console.error(
125
125
  "%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",
126
126
  m
127
127
  ));
@@ -224,7 +224,7 @@ React keys must be passed directly to JSX without using spread:
224
224
  function N(r) {
225
225
  return typeof r == "object" && r !== null && r.$$typeof === P;
226
226
  }
227
- var D = J, P = /* @__PURE__ */ Symbol.for("react.transitional.element"), h = /* @__PURE__ */ Symbol.for("react.portal"), F = /* @__PURE__ */ Symbol.for("react.fragment"), _ = /* @__PURE__ */ Symbol.for("react.strict_mode"), q = /* @__PURE__ */ Symbol.for("react.profiler"), u = /* @__PURE__ */ Symbol.for("react.consumer"), s = /* @__PURE__ */ Symbol.for("react.context"), n = /* @__PURE__ */ Symbol.for("react.forward_ref"), o = /* @__PURE__ */ Symbol.for("react.suspense"), a = /* @__PURE__ */ Symbol.for("react.suspense_list"), c = /* @__PURE__ */ Symbol.for("react.memo"), i = /* @__PURE__ */ Symbol.for("react.lazy"), v = /* @__PURE__ */ Symbol.for("react.activity"), $ = /* @__PURE__ */ Symbol.for("react.client.reference"), p = D.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, x = Object.prototype.hasOwnProperty, R = Array.isArray, L = console.createTask ? console.createTask : function() {
227
+ var D = J, P = /* @__PURE__ */ Symbol.for("react.transitional.element"), A = /* @__PURE__ */ Symbol.for("react.portal"), F = /* @__PURE__ */ Symbol.for("react.fragment"), _ = /* @__PURE__ */ Symbol.for("react.strict_mode"), q = /* @__PURE__ */ Symbol.for("react.profiler"), u = /* @__PURE__ */ Symbol.for("react.consumer"), s = /* @__PURE__ */ Symbol.for("react.context"), n = /* @__PURE__ */ Symbol.for("react.forward_ref"), o = /* @__PURE__ */ Symbol.for("react.suspense"), a = /* @__PURE__ */ Symbol.for("react.suspense_list"), c = /* @__PURE__ */ Symbol.for("react.memo"), i = /* @__PURE__ */ Symbol.for("react.lazy"), v = /* @__PURE__ */ Symbol.for("react.activity"), $ = /* @__PURE__ */ Symbol.for("react.client.reference"), p = D.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, x = Object.prototype.hasOwnProperty, R = Array.isArray, L = console.createTask ? console.createTask : function() {
228
228
  return null;
229
229
  };
230
230
  D = {
@@ -232,7 +232,7 @@ React keys must be passed directly to JSX without using spread:
232
232
  return r();
233
233
  }
234
234
  };
235
- var A, le = {}, ne = D.react_stack_bottom_frame.bind(
235
+ var h, le = {}, ne = D.react_stack_bottom_frame.bind(
236
236
  D,
237
237
  b
238
238
  )(), ie = L(d(b)), oe = {};
@@ -261,7 +261,7 @@ React keys must be passed directly to JSX without using spread:
261
261
  }
262
262
  var ce;
263
263
  function Ve() {
264
- return ce || (ce = 1, process.env.NODE_ENV === "production" ? ee.exports = Ae() : ee.exports = he()), ee.exports;
264
+ return ce || (ce = 1, process.env.NODE_ENV === "production" ? ee.exports = he() : ee.exports = Ae()), ee.exports;
265
265
  }
266
266
  var t = Ve();
267
267
  const G = ({
@@ -378,7 +378,7 @@ const G = ({
378
378
  } catch (n) {
379
379
  throw e.onError && e.onError(n), n;
380
380
  }
381
- }, [e, l]), h = k(() => {
381
+ }, [e, l]), A = k(() => {
382
382
  e.onCancel && e.onCancel();
383
383
  }, [e]), F = (s, n) => s.name || s.label || `tab-${n}`;
384
384
  if (C)
@@ -401,7 +401,7 @@ const G = ({
401
401
  showSubmit: e.showSubmit !== !1 && e.mode !== "view",
402
402
  showCancel: e.showCancel !== !1,
403
403
  onSubmit: P,
404
- onCancel: h
404
+ onCancel: A
405
405
  }, u = e.tabPosition === "left" || e.tabPosition === "right";
406
406
  return /* @__PURE__ */ t.jsx("div", { className: V("w-full", f, e.className), children: /* @__PURE__ */ t.jsxs(
407
407
  je,
@@ -459,7 +459,7 @@ const G = ({
459
459
  dataSource: l,
460
460
  className: f
461
461
  }) => {
462
- const [d, w] = g(null), [b, T] = g({}), [E, S] = g(!0), [C, j] = g(null), [y, N] = g(0), [D, P] = g(/* @__PURE__ */ new Set()), [h, F] = g(!1), _ = e.sections.length, q = y === 0, u = y === _ - 1;
462
+ const [d, w] = g(null), [b, T] = g({}), [E, S] = g(!0), [C, j] = g(null), [y, N] = g(0), [D, P] = g(/* @__PURE__ */ new Set()), [A, F] = g(!1), _ = e.sections.length, q = y === 0, u = y === _ - 1;
463
463
  J.useEffect(() => {
464
464
  (async () => {
465
465
  if (!l) {
@@ -496,19 +496,19 @@ const G = ({
496
496
  if (typeof R == "object")
497
497
  x.push(R);
498
498
  else if (d?.fields?.[L]) {
499
- const A = d.fields[L];
499
+ const h = d.fields[L];
500
500
  x.push({
501
501
  name: L,
502
- label: A.label || L,
503
- type: U(A.type),
504
- required: A.required || !1,
505
- disabled: e.readOnly || e.mode === "view" || A.readonly,
506
- placeholder: A.placeholder,
507
- description: A.help || A.description,
508
- validation: Y(A),
509
- field: A,
510
- options: A.options,
511
- multiple: A.multiple
502
+ label: h.label || L,
503
+ type: U(h.type),
504
+ required: h.required || !1,
505
+ disabled: e.readOnly || e.mode === "view" || h.readonly,
506
+ placeholder: h.placeholder,
507
+ description: h.help || h.description,
508
+ validation: Y(h),
509
+ field: h,
510
+ options: h.options,
511
+ multiple: h.multiple
512
512
  });
513
513
  } else
514
514
  x.push({
@@ -556,7 +556,7 @@ const G = ({
556
556
  const $ = e.sections[y];
557
557
  return /* @__PURE__ */ t.jsxs("div", { className: V("w-full", f, e.className), children: [
558
558
  e.showStepIndicator !== !1 && /* @__PURE__ */ t.jsx("nav", { "aria-label": "Progress", className: "mb-8", children: /* @__PURE__ */ t.jsx("ol", { className: "flex items-center", children: e.sections.map((p, x) => {
559
- const R = x === y, L = D.has(x), A = e.allowSkip || L || x <= y;
559
+ const R = x === y, L = D.has(x), h = e.allowSkip || L || x <= y;
560
560
  return /* @__PURE__ */ t.jsxs(
561
561
  "li",
562
562
  {
@@ -568,7 +568,7 @@ const G = ({
568
568
  x !== _ - 1 && /* @__PURE__ */ t.jsx(
569
569
  "div",
570
570
  {
571
- className: "absolute top-4 left-8 -right-4 sm:left-10 sm:-right-2 h-0.5",
571
+ className: "absolute top-3 sm:top-4 left-6 -right-4 sm:left-10 sm:-right-2 h-0.5",
572
572
  "aria-hidden": "true",
573
573
  children: /* @__PURE__ */ t.jsx(
574
574
  "div",
@@ -587,24 +587,24 @@ const G = ({
587
587
  type: "button",
588
588
  className: V(
589
589
  "group relative flex items-center",
590
- A ? "cursor-pointer" : "cursor-not-allowed"
590
+ h ? "cursor-pointer" : "cursor-not-allowed"
591
591
  ),
592
592
  onClick: () => v(x),
593
- disabled: !A,
593
+ disabled: !h,
594
594
  children: [
595
595
  /* @__PURE__ */ t.jsx(
596
596
  "span",
597
597
  {
598
598
  className: V(
599
- "flex h-8 w-8 items-center justify-center rounded-full text-sm font-medium transition-colors",
599
+ "flex h-6 w-6 sm:h-8 sm:w-8 items-center justify-center rounded-full text-xs sm:text-sm font-medium transition-colors",
600
600
  L && "bg-primary text-primary-foreground",
601
601
  R && !L && "border-2 border-primary bg-background text-primary",
602
602
  !R && !L && "border-2 border-muted bg-background text-muted-foreground"
603
603
  ),
604
- children: L ? /* @__PURE__ */ t.jsx(Pe, { className: "h-4 w-4" }) : x + 1
604
+ children: L ? /* @__PURE__ */ t.jsx(Pe, { className: "h-3 w-3 sm:h-4 sm:w-4" }) : x + 1
605
605
  }
606
606
  ),
607
- /* @__PURE__ */ t.jsx("span", { className: "ml-3 text-sm font-medium hidden sm:block", children: /* @__PURE__ */ t.jsx(
607
+ /* @__PURE__ */ t.jsx("span", { className: "ml-2 sm:ml-3 text-xs sm:text-sm font-medium hidden sm:block", children: /* @__PURE__ */ t.jsx(
608
608
  "span",
609
609
  {
610
610
  className: V(
@@ -674,8 +674,8 @@ const G = ({
674
674
  K,
675
675
  {
676
676
  onClick: () => o(b),
677
- disabled: h || e.mode === "view",
678
- children: h ? "Submitting..." : e.submitText || (e.mode === "create" ? "Create" : "Update")
677
+ disabled: A || e.mode === "view",
678
+ children: A ? "Submitting..." : e.submitText || (e.mode === "create" ? "Create" : "Update")
679
679
  }
680
680
  ) : /* @__PURE__ */ t.jsxs(
681
681
  K,
@@ -769,7 +769,7 @@ const G = ({
769
769
  }
770
770
  }, [e, l]), D = k(() => {
771
771
  e.onCancel && e.onCancel();
772
- }, [e]), P = Q(() => e.sections.slice(0, 1), [e.sections]), h = Q(() => e.sections.slice(1), [e.sections]);
772
+ }, [e]), P = Q(() => e.sections.slice(0, 1), [e.sections]), A = Q(() => e.sections.slice(1), [e.sections]);
773
773
  Q(
774
774
  () => e.sections.flatMap((s) => y(s)),
775
775
  [e.sections, y]
@@ -814,10 +814,10 @@ const G = ({
814
814
  o.name || o.label || a
815
815
  )) });
816
816
  return /* @__PURE__ */ t.jsx("div", { className: V("w-full", f, e.className), children: /* @__PURE__ */ t.jsxs(Ne, { orientation: F, className: "min-h-[300px] rounded-lg border", children: [
817
- /* @__PURE__ */ t.jsx(se, { defaultSize: _, minSize: 20, children: u(P, h.length === 0) }),
818
- h.length > 0 && /* @__PURE__ */ t.jsxs(t.Fragment, { children: [
817
+ /* @__PURE__ */ t.jsx(se, { defaultSize: _, minSize: 20, children: u(P, A.length === 0) }),
818
+ A.length > 0 && /* @__PURE__ */ t.jsxs(t.Fragment, { children: [
819
819
  /* @__PURE__ */ t.jsx(Se, { withHandle: e.splitResizable !== !1 }),
820
- /* @__PURE__ */ t.jsx(se, { defaultSize: 100 - _, minSize: 20, children: u(h, !0) })
820
+ /* @__PURE__ */ t.jsx(se, { defaultSize: 100 - _, minSize: 20, children: u(A, !0) })
821
821
  ] })
822
822
  ] }) });
823
823
  }, Me = ({
@@ -859,7 +859,7 @@ const G = ({
859
859
  }
860
860
  })();
861
861
  }, [d, e.mode, e.recordId, e.initialData, e.initialValues, l, e.objectName]);
862
- const h = k((o) => {
862
+ const A = k((o) => {
863
863
  const a = [];
864
864
  for (const c of o.fields) {
865
865
  const i = typeof c == "string" ? c : c.name;
@@ -959,7 +959,7 @@ const G = ({
959
959
  {
960
960
  schema: {
961
961
  ...s,
962
- fields: h(o),
962
+ fields: A(o),
963
963
  showSubmit: a === e.sections.length - 1 && s.showSubmit,
964
964
  showCancel: a === e.sections.length - 1 && s.showCancel
965
965
  }
@@ -1037,7 +1037,7 @@ const G = ({
1037
1037
  }
1038
1038
  })();
1039
1039
  }, [d, e.mode, e.recordId, e.initialData, e.initialValues, l, e.objectName]);
1040
- const h = k((n) => {
1040
+ const A = k((n) => {
1041
1041
  const o = [];
1042
1042
  for (const a of n.fields) {
1043
1043
  const c = typeof a == "string" ? a : a.name;
@@ -1137,7 +1137,7 @@ const G = ({
1137
1137
  {
1138
1138
  schema: {
1139
1139
  ...u,
1140
- fields: h(n),
1140
+ fields: A(n),
1141
1141
  showSubmit: o === e.sections.length - 1 && u.showSubmit,
1142
1142
  showCancel: o === e.sections.length - 1 && u.showCancel
1143
1143
  }
@@ -1401,12 +1401,12 @@ const G = ({
1401
1401
  ...T
1402
1402
  };
1403
1403
  if (j)
1404
- return /* @__PURE__ */ t.jsxs("div", { className: "p-4 border border-red-300 bg-red-50 rounded-md", children: [
1404
+ return /* @__PURE__ */ t.jsxs("div", { className: "p-3 sm:p-4 border border-red-300 bg-red-50 rounded-md", children: [
1405
1405
  /* @__PURE__ */ t.jsx("h3", { className: "text-red-800 font-semibold", children: "Error loading form" }),
1406
1406
  /* @__PURE__ */ t.jsx("p", { className: "text-red-600 text-sm mt-1", children: j.message })
1407
1407
  ] });
1408
1408
  if (S)
1409
- return /* @__PURE__ */ t.jsxs("div", { className: "p-8 text-center", children: [
1409
+ return /* @__PURE__ */ t.jsxs("div", { className: "p-4 sm:p-8 text-center", children: [
1410
1410
  /* @__PURE__ */ t.jsx("div", { className: "inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900" }),
1411
1411
  /* @__PURE__ */ t.jsx("p", { className: "mt-2 text-sm text-gray-600", children: "Loading form..." })
1412
1412
  ] });
@@ -1,6 +1,6 @@
1
- (function(z,o){typeof exports=="object"&&typeof module<"u"?o(exports,require("react"),require("@object-ui/core"),require("@object-ui/react"),require("@object-ui/fields"),require("@object-ui/components"),require("lucide-react")):typeof define=="function"&&define.amd?define(["exports","react","@object-ui/core","@object-ui/react","@object-ui/fields","@object-ui/components","lucide-react"],o):(z=typeof globalThis<"u"?globalThis:z||self,o(z.ObjectUIPluginForm={},z.React,z.core,z.react,z.fields,z.components,z.lucideReact))})(this,(function(z,o,K,R,L,j,H){"use strict";var G={exports:{}},B={};var ee;function me(){if(ee)return B;ee=1;var e=Symbol.for("react.transitional.element"),l=Symbol.for("react.fragment");function c(u,v,m){var C=null;if(m!==void 0&&(C=""+m),v.key!==void 0&&(C=""+v.key),"key"in v){m={};for(var O in v)O!=="key"&&(m[O]=v[O])}else m=v;return v=m.ref,{$$typeof:e,type:u,key:C,ref:v!==void 0?v:null,props:m}}return B.Fragment=l,B.jsx=c,B.jsxs=c,B}var J={};var te;function ye(){return te||(te=1,process.env.NODE_ENV!=="production"&&(function(){function e(r){if(r==null)return null;if(typeof r=="function")return r.$$typeof===W?null:r.displayName||r.name||null;if(typeof r=="string")return r;switch(r){case I:return"Fragment";case M:return"Profiler";case k:return"StrictMode";case s:return"Suspense";case d:return"SuspenseList";case S:return"Activity"}if(typeof r=="object")switch(typeof r.tag=="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),r.$$typeof){case $:return"Portal";case a:return r.displayName||"Context";case p:return(r._context.displayName||"Context")+".Consumer";case i:var y=r.render;return r=r.displayName,r||(r=y.displayName||y.name||"",r=r!==""?"ForwardRef("+r+")":"ForwardRef"),r;case f:return y=r.displayName||null,y!==null?y:e(r.type)||"Memo";case n:y=r._payload,r=r._init;try{return e(r(y))}catch{}}return null}function l(r){return""+r}function c(r){try{l(r);var y=!1}catch{y=!0}if(y){y=console;var F=y.error,h=typeof Symbol=="function"&&Symbol.toStringTag&&r[Symbol.toStringTag]||r.constructor.name||"Object";return F.call(y,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",h),l(r)}}function u(r){if(r===I)return"<>";if(typeof r=="object"&&r!==null&&r.$$typeof===n)return"<...>";try{var y=e(r);return y?"<"+y+">":"<...>"}catch{return"<...>"}}function v(){var r=b.A;return r===null?null:r.getOwner()}function m(){return Error("react-stack-top-frame")}function C(r){if(g.call(r,"key")){var y=Object.getOwnPropertyDescriptor(r,"key").get;if(y&&y.isReactWarning)return!1}return r.key!==void 0}function O(r,y){function F(){q||(q=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",y))}F.isReactWarning=!0,Object.defineProperty(r,"key",{get:F,configurable:!0})}function T(){var r=e(this.type);return fe[r]||(fe[r]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),r=this.props.ref,r!==void 0?r:null}function E(r,y,F,h,X,Q){var P=F.ref;return r={$$typeof:V,type:r,key:y,props:F,_owner:h},(P!==void 0?P:null)!==null?Object.defineProperty(r,"ref",{enumerable:!1,get:T}):Object.defineProperty(r,"ref",{enumerable:!1,value:null}),r._store={},Object.defineProperty(r._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(r,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(r,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:X}),Object.defineProperty(r,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:Q}),Object.freeze&&(Object.freeze(r.props),Object.freeze(r)),r}function w(r,y,F,h,X,Q){var P=y.children;if(P!==void 0)if(h)if(_(P)){for(h=0;h<P.length;h++)x(P[h]);Object.freeze&&Object.freeze(P)}else console.error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else x(P);if(g.call(y,"key")){P=e(r);var U=Object.keys(y).filter(function(ge){return ge!=="key"});h=0<U.length?"{key: someKey, "+U.join(": ..., ")+": ...}":"{key: someKey}",be[P+h]||(U=0<U.length?"{"+U.join(": ..., ")+": ...}":"{}",console.error(`A props object containing a "key" prop is being spread into JSX:
1
+ (function(z,o){typeof exports=="object"&&typeof module<"u"?o(exports,require("react"),require("@object-ui/core"),require("@object-ui/react"),require("@object-ui/fields"),require("@object-ui/components"),require("lucide-react")):typeof define=="function"&&define.amd?define(["exports","react","@object-ui/core","@object-ui/react","@object-ui/fields","@object-ui/components","lucide-react"],o):(z=typeof globalThis<"u"?globalThis:z||self,o(z.ObjectUIPluginForm={},z.React,z.core,z.react,z.fields,z.components,z.lucideReact))})(this,(function(z,o,K,R,L,j,H){"use strict";var G={exports:{}},B={};var ee;function me(){if(ee)return B;ee=1;var e=Symbol.for("react.transitional.element"),l=Symbol.for("react.fragment");function c(u,v,m){var C=null;if(m!==void 0&&(C=""+m),v.key!==void 0&&(C=""+v.key),"key"in v){m={};for(var O in v)O!=="key"&&(m[O]=v[O])}else m=v;return v=m.ref,{$$typeof:e,type:u,key:C,ref:v!==void 0?v:null,props:m}}return B.Fragment=l,B.jsx=c,B.jsxs=c,B}var J={};var te;function ye(){return te||(te=1,process.env.NODE_ENV!=="production"&&(function(){function e(r){if(r==null)return null;if(typeof r=="function")return r.$$typeof===W?null:r.displayName||r.name||null;if(typeof r=="string")return r;switch(r){case I:return"Fragment";case M:return"Profiler";case k:return"StrictMode";case s:return"Suspense";case d:return"SuspenseList";case S:return"Activity"}if(typeof r=="object")switch(typeof r.tag=="number"&&console.error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."),r.$$typeof){case $:return"Portal";case a:return r.displayName||"Context";case p:return(r._context.displayName||"Context")+".Consumer";case i:var y=r.render;return r=r.displayName,r||(r=y.displayName||y.name||"",r=r!==""?"ForwardRef("+r+")":"ForwardRef"),r;case f:return y=r.displayName||null,y!==null?y:e(r.type)||"Memo";case n:y=r._payload,r=r._init;try{return e(r(y))}catch{}}return null}function l(r){return""+r}function c(r){try{l(r);var y=!1}catch{y=!0}if(y){y=console;var F=y.error,h=typeof Symbol=="function"&&Symbol.toStringTag&&r[Symbol.toStringTag]||r.constructor.name||"Object";return F.call(y,"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.",h),l(r)}}function u(r){if(r===I)return"<>";if(typeof r=="object"&&r!==null&&r.$$typeof===n)return"<...>";try{var y=e(r);return y?"<"+y+">":"<...>"}catch{return"<...>"}}function v(){var r=b.A;return r===null?null:r.getOwner()}function m(){return Error("react-stack-top-frame")}function C(r){if(w.call(r,"key")){var y=Object.getOwnPropertyDescriptor(r,"key").get;if(y&&y.isReactWarning)return!1}return r.key!==void 0}function O(r,y){function F(){q||(q=!0,console.error("%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)",y))}F.isReactWarning=!0,Object.defineProperty(r,"key",{get:F,configurable:!0})}function T(){var r=e(this.type);return fe[r]||(fe[r]=!0,console.error("Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.")),r=this.props.ref,r!==void 0?r:null}function E(r,y,F,h,X,Q){var P=F.ref;return r={$$typeof:V,type:r,key:y,props:F,_owner:h},(P!==void 0?P:null)!==null?Object.defineProperty(r,"ref",{enumerable:!1,get:T}):Object.defineProperty(r,"ref",{enumerable:!1,value:null}),r._store={},Object.defineProperty(r._store,"validated",{configurable:!1,enumerable:!1,writable:!0,value:0}),Object.defineProperty(r,"_debugInfo",{configurable:!1,enumerable:!1,writable:!0,value:null}),Object.defineProperty(r,"_debugStack",{configurable:!1,enumerable:!1,writable:!0,value:X}),Object.defineProperty(r,"_debugTask",{configurable:!1,enumerable:!1,writable:!0,value:Q}),Object.freeze&&(Object.freeze(r.props),Object.freeze(r)),r}function g(r,y,F,h,X,Q){var P=y.children;if(P!==void 0)if(h)if(_(P)){for(h=0;h<P.length;h++)x(P[h]);Object.freeze&&Object.freeze(P)}else console.error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.");else x(P);if(w.call(y,"key")){P=e(r);var U=Object.keys(y).filter(function(we){return we!=="key"});h=0<U.length?"{key: someKey, "+U.join(": ..., ")+": ...}":"{key: someKey}",be[P+h]||(U=0<U.length?"{"+U.join(": ..., ")+": ...}":"{}",console.error(`A props object containing a "key" prop is being spread into JSX:
2
2
  let props = %s;
3
3
  <%s {...props} />
4
4
  React keys must be passed directly to JSX without using spread:
5
5
  let props = %s;
6
- <%s key={someKey} {...props} />`,h,P,U,P),be[P+h]=!0)}if(P=null,F!==void 0&&(c(F),P=""+F),C(y)&&(c(y.key),P=""+y.key),"key"in y){F={};for(var Z in y)Z!=="key"&&(F[Z]=y[Z])}else F=y;return P&&O(F,typeof r=="function"?r.displayName||r.name||"Unknown":r),E(r,P,F,v(),X,Q)}function x(r){N(r)?r._store&&(r._store.validated=1):typeof r=="object"&&r!==null&&r.$$typeof===n&&(r._payload.status==="fulfilled"?N(r._payload.value)&&r._payload.value._store&&(r._payload.value._store.validated=1):r._store&&(r._store.validated=1))}function N(r){return typeof r=="object"&&r!==null&&r.$$typeof===V}var D=o,V=Symbol.for("react.transitional.element"),$=Symbol.for("react.portal"),I=Symbol.for("react.fragment"),k=Symbol.for("react.strict_mode"),M=Symbol.for("react.profiler"),p=Symbol.for("react.consumer"),a=Symbol.for("react.context"),i=Symbol.for("react.forward_ref"),s=Symbol.for("react.suspense"),d=Symbol.for("react.suspense_list"),f=Symbol.for("react.memo"),n=Symbol.for("react.lazy"),S=Symbol.for("react.activity"),W=Symbol.for("react.client.reference"),b=D.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,g=Object.prototype.hasOwnProperty,_=Array.isArray,A=console.createTask?console.createTask:function(){return null};D={react_stack_bottom_frame:function(r){return r()}};var q,fe={},ce=D.react_stack_bottom_frame.bind(D,m)(),pe=A(u(m)),be={};J.Fragment=I,J.jsx=function(r,y,F){var h=1e4>b.recentlyCreatedOwnerStacks++;return w(r,y,F,!1,h?Error("react-stack-top-frame"):ce,h?A(u(r)):pe)},J.jsxs=function(r,y,F){var h=1e4>b.recentlyCreatedOwnerStacks++;return w(r,y,F,!0,h?Error("react-stack-top-frame"):ce,h?A(u(r)):pe)}})()),J}var re;function je(){return re||(re=1,process.env.NODE_ENV==="production"?G.exports=me():G.exports=ye()),G.exports}var t=je();const Y=({label:e,description:l,collapsible:c=!1,collapsed:u=!1,columns:v=1,children:m,className:C})=>{const[O,T]=o.useState(u),E={1:"grid-cols-1",2:"grid-cols-1 md:grid-cols-2",3:"grid-cols-1 md:grid-cols-2 lg:grid-cols-3",4:"grid-cols-1 md:grid-cols-2 lg:grid-cols-4"},w=()=>{c&&T(!O)};return t.jsxs("div",{className:j.cn("form-section",C),children:[(e||l)&&t.jsxs("div",{className:j.cn("flex items-start gap-2 mb-4",c&&"cursor-pointer select-none"),onClick:w,role:c?"button":void 0,"aria-expanded":c?!O:void 0,children:[c&&t.jsx("span",{className:"mt-0.5 text-muted-foreground",children:O?t.jsx(H.ChevronRight,{className:"h-4 w-4"}):t.jsx(H.ChevronDown,{className:"h-4 w-4"})}),t.jsxs("div",{className:"flex-1",children:[e&&t.jsx("h3",{className:"text-base font-semibold text-foreground",children:e}),l&&t.jsx("p",{className:"text-sm text-muted-foreground mt-0.5",children:l})]})]}),!O&&t.jsx("div",{className:j.cn("grid gap-4",E[v]),children:m})]})},le=({schema:e,dataSource:l,className:c})=>{const[u,v]=o.useState(null),[m,C]=o.useState({}),[O,T]=o.useState(!0),[E,w]=o.useState(null),[x,N]=o.useState(e.defaultTab||e.sections[0]?.name||e.sections[0]?.label||"tab-0");o.useEffect(()=>{(async()=>{if(!l){T(!1);return}try{const i=await l.getObjectSchema(e.objectName);v(i)}catch(i){w(i)}})()},[e.objectName,l]),o.useEffect(()=>{(u||!l)&&(async()=>{if(e.mode==="create"||!e.recordId||!l){C(e.initialData||e.initialValues||{}),T(!1);return}try{const i=await l.findOne(e.objectName,e.recordId);C(i||{})}catch(i){w(i)}finally{T(!1)}})()},[u,e.mode,e.recordId,e.initialData,e.initialValues,l,e.objectName]);const D=o.useCallback(a=>{const i=[];for(const s of a.fields){const d=typeof s=="string"?s:s.name;if(typeof s=="object")i.push(s);else if(u?.fields?.[d]){const f=u.fields[d];i.push({name:d,label:f.label||d,type:L.mapFieldTypeToFormType(f.type),required:f.required||!1,disabled:e.readOnly||e.mode==="view"||f.readonly,placeholder:f.placeholder,description:f.help||f.description,validation:L.buildValidationRules(f),field:f,options:f.options,multiple:f.multiple})}else i.push({name:d,label:d,type:"input"})}return i},[u,e.readOnly,e.mode]),V=o.useCallback(async a=>{if(!l)return e.onSuccess&&await e.onSuccess(a),a;try{let i;return e.mode==="create"?i=await l.create(e.objectName,a):e.mode==="edit"&&e.recordId&&(i=await l.update(e.objectName,e.recordId,a)),e.onSuccess&&await e.onSuccess(i),i}catch(i){throw e.onError&&e.onError(i),i}},[e,l]),$=o.useCallback(()=>{e.onCancel&&e.onCancel()},[e]),I=(a,i)=>a.name||a.label||`tab-${i}`;if(E)return t.jsxs("div",{className:"p-4 border border-red-300 bg-red-50 rounded-md",children:[t.jsx("h3",{className:"text-red-800 font-semibold",children:"Error loading form"}),t.jsx("p",{className:"text-red-600 text-sm mt-1",children:E.message})]});if(O)return t.jsxs("div",{className:"p-8 text-center",children:[t.jsx("div",{className:"inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900"}),t.jsx("p",{className:"mt-2 text-sm text-gray-600",children:"Loading form..."})]});const M={type:"form",fields:e.sections.flatMap(a=>D(a)),layout:"vertical",defaultValues:m,submitLabel:e.submitText||(e.mode==="create"?"Create":"Update"),cancelLabel:e.cancelText,showSubmit:e.showSubmit!==!1&&e.mode!=="view",showCancel:e.showCancel!==!1,onSubmit:V,onCancel:$},p=e.tabPosition==="left"||e.tabPosition==="right";return t.jsx("div",{className:j.cn("w-full",c,e.className),children:t.jsxs(j.Tabs,{value:x,onValueChange:N,orientation:p?"vertical":"horizontal",className:j.cn(p&&"flex gap-4"),children:[t.jsx(j.TabsList,{className:j.cn(p?"flex-col h-auto":"",e.tabPosition==="bottom"&&"order-last",e.tabPosition==="right"&&"order-last"),children:e.sections.map((a,i)=>t.jsx(j.TabsTrigger,{value:I(a,i),className:p?"w-full justify-start":"",children:a.label||`Tab ${i+1}`},I(a,i)))}),t.jsx("div",{className:"flex-1",children:e.sections.map((a,i)=>t.jsx(j.TabsContent,{value:I(a,i),className:"mt-0",children:t.jsx(Y,{description:a.description,columns:a.columns||1,children:t.jsx(R.SchemaRenderer,{schema:{...M,fields:D(a),showSubmit:e.showSubmit!==!1&&e.mode!=="view",showCancel:e.showCancel!==!1}})})},I(a,i)))})]})})},ie=({schema:e,dataSource:l,className:c})=>{const[u,v]=o.useState(null),[m,C]=o.useState({}),[O,T]=o.useState(!0),[E,w]=o.useState(null),[x,N]=o.useState(0),[D,V]=o.useState(new Set),[$,I]=o.useState(!1),k=e.sections.length,M=x===0,p=x===k-1;o.useEffect(()=>{(async()=>{if(!l){T(!1);return}try{const g=await l.getObjectSchema(e.objectName);v(g)}catch(g){w(g)}})()},[e.objectName,l]),o.useEffect(()=>{(u||!l)&&(async()=>{if(e.mode==="create"||!e.recordId||!l){C(e.initialData||e.initialValues||{}),T(!1);return}try{const g=await l.findOne(e.objectName,e.recordId);C(g||{})}catch(g){w(g)}finally{T(!1)}})()},[u,e.mode,e.recordId,e.initialData,e.initialValues,l,e.objectName]);const a=o.useCallback(b=>{const g=[];for(const _ of b.fields){const A=typeof _=="string"?_:_.name;if(typeof _=="object")g.push(_);else if(u?.fields?.[A]){const q=u.fields[A];g.push({name:A,label:q.label||A,type:L.mapFieldTypeToFormType(q.type),required:q.required||!1,disabled:e.readOnly||e.mode==="view"||q.readonly,placeholder:q.placeholder,description:q.help||q.description,validation:L.buildValidationRules(q),field:q,options:q.options,multiple:q.multiple})}else g.push({name:A,label:A,type:"input"})}return g},[u,e.readOnly,e.mode]),i=o.useMemo(()=>x>=0&&x<k?a(e.sections[x]):[],[x,k,e.sections,a]),s=o.useCallback(async b=>{const g={...m,...b};if(C(g),V(_=>new Set(_).add(x)),p){I(!0);try{if(!l)return e.onSuccess&&await e.onSuccess(g),g;let _;return e.mode==="create"?_=await l.create(e.objectName,g):e.mode==="edit"&&e.recordId&&(_=await l.update(e.objectName,e.recordId,g)),e.onSuccess&&await e.onSuccess(_),_}catch(_){throw e.onError&&e.onError(_),_}finally{I(!1)}}else d(x+1)},[m,x,p,e,l]),d=o.useCallback(b=>{b>=0&&b<k&&(N(b),e.onStepChange&&e.onStepChange(b))},[k,e]),f=o.useCallback(()=>{d(x-1)},[x,d]),n=o.useCallback(()=>{e.onCancel&&e.onCancel()},[e]),S=o.useCallback(b=>{(e.allowSkip||D.has(b)||b<=x)&&d(b)},[e.allowSkip,D,x,d]);if(E)return t.jsxs("div",{className:"p-4 border border-red-300 bg-red-50 rounded-md",children:[t.jsx("h3",{className:"text-red-800 font-semibold",children:"Error loading form"}),t.jsx("p",{className:"text-red-600 text-sm mt-1",children:E.message})]});if(O)return t.jsxs("div",{className:"p-8 text-center",children:[t.jsx("div",{className:"inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900"}),t.jsx("p",{className:"mt-2 text-sm text-gray-600",children:"Loading form..."})]});const W=e.sections[x];return t.jsxs("div",{className:j.cn("w-full",c,e.className),children:[e.showStepIndicator!==!1&&t.jsx("nav",{"aria-label":"Progress",className:"mb-8",children:t.jsx("ol",{className:"flex items-center",children:e.sections.map((b,g)=>{const _=g===x,A=D.has(g),q=e.allowSkip||A||g<=x;return t.jsxs("li",{className:j.cn("relative flex-1",g!==k-1&&"pr-8 sm:pr-12"),children:[g!==k-1&&t.jsx("div",{className:"absolute top-4 left-8 -right-4 sm:left-10 sm:-right-2 h-0.5","aria-hidden":"true",children:t.jsx("div",{className:j.cn("h-full",A?"bg-primary":"bg-muted")})}),t.jsxs("button",{type:"button",className:j.cn("group relative flex items-center",q?"cursor-pointer":"cursor-not-allowed"),onClick:()=>S(g),disabled:!q,children:[t.jsx("span",{className:j.cn("flex h-8 w-8 items-center justify-center rounded-full text-sm font-medium transition-colors",A&&"bg-primary text-primary-foreground",_&&!A&&"border-2 border-primary bg-background text-primary",!_&&!A&&"border-2 border-muted bg-background text-muted-foreground"),children:A?t.jsx(H.Check,{className:"h-4 w-4"}):g+1}),t.jsx("span",{className:"ml-3 text-sm font-medium hidden sm:block",children:t.jsx("span",{className:j.cn(_?"text-foreground":"text-muted-foreground"),children:b.label||`Step ${g+1}`})})]})]},g)})})}),t.jsx("div",{className:"min-h-[200px]",children:W&&t.jsx(Y,{label:W.label,description:W.description,columns:W.columns||1,children:i.length>0?t.jsx(R.SchemaRenderer,{schema:{type:"form",fields:i,layout:"vertical",defaultValues:m,showSubmit:!1,showCancel:!1,onSubmit:s}}):t.jsx("div",{className:"text-center py-8 text-muted-foreground",children:"No fields configured for this step"})})}),t.jsxs("div",{className:"flex items-center justify-between mt-6 pt-4 border-t",children:[t.jsx("div",{children:e.showCancel!==!1&&t.jsx(j.Button,{variant:"ghost",onClick:n,children:e.cancelText||"Cancel"})}),t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsxs("span",{className:"text-sm text-muted-foreground mr-2",children:["Step ",x+1," of ",k]}),!M&&t.jsxs(j.Button,{variant:"outline",onClick:f,children:[t.jsx(H.ChevronLeft,{className:"h-4 w-4 mr-1"}),e.prevText||"Back"]}),p?t.jsx(j.Button,{onClick:()=>s(m),disabled:$||e.mode==="view",children:$?"Submitting...":e.submitText||(e.mode==="create"?"Create":"Update")}):t.jsxs(j.Button,{onClick:()=>s(m),children:[e.nextText||"Next",t.jsx(H.ChevronRight,{className:"h-4 w-4 ml-1"})]})]})]})]})},ne=({schema:e,dataSource:l,className:c})=>{const[u,v]=o.useState(null),[m,C]=o.useState({}),[O,T]=o.useState(!0),[E,w]=o.useState(null);o.useEffect(()=>{(async()=>{if(!l){T(!1);return}try{const i=await l.getObjectSchema(e.objectName);v(i)}catch(i){w(i),T(!1)}})()},[e.objectName,l]),o.useEffect(()=>{(u||!l)&&(async()=>{if(e.mode==="create"||!e.recordId){C(e.initialData||e.initialValues||{}),T(!1);return}if(!l){C(e.initialData||e.initialValues||{}),T(!1);return}try{const i=await l.findOne(e.objectName,e.recordId);C(i||{})}catch(i){w(i)}finally{T(!1)}})()},[u,e.mode,e.recordId,e.initialData,e.initialValues,l,e.objectName]);const x=o.useCallback(a=>{const i=[];for(const s of a.fields){const d=typeof s=="string"?s:s.name;if(typeof s=="object")i.push(s);else if(u?.fields?.[d]){const f=u.fields[d];i.push({name:d,label:f.label||d,type:L.mapFieldTypeToFormType(f.type),required:f.required||!1,disabled:e.readOnly||e.mode==="view"||f.readonly,placeholder:f.placeholder,description:f.help||f.description,validation:L.buildValidationRules(f),field:f,options:f.options,multiple:f.multiple})}else i.push({name:d,label:d,type:"input"})}return i},[u,e.readOnly,e.mode]),N=o.useCallback(async a=>{if(!l)return e.onSuccess&&await e.onSuccess(a),a;try{let i;return e.mode==="create"?i=await l.create(e.objectName,a):e.mode==="edit"&&e.recordId&&(i=await l.update(e.objectName,e.recordId,a)),e.onSuccess&&await e.onSuccess(i),i}catch(i){throw e.onError&&e.onError(i),i}},[e,l]),D=o.useCallback(()=>{e.onCancel&&e.onCancel()},[e]),V=o.useMemo(()=>e.sections.slice(0,1),[e.sections]),$=o.useMemo(()=>e.sections.slice(1),[e.sections]);o.useMemo(()=>e.sections.flatMap(a=>x(a)),[e.sections,x]);const I=e.splitDirection||"horizontal",k=e.splitSize||50;if(E)return t.jsxs("div",{className:"p-4 border border-red-300 bg-red-50 rounded-md",children:[t.jsx("h3",{className:"text-red-800 font-semibold",children:"Error loading form"}),t.jsx("p",{className:"text-red-600 text-sm mt-1",children:E.message})]});if(O)return t.jsxs("div",{className:"p-8 text-center",children:[t.jsx("div",{className:"inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900"}),t.jsx("p",{className:"mt-2 text-sm text-gray-600",children:"Loading form..."})]});const M={type:"form",layout:"vertical",defaultValues:m,onSubmit:N,onCancel:D},p=(a,i)=>t.jsx("div",{className:"space-y-4 p-4",children:a.map((s,d)=>t.jsx(Y,{label:s.label,description:s.description,columns:s.columns||1,children:t.jsx(R.SchemaRenderer,{schema:{...M,fields:x(s),showSubmit:i&&e.showSubmit!==!1&&e.mode!=="view",showCancel:i&&e.showCancel!==!1,submitLabel:e.submitText||(e.mode==="create"?"Create":"Update"),cancelLabel:e.cancelText}})},s.name||s.label||d))});return t.jsx("div",{className:j.cn("w-full",c,e.className),children:t.jsxs(j.ResizablePanelGroup,{orientation:I,className:"min-h-[300px] rounded-lg border",children:[t.jsx(j.ResizablePanel,{defaultSize:k,minSize:20,children:p(V,$.length===0)}),$.length>0&&t.jsxs(t.Fragment,{children:[t.jsx(j.ResizableHandle,{withHandle:e.splitResizable!==!1}),t.jsx(j.ResizablePanel,{defaultSize:100-k,minSize:20,children:p($,!0)})]})]})})},oe=({schema:e,dataSource:l,className:c})=>{const[u,v]=o.useState(null),[m,C]=o.useState([]),[O,T]=o.useState({}),[E,w]=o.useState(!0),[x,N]=o.useState(null),D=e.open!==!1,V=e.drawerSide||"right";o.useEffect(()=>{(async()=>{if(!l){w(!1);return}try{const d=await l.getObjectSchema(e.objectName);v(d)}catch(d){N(d),w(!1)}})()},[e.objectName,l]),o.useEffect(()=>{(u||!l)&&(async()=>{if(e.mode==="create"||!e.recordId){T(e.initialData||e.initialValues||{}),w(!1);return}if(!l){T(e.initialData||e.initialValues||{}),w(!1);return}try{const d=await l.findOne(e.objectName,e.recordId);T(d||{})}catch(d){N(d)}finally{w(!1)}})()},[u,e.mode,e.recordId,e.initialData,e.initialValues,l,e.objectName]);const $=o.useCallback(s=>{const d=[];for(const f of s.fields){const n=typeof f=="string"?f:f.name;if(typeof f=="object")d.push(f);else if(u?.fields?.[n]){const S=u.fields[n];d.push({name:n,label:S.label||n,type:L.mapFieldTypeToFormType(S.type),required:S.required||!1,disabled:e.readOnly||e.mode==="view"||S.readonly,placeholder:S.placeholder,description:S.help||S.description,validation:L.buildValidationRules(S),field:S,options:S.options,multiple:S.multiple})}else d.push({name:n,label:n,type:"input"})}return d},[u,e.readOnly,e.mode]);o.useEffect(()=>{if(!u&&l)return;if(e.customFields?.length){C(e.customFields),w(!1);return}if(e.sections?.length){w(!1);return}if(!u)return;const s=e.fields||Object.keys(u.fields||{}),d=[];for(const f of s){const n=typeof f=="string"?f:f.name;if(!n)continue;const S=u.fields?.[n];S&&d.push({name:n,label:S.label||n,type:L.mapFieldTypeToFormType(S.type),required:S.required||!1,disabled:e.readOnly||e.mode==="view"||S.readonly,placeholder:S.placeholder,description:S.help||S.description,validation:L.buildValidationRules(S),field:S,options:S.options,multiple:S.multiple})}C(d),w(!1)},[u,e.fields,e.customFields,e.sections,e.readOnly,e.mode,l]);const I=o.useCallback(async s=>{if(!l)return e.onSuccess&&await e.onSuccess(s),e.onOpenChange?.(!1),s;try{let d;return e.mode==="create"?d=await l.create(e.objectName,s):e.mode==="edit"&&e.recordId&&(d=await l.update(e.objectName,e.recordId,s)),e.onSuccess&&await e.onSuccess(d),e.onOpenChange?.(!1),d}catch(d){throw e.onError&&e.onError(d),d}},[e,l]),k=o.useCallback(()=>{e.onCancel&&e.onCancel(),e.onOpenChange?.(!1)},[e]),M=o.useMemo(()=>e.drawerWidth?V==="left"||V==="right"?{width:e.drawerWidth,maxWidth:e.drawerWidth}:{height:e.drawerWidth,maxHeight:e.drawerWidth}:void 0,[e.drawerWidth,V]),a={type:"form",layout:e.layout==="vertical"||e.layout==="horizontal"?e.layout:"vertical",defaultValues:O,submitLabel:e.submitText||(e.mode==="create"?"Create":"Update"),cancelLabel:e.cancelText,showSubmit:e.showSubmit!==!1&&e.mode!=="view",showCancel:e.showCancel!==!1,onSubmit:I,onCancel:k},i=()=>x?t.jsxs("div",{className:"p-4 border border-red-300 bg-red-50 rounded-md",children:[t.jsx("h3",{className:"text-red-800 font-semibold",children:"Error loading form"}),t.jsx("p",{className:"text-red-600 text-sm mt-1",children:x.message})]}):E?t.jsxs("div",{className:"p-8 text-center",children:[t.jsx("div",{className:"inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900"}),t.jsx("p",{className:"mt-2 text-sm text-gray-600",children:"Loading form..."})]}):e.sections?.length?t.jsx("div",{className:"space-y-6",children:e.sections.map((s,d)=>t.jsx(Y,{label:s.label,description:s.description,columns:s.columns||1,children:t.jsx(R.SchemaRenderer,{schema:{...a,fields:$(s),showSubmit:d===e.sections.length-1&&a.showSubmit,showCancel:d===e.sections.length-1&&a.showCancel}})},s.name||s.label||d))}):t.jsx(R.SchemaRenderer,{schema:{...a,fields:m,columns:e.columns}});return t.jsx(j.Sheet,{open:D,onOpenChange:e.onOpenChange,children:t.jsxs(j.SheetContent,{side:V,className:j.cn("overflow-y-auto",c,e.className),style:M,children:[(e.title||e.description)&&t.jsxs(j.SheetHeader,{children:[e.title&&t.jsx(j.SheetTitle,{children:e.title}),e.description&&t.jsx(j.SheetDescription,{children:e.description})]}),t.jsx("div",{className:"py-4",children:i()})]})})},se={sm:"max-w-sm",default:"max-w-lg",lg:"max-w-2xl",xl:"max-w-4xl",full:"max-w-[95vw] w-full"},ae=({schema:e,dataSource:l,className:c})=>{const[u,v]=o.useState(null),[m,C]=o.useState([]),[O,T]=o.useState({}),[E,w]=o.useState(!0),[x,N]=o.useState(null),D=e.open!==!1,V=se[e.modalSize||"default"]||se.default;o.useEffect(()=>{(async()=>{if(!l){w(!1);return}try{const s=await l.getObjectSchema(e.objectName);v(s)}catch(s){N(s),w(!1)}})()},[e.objectName,l]),o.useEffect(()=>{(u||!l)&&(async()=>{if(e.mode==="create"||!e.recordId){T(e.initialData||e.initialValues||{}),w(!1);return}if(!l){T(e.initialData||e.initialValues||{}),w(!1);return}try{const s=await l.findOne(e.objectName,e.recordId);T(s||{})}catch(s){N(s)}finally{w(!1)}})()},[u,e.mode,e.recordId,e.initialData,e.initialValues,l,e.objectName]);const $=o.useCallback(i=>{const s=[];for(const d of i.fields){const f=typeof d=="string"?d:d.name;if(typeof d=="object")s.push(d);else if(u?.fields?.[f]){const n=u.fields[f];s.push({name:f,label:n.label||f,type:L.mapFieldTypeToFormType(n.type),required:n.required||!1,disabled:e.readOnly||e.mode==="view"||n.readonly,placeholder:n.placeholder,description:n.help||n.description,validation:L.buildValidationRules(n),field:n,options:n.options,multiple:n.multiple})}else s.push({name:f,label:f,type:"input"})}return s},[u,e.readOnly,e.mode]);o.useEffect(()=>{if(!u&&l)return;if(e.customFields?.length){C(e.customFields),w(!1);return}if(e.sections?.length){w(!1);return}if(!u)return;const i=e.fields||Object.keys(u.fields||{}),s=[];for(const d of i){const f=typeof d=="string"?d:d.name;if(!f)continue;const n=u.fields?.[f];n&&s.push({name:f,label:n.label||f,type:L.mapFieldTypeToFormType(n.type),required:n.required||!1,disabled:e.readOnly||e.mode==="view"||n.readonly,placeholder:n.placeholder,description:n.help||n.description,validation:L.buildValidationRules(n),field:n,options:n.options,multiple:n.multiple})}C(s),w(!1)},[u,e.fields,e.customFields,e.sections,e.readOnly,e.mode,l]);const I=o.useCallback(async i=>{if(!l)return e.onSuccess&&await e.onSuccess(i),e.onOpenChange?.(!1),i;try{let s;return e.mode==="create"?s=await l.create(e.objectName,i):e.mode==="edit"&&e.recordId&&(s=await l.update(e.objectName,e.recordId,i)),e.onSuccess&&await e.onSuccess(s),e.onOpenChange?.(!1),s}catch(s){throw e.onError&&e.onError(s),s}},[e,l]),k=o.useCallback(()=>{e.onCancel&&e.onCancel(),e.onOpenChange?.(!1)},[e]),p={type:"form",layout:e.layout==="vertical"||e.layout==="horizontal"?e.layout:"vertical",defaultValues:O,submitLabel:e.submitText||(e.mode==="create"?"Create":"Update"),cancelLabel:e.cancelText,showSubmit:e.showSubmit!==!1&&e.mode!=="view",showCancel:e.showCancel!==!1,onSubmit:I,onCancel:k},a=()=>x?t.jsxs("div",{className:"p-4 border border-red-300 bg-red-50 rounded-md",children:[t.jsx("h3",{className:"text-red-800 font-semibold",children:"Error loading form"}),t.jsx("p",{className:"text-red-600 text-sm mt-1",children:x.message})]}):E?t.jsxs("div",{className:"p-8 text-center",children:[t.jsx("div",{className:"inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900"}),t.jsx("p",{className:"mt-2 text-sm text-gray-600",children:"Loading form..."})]}):e.sections?.length?t.jsx("div",{className:"space-y-6",children:e.sections.map((i,s)=>t.jsx(Y,{label:i.label,description:i.description,columns:i.columns||1,children:t.jsx(R.SchemaRenderer,{schema:{...p,fields:$(i),showSubmit:s===e.sections.length-1&&p.showSubmit,showCancel:s===e.sections.length-1&&p.showCancel}})},i.name||i.label||s))}):t.jsx(R.SchemaRenderer,{schema:{...p,fields:m,columns:e.columns}});return t.jsx(j.Dialog,{open:D,onOpenChange:e.onOpenChange,children:t.jsxs(j.DialogContent,{className:j.cn(V,"max-h-[90vh] overflow-y-auto",c,e.className),children:[(e.title||e.description)&&t.jsxs(j.DialogHeader,{children:[e.title&&t.jsx(j.DialogTitle,{children:e.title}),e.description&&t.jsx(j.DialogDescription,{children:e.description})]}),t.jsx("div",{className:"py-2",children:a()})]})})},de=({schema:e,dataSource:l})=>{if(e.formType==="tabbed"&&e.sections?.length)return t.jsx(le,{schema:{...e,formType:"tabbed",sections:e.sections.map(c=>({name:c.name,label:c.label,description:c.description,columns:c.columns,fields:c.fields})),defaultTab:e.defaultTab,tabPosition:e.tabPosition},dataSource:l,className:e.className});if(e.formType==="wizard"&&e.sections?.length)return t.jsx(ie,{schema:{...e,formType:"wizard",sections:e.sections.map(c=>({name:c.name,label:c.label,description:c.description,columns:c.columns,fields:c.fields})),allowSkip:e.allowSkip,showStepIndicator:e.showStepIndicator,nextText:e.nextText,prevText:e.prevText,onStepChange:e.onStepChange},dataSource:l,className:e.className});if(e.formType==="split"&&e.sections?.length)return t.jsx(ne,{schema:{...e,formType:"split",sections:e.sections.map(c=>({name:c.name,label:c.label,description:c.description,columns:c.columns,fields:c.fields})),splitDirection:e.splitDirection,splitSize:e.splitSize,splitResizable:e.splitResizable},dataSource:l,className:e.className});if(e.formType==="drawer"){const{layout:c,...u}=e,v=e.layout==="vertical"||e.layout==="horizontal"?e.layout:void 0;return t.jsx(oe,{schema:{...u,layout:v,formType:"drawer",sections:e.sections?.map(m=>({name:m.name,label:m.label,description:m.description,columns:m.columns,fields:m.fields})),open:e.open,onOpenChange:e.onOpenChange,drawerSide:e.drawerSide,drawerWidth:e.drawerWidth},dataSource:l,className:e.className})}if(e.formType==="modal"){const{layout:c,...u}=e,v=e.layout==="vertical"||e.layout==="horizontal"?e.layout:void 0;return t.jsx(ae,{schema:{...u,layout:v,formType:"modal",sections:e.sections?.map(m=>({name:m.name,label:m.label,description:m.description,columns:m.columns,fields:m.fields})),open:e.open,onOpenChange:e.onOpenChange,modalSize:e.modalSize,modalCloseButton:e.modalCloseButton},dataSource:l,className:e.className})}return t.jsx(xe,{schema:e,dataSource:l})},xe=({schema:e,dataSource:l})=>{const[c,u]=o.useState(null),[v,m]=o.useState([]),[C,O]=o.useState(null),[T,E]=o.useState(!0),[w,x]=o.useState(null),N=e.customFields&&e.customFields.length>0;o.useEffect(()=>{N&&(O(e.initialData||e.initialValues||{}),E(!1))},[N,e.initialData,e.initialValues]),o.useEffect(()=>{const p=async()=>{try{if(!l)throw new Error("DataSource is required when using ObjectQL schema fetching (inline fields not provided)");const a=await l.getObjectSchema(e.objectName);if(!a)throw new Error(`No schema found for object "${e.objectName}"`);u(a)}catch(a){x(a),E(!1)}};N?u({name:e.objectName,fields:{}}):e.objectName&&l?p():N||E(!1)},[e.objectName,l,N]),o.useEffect(()=>{c&&!N&&(async()=>{if(!e.recordId||e.mode==="create"){O(e.initialData||e.initialValues||{}),E(!1);return}if(!N){if(!l){x(new Error("DataSource is required for fetching record data (inline data not provided)")),E(!1);return}E(!0);try{const a=await l.findOne(e.objectName,e.recordId);O(a)}catch(a){console.error("Failed to fetch record:",a),x(a)}finally{E(!1)}}})()},[e.objectName,e.recordId,e.mode,e.initialValues,e.initialData,l,c,N]),o.useEffect(()=>{if(N&&e.customFields){m(e.customFields),E(!1);return}if(!c)return;const p=[],a=e.fields||Object.keys(c.fields||{});(Array.isArray(a)?a:Object.keys(a)).forEach(d=>{const f=typeof d=="string"?d:d.name;if(!f)return;const n=c.fields?.[f];if(!n&&!N)return;const S=!n?.permissions||n?.permissions.write!==!1;if(e.mode!=="view"&&!S)return;const W=e.customFields?.find(b=>b.name===f);if(W)p.push(W);else if(n){const b={name:f,label:n.label||d,type:L.mapFieldTypeToFormType(n.type),required:n.required||!1,disabled:e.readOnly||e.mode==="view"||n.readonly,placeholder:n.placeholder,description:n.help||n.description,validation:L.buildValidationRules(n),field:n};if((n.type==="select"||n.type==="lookup"||n.type==="master_detail")&&(b.options=n.options||[],b.multiple=n.multiple),(n.type==="number"||n.type==="currency"||n.type==="percent")&&(b.inputType="number",b.min=n.min,b.max=n.max,b.step=n.precision?Math.pow(10,-n.precision):void 0),n.type==="date"&&(b.inputType="date"),n.type==="datetime"&&(b.inputType="datetime-local"),(n.type==="text"||n.type==="textarea"||n.type==="markdown"||n.type==="html")&&(b.maxLength=n.max_length,b.minLength=n.min_length),(n.type==="file"||n.type==="image")&&(b.inputType="file",b.multiple=n.multiple,b.accept=n.accept?n.accept.join(","):void 0,n.max_size)){const g=`Max size: ${L.formatFileSize(n.max_size)}`;b.description=b.description?`${b.description} (${g})`:g}n.type==="email"&&(b.inputType="email"),n.type==="phone"&&(b.inputType="tel"),n.type==="url"&&(b.inputType="url"),n.type==="password"&&(b.inputType="password"),n.type==="time"&&(b.inputType="time"),(n.type==="formula"||n.type==="summary"||n.type==="auto_number")&&(b.disabled=!0),n.visible_on&&(b.visible=g=>L.evaluateCondition(n.visible_on,g)),p.push(b)}}),m(p),!N&&e.recordId&&e.mode!=="create"&&l||E(!1)},[c,e.fields,e.customFields,e.readOnly,e.mode,N,e.recordId,l]);const D=o.useCallback(async(p,a)=>{if(p&&(p.nativeEvent||p._reactName==="onSubmit")&&(console.warn("ObjectForm: Received Event instead of data in handleSubmit! This suggests a Form renderer issue."),a===void 0&&(a=p,p={})),N&&!l)return e.onSuccess&&await e.onSuccess(p),p;if(!l)throw new Error("DataSource is required for form submission (inline mode not configured)");try{let i;if(e.mode==="create")i=await l.create(e.objectName,p);else if(e.mode==="edit"&&e.recordId)i=await l.update(e.objectName,e.recordId,p);else throw new Error("Invalid form mode or missing record ID");return e.onSuccess&&await e.onSuccess(i),i}catch(i){throw console.error("Failed to submit form:",i),e.onError&&e.onError(i),i}},[e,l,N]),V=o.useCallback(()=>{e.onCancel&&e.onCancel()},[e]),I={...o.useMemo(()=>{if(!c?.fields)return{};const p={};return Object.keys(c.fields).forEach(a=>{const i=c.fields[a];i.defaultValue!==void 0&&(p[a]=i.defaultValue)}),p},[c]),...C};if(w)return t.jsxs("div",{className:"p-4 border border-red-300 bg-red-50 rounded-md",children:[t.jsx("h3",{className:"text-red-800 font-semibold",children:"Error loading form"}),t.jsx("p",{className:"text-red-600 text-sm mt-1",children:w.message})]});if(T)return t.jsxs("div",{className:"p-8 text-center",children:[t.jsx("div",{className:"inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900"}),t.jsx("p",{className:"mt-2 text-sm text-gray-600",children:"Loading form..."})]});const k=e.layout==="vertical"||e.layout==="horizontal"?e.layout:"vertical";if(e.sections?.length&&(!e.formType||e.formType==="simple"))return t.jsx("div",{className:"w-full space-y-6",children:e.sections.map((p,a)=>{const i=p.fields.map(d=>typeof d=="string"?d:d.name),s=v.filter(d=>i.includes(d.name));return t.jsx(Y,{label:p.label,description:p.description,collapsible:p.collapsible,collapsed:p.collapsed,columns:p.columns,children:t.jsx(R.SchemaRenderer,{schema:{type:"form",fields:s,layout:k,defaultValues:I,showSubmit:a===e.sections.length-1&&e.showSubmit!==!1&&e.mode!=="view",showCancel:a===e.sections.length-1&&e.showCancel!==!1,submitLabel:e.submitText||(e.mode==="create"?"Create":"Update"),cancelLabel:e.cancelText,onSubmit:D,onCancel:V}})},p.name||p.label||a)})});const M={type:"form",fields:v,layout:k,columns:e.columns,submitLabel:e.submitText||(e.mode==="create"?"Create":"Update"),cancelLabel:e.cancelText,showSubmit:e.showSubmit!==!1&&e.mode!=="view",showCancel:e.showCancel!==!1,resetOnSubmit:e.showReset,defaultValues:I,onSubmit:D,onCancel:V,className:e.className};return t.jsx("div",{className:"w-full",children:t.jsx(R.SchemaRenderer,{schema:M})})},ue=({schema:e})=>t.jsx(de,{schema:e});K.ComponentRegistry.register("object-form",ue,{namespace:"plugin-form",label:"Object Form",category:"plugin",inputs:[{name:"objectName",type:"string",label:"Object Name",required:!0},{name:"fields",type:"array",label:"Fields"},{name:"mode",type:"enum",label:"Mode",enum:["create","edit","view"]},{name:"formType",type:"enum",label:"Form Type",enum:["simple","tabbed","wizard","split","drawer","modal"]},{name:"sections",type:"array",label:"Sections"},{name:"title",type:"string",label:"Title"},{name:"description",type:"string",label:"Description"},{name:"layout",type:"enum",label:"Layout",enum:["vertical","horizontal","inline","grid"]},{name:"columns",type:"number",label:"Columns"},{name:"defaultTab",type:"string",label:"Default Tab"},{name:"tabPosition",type:"enum",label:"Tab Position",enum:["top","bottom","left","right"]},{name:"allowSkip",type:"boolean",label:"Allow Skip Steps"},{name:"showStepIndicator",type:"boolean",label:"Show Step Indicator"},{name:"splitDirection",type:"enum",label:"Split Direction",enum:["horizontal","vertical"]},{name:"splitSize",type:"number",label:"Split Panel Size (%)"},{name:"splitResizable",type:"boolean",label:"Split Resizable"},{name:"drawerSide",type:"enum",label:"Drawer Side",enum:["top","bottom","left","right"]},{name:"drawerWidth",type:"string",label:"Drawer Width"},{name:"modalSize",type:"enum",label:"Modal Size",enum:["sm","default","lg","xl","full"]}]}),K.ComponentRegistry.register("form",ue,{namespace:"view",skipFallback:!0,label:"Data Form View",category:"view",inputs:[{name:"objectName",type:"string",label:"Object Name",required:!0},{name:"fields",type:"array",label:"Fields"},{name:"mode",type:"enum",label:"Mode",enum:["create","edit","view"]}]}),z.DrawerForm=oe,z.FormSection=Y,z.ModalForm=ae,z.ObjectForm=de,z.SplitForm=ne,z.TabbedForm=le,z.WizardForm=ie,Object.defineProperty(z,Symbol.toStringTag,{value:"Module"})}));
6
+ <%s key={someKey} {...props} />`,h,P,U,P),be[P+h]=!0)}if(P=null,F!==void 0&&(c(F),P=""+F),C(y)&&(c(y.key),P=""+y.key),"key"in y){F={};for(var Z in y)Z!=="key"&&(F[Z]=y[Z])}else F=y;return P&&O(F,typeof r=="function"?r.displayName||r.name||"Unknown":r),E(r,P,F,v(),X,Q)}function x(r){N(r)?r._store&&(r._store.validated=1):typeof r=="object"&&r!==null&&r.$$typeof===n&&(r._payload.status==="fulfilled"?N(r._payload.value)&&r._payload.value._store&&(r._payload.value._store.validated=1):r._store&&(r._store.validated=1))}function N(r){return typeof r=="object"&&r!==null&&r.$$typeof===V}var D=o,V=Symbol.for("react.transitional.element"),$=Symbol.for("react.portal"),I=Symbol.for("react.fragment"),k=Symbol.for("react.strict_mode"),M=Symbol.for("react.profiler"),p=Symbol.for("react.consumer"),a=Symbol.for("react.context"),i=Symbol.for("react.forward_ref"),s=Symbol.for("react.suspense"),d=Symbol.for("react.suspense_list"),f=Symbol.for("react.memo"),n=Symbol.for("react.lazy"),S=Symbol.for("react.activity"),W=Symbol.for("react.client.reference"),b=D.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,w=Object.prototype.hasOwnProperty,_=Array.isArray,A=console.createTask?console.createTask:function(){return null};D={react_stack_bottom_frame:function(r){return r()}};var q,fe={},ce=D.react_stack_bottom_frame.bind(D,m)(),pe=A(u(m)),be={};J.Fragment=I,J.jsx=function(r,y,F){var h=1e4>b.recentlyCreatedOwnerStacks++;return g(r,y,F,!1,h?Error("react-stack-top-frame"):ce,h?A(u(r)):pe)},J.jsxs=function(r,y,F){var h=1e4>b.recentlyCreatedOwnerStacks++;return g(r,y,F,!0,h?Error("react-stack-top-frame"):ce,h?A(u(r)):pe)}})()),J}var re;function je(){return re||(re=1,process.env.NODE_ENV==="production"?G.exports=me():G.exports=ye()),G.exports}var t=je();const Y=({label:e,description:l,collapsible:c=!1,collapsed:u=!1,columns:v=1,children:m,className:C})=>{const[O,T]=o.useState(u),E={1:"grid-cols-1",2:"grid-cols-1 md:grid-cols-2",3:"grid-cols-1 md:grid-cols-2 lg:grid-cols-3",4:"grid-cols-1 md:grid-cols-2 lg:grid-cols-4"},g=()=>{c&&T(!O)};return t.jsxs("div",{className:j.cn("form-section",C),children:[(e||l)&&t.jsxs("div",{className:j.cn("flex items-start gap-2 mb-4",c&&"cursor-pointer select-none"),onClick:g,role:c?"button":void 0,"aria-expanded":c?!O:void 0,children:[c&&t.jsx("span",{className:"mt-0.5 text-muted-foreground",children:O?t.jsx(H.ChevronRight,{className:"h-4 w-4"}):t.jsx(H.ChevronDown,{className:"h-4 w-4"})}),t.jsxs("div",{className:"flex-1",children:[e&&t.jsx("h3",{className:"text-base font-semibold text-foreground",children:e}),l&&t.jsx("p",{className:"text-sm text-muted-foreground mt-0.5",children:l})]})]}),!O&&t.jsx("div",{className:j.cn("grid gap-4",E[v]),children:m})]})},le=({schema:e,dataSource:l,className:c})=>{const[u,v]=o.useState(null),[m,C]=o.useState({}),[O,T]=o.useState(!0),[E,g]=o.useState(null),[x,N]=o.useState(e.defaultTab||e.sections[0]?.name||e.sections[0]?.label||"tab-0");o.useEffect(()=>{(async()=>{if(!l){T(!1);return}try{const i=await l.getObjectSchema(e.objectName);v(i)}catch(i){g(i)}})()},[e.objectName,l]),o.useEffect(()=>{(u||!l)&&(async()=>{if(e.mode==="create"||!e.recordId||!l){C(e.initialData||e.initialValues||{}),T(!1);return}try{const i=await l.findOne(e.objectName,e.recordId);C(i||{})}catch(i){g(i)}finally{T(!1)}})()},[u,e.mode,e.recordId,e.initialData,e.initialValues,l,e.objectName]);const D=o.useCallback(a=>{const i=[];for(const s of a.fields){const d=typeof s=="string"?s:s.name;if(typeof s=="object")i.push(s);else if(u?.fields?.[d]){const f=u.fields[d];i.push({name:d,label:f.label||d,type:L.mapFieldTypeToFormType(f.type),required:f.required||!1,disabled:e.readOnly||e.mode==="view"||f.readonly,placeholder:f.placeholder,description:f.help||f.description,validation:L.buildValidationRules(f),field:f,options:f.options,multiple:f.multiple})}else i.push({name:d,label:d,type:"input"})}return i},[u,e.readOnly,e.mode]),V=o.useCallback(async a=>{if(!l)return e.onSuccess&&await e.onSuccess(a),a;try{let i;return e.mode==="create"?i=await l.create(e.objectName,a):e.mode==="edit"&&e.recordId&&(i=await l.update(e.objectName,e.recordId,a)),e.onSuccess&&await e.onSuccess(i),i}catch(i){throw e.onError&&e.onError(i),i}},[e,l]),$=o.useCallback(()=>{e.onCancel&&e.onCancel()},[e]),I=(a,i)=>a.name||a.label||`tab-${i}`;if(E)return t.jsxs("div",{className:"p-4 border border-red-300 bg-red-50 rounded-md",children:[t.jsx("h3",{className:"text-red-800 font-semibold",children:"Error loading form"}),t.jsx("p",{className:"text-red-600 text-sm mt-1",children:E.message})]});if(O)return t.jsxs("div",{className:"p-8 text-center",children:[t.jsx("div",{className:"inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900"}),t.jsx("p",{className:"mt-2 text-sm text-gray-600",children:"Loading form..."})]});const M={type:"form",fields:e.sections.flatMap(a=>D(a)),layout:"vertical",defaultValues:m,submitLabel:e.submitText||(e.mode==="create"?"Create":"Update"),cancelLabel:e.cancelText,showSubmit:e.showSubmit!==!1&&e.mode!=="view",showCancel:e.showCancel!==!1,onSubmit:V,onCancel:$},p=e.tabPosition==="left"||e.tabPosition==="right";return t.jsx("div",{className:j.cn("w-full",c,e.className),children:t.jsxs(j.Tabs,{value:x,onValueChange:N,orientation:p?"vertical":"horizontal",className:j.cn(p&&"flex gap-4"),children:[t.jsx(j.TabsList,{className:j.cn(p?"flex-col h-auto":"",e.tabPosition==="bottom"&&"order-last",e.tabPosition==="right"&&"order-last"),children:e.sections.map((a,i)=>t.jsx(j.TabsTrigger,{value:I(a,i),className:p?"w-full justify-start":"",children:a.label||`Tab ${i+1}`},I(a,i)))}),t.jsx("div",{className:"flex-1",children:e.sections.map((a,i)=>t.jsx(j.TabsContent,{value:I(a,i),className:"mt-0",children:t.jsx(Y,{description:a.description,columns:a.columns||1,children:t.jsx(R.SchemaRenderer,{schema:{...M,fields:D(a),showSubmit:e.showSubmit!==!1&&e.mode!=="view",showCancel:e.showCancel!==!1}})})},I(a,i)))})]})})},ie=({schema:e,dataSource:l,className:c})=>{const[u,v]=o.useState(null),[m,C]=o.useState({}),[O,T]=o.useState(!0),[E,g]=o.useState(null),[x,N]=o.useState(0),[D,V]=o.useState(new Set),[$,I]=o.useState(!1),k=e.sections.length,M=x===0,p=x===k-1;o.useEffect(()=>{(async()=>{if(!l){T(!1);return}try{const w=await l.getObjectSchema(e.objectName);v(w)}catch(w){g(w)}})()},[e.objectName,l]),o.useEffect(()=>{(u||!l)&&(async()=>{if(e.mode==="create"||!e.recordId||!l){C(e.initialData||e.initialValues||{}),T(!1);return}try{const w=await l.findOne(e.objectName,e.recordId);C(w||{})}catch(w){g(w)}finally{T(!1)}})()},[u,e.mode,e.recordId,e.initialData,e.initialValues,l,e.objectName]);const a=o.useCallback(b=>{const w=[];for(const _ of b.fields){const A=typeof _=="string"?_:_.name;if(typeof _=="object")w.push(_);else if(u?.fields?.[A]){const q=u.fields[A];w.push({name:A,label:q.label||A,type:L.mapFieldTypeToFormType(q.type),required:q.required||!1,disabled:e.readOnly||e.mode==="view"||q.readonly,placeholder:q.placeholder,description:q.help||q.description,validation:L.buildValidationRules(q),field:q,options:q.options,multiple:q.multiple})}else w.push({name:A,label:A,type:"input"})}return w},[u,e.readOnly,e.mode]),i=o.useMemo(()=>x>=0&&x<k?a(e.sections[x]):[],[x,k,e.sections,a]),s=o.useCallback(async b=>{const w={...m,...b};if(C(w),V(_=>new Set(_).add(x)),p){I(!0);try{if(!l)return e.onSuccess&&await e.onSuccess(w),w;let _;return e.mode==="create"?_=await l.create(e.objectName,w):e.mode==="edit"&&e.recordId&&(_=await l.update(e.objectName,e.recordId,w)),e.onSuccess&&await e.onSuccess(_),_}catch(_){throw e.onError&&e.onError(_),_}finally{I(!1)}}else d(x+1)},[m,x,p,e,l]),d=o.useCallback(b=>{b>=0&&b<k&&(N(b),e.onStepChange&&e.onStepChange(b))},[k,e]),f=o.useCallback(()=>{d(x-1)},[x,d]),n=o.useCallback(()=>{e.onCancel&&e.onCancel()},[e]),S=o.useCallback(b=>{(e.allowSkip||D.has(b)||b<=x)&&d(b)},[e.allowSkip,D,x,d]);if(E)return t.jsxs("div",{className:"p-4 border border-red-300 bg-red-50 rounded-md",children:[t.jsx("h3",{className:"text-red-800 font-semibold",children:"Error loading form"}),t.jsx("p",{className:"text-red-600 text-sm mt-1",children:E.message})]});if(O)return t.jsxs("div",{className:"p-8 text-center",children:[t.jsx("div",{className:"inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900"}),t.jsx("p",{className:"mt-2 text-sm text-gray-600",children:"Loading form..."})]});const W=e.sections[x];return t.jsxs("div",{className:j.cn("w-full",c,e.className),children:[e.showStepIndicator!==!1&&t.jsx("nav",{"aria-label":"Progress",className:"mb-8",children:t.jsx("ol",{className:"flex items-center",children:e.sections.map((b,w)=>{const _=w===x,A=D.has(w),q=e.allowSkip||A||w<=x;return t.jsxs("li",{className:j.cn("relative flex-1",w!==k-1&&"pr-8 sm:pr-12"),children:[w!==k-1&&t.jsx("div",{className:"absolute top-3 sm:top-4 left-6 -right-4 sm:left-10 sm:-right-2 h-0.5","aria-hidden":"true",children:t.jsx("div",{className:j.cn("h-full",A?"bg-primary":"bg-muted")})}),t.jsxs("button",{type:"button",className:j.cn("group relative flex items-center",q?"cursor-pointer":"cursor-not-allowed"),onClick:()=>S(w),disabled:!q,children:[t.jsx("span",{className:j.cn("flex h-6 w-6 sm:h-8 sm:w-8 items-center justify-center rounded-full text-xs sm:text-sm font-medium transition-colors",A&&"bg-primary text-primary-foreground",_&&!A&&"border-2 border-primary bg-background text-primary",!_&&!A&&"border-2 border-muted bg-background text-muted-foreground"),children:A?t.jsx(H.Check,{className:"h-3 w-3 sm:h-4 sm:w-4"}):w+1}),t.jsx("span",{className:"ml-2 sm:ml-3 text-xs sm:text-sm font-medium hidden sm:block",children:t.jsx("span",{className:j.cn(_?"text-foreground":"text-muted-foreground"),children:b.label||`Step ${w+1}`})})]})]},w)})})}),t.jsx("div",{className:"min-h-[200px]",children:W&&t.jsx(Y,{label:W.label,description:W.description,columns:W.columns||1,children:i.length>0?t.jsx(R.SchemaRenderer,{schema:{type:"form",fields:i,layout:"vertical",defaultValues:m,showSubmit:!1,showCancel:!1,onSubmit:s}}):t.jsx("div",{className:"text-center py-8 text-muted-foreground",children:"No fields configured for this step"})})}),t.jsxs("div",{className:"flex items-center justify-between mt-6 pt-4 border-t",children:[t.jsx("div",{children:e.showCancel!==!1&&t.jsx(j.Button,{variant:"ghost",onClick:n,children:e.cancelText||"Cancel"})}),t.jsxs("div",{className:"flex items-center gap-2",children:[t.jsxs("span",{className:"text-sm text-muted-foreground mr-2",children:["Step ",x+1," of ",k]}),!M&&t.jsxs(j.Button,{variant:"outline",onClick:f,children:[t.jsx(H.ChevronLeft,{className:"h-4 w-4 mr-1"}),e.prevText||"Back"]}),p?t.jsx(j.Button,{onClick:()=>s(m),disabled:$||e.mode==="view",children:$?"Submitting...":e.submitText||(e.mode==="create"?"Create":"Update")}):t.jsxs(j.Button,{onClick:()=>s(m),children:[e.nextText||"Next",t.jsx(H.ChevronRight,{className:"h-4 w-4 ml-1"})]})]})]})]})},ne=({schema:e,dataSource:l,className:c})=>{const[u,v]=o.useState(null),[m,C]=o.useState({}),[O,T]=o.useState(!0),[E,g]=o.useState(null);o.useEffect(()=>{(async()=>{if(!l){T(!1);return}try{const i=await l.getObjectSchema(e.objectName);v(i)}catch(i){g(i),T(!1)}})()},[e.objectName,l]),o.useEffect(()=>{(u||!l)&&(async()=>{if(e.mode==="create"||!e.recordId){C(e.initialData||e.initialValues||{}),T(!1);return}if(!l){C(e.initialData||e.initialValues||{}),T(!1);return}try{const i=await l.findOne(e.objectName,e.recordId);C(i||{})}catch(i){g(i)}finally{T(!1)}})()},[u,e.mode,e.recordId,e.initialData,e.initialValues,l,e.objectName]);const x=o.useCallback(a=>{const i=[];for(const s of a.fields){const d=typeof s=="string"?s:s.name;if(typeof s=="object")i.push(s);else if(u?.fields?.[d]){const f=u.fields[d];i.push({name:d,label:f.label||d,type:L.mapFieldTypeToFormType(f.type),required:f.required||!1,disabled:e.readOnly||e.mode==="view"||f.readonly,placeholder:f.placeholder,description:f.help||f.description,validation:L.buildValidationRules(f),field:f,options:f.options,multiple:f.multiple})}else i.push({name:d,label:d,type:"input"})}return i},[u,e.readOnly,e.mode]),N=o.useCallback(async a=>{if(!l)return e.onSuccess&&await e.onSuccess(a),a;try{let i;return e.mode==="create"?i=await l.create(e.objectName,a):e.mode==="edit"&&e.recordId&&(i=await l.update(e.objectName,e.recordId,a)),e.onSuccess&&await e.onSuccess(i),i}catch(i){throw e.onError&&e.onError(i),i}},[e,l]),D=o.useCallback(()=>{e.onCancel&&e.onCancel()},[e]),V=o.useMemo(()=>e.sections.slice(0,1),[e.sections]),$=o.useMemo(()=>e.sections.slice(1),[e.sections]);o.useMemo(()=>e.sections.flatMap(a=>x(a)),[e.sections,x]);const I=e.splitDirection||"horizontal",k=e.splitSize||50;if(E)return t.jsxs("div",{className:"p-4 border border-red-300 bg-red-50 rounded-md",children:[t.jsx("h3",{className:"text-red-800 font-semibold",children:"Error loading form"}),t.jsx("p",{className:"text-red-600 text-sm mt-1",children:E.message})]});if(O)return t.jsxs("div",{className:"p-8 text-center",children:[t.jsx("div",{className:"inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900"}),t.jsx("p",{className:"mt-2 text-sm text-gray-600",children:"Loading form..."})]});const M={type:"form",layout:"vertical",defaultValues:m,onSubmit:N,onCancel:D},p=(a,i)=>t.jsx("div",{className:"space-y-4 p-4",children:a.map((s,d)=>t.jsx(Y,{label:s.label,description:s.description,columns:s.columns||1,children:t.jsx(R.SchemaRenderer,{schema:{...M,fields:x(s),showSubmit:i&&e.showSubmit!==!1&&e.mode!=="view",showCancel:i&&e.showCancel!==!1,submitLabel:e.submitText||(e.mode==="create"?"Create":"Update"),cancelLabel:e.cancelText}})},s.name||s.label||d))});return t.jsx("div",{className:j.cn("w-full",c,e.className),children:t.jsxs(j.ResizablePanelGroup,{orientation:I,className:"min-h-[300px] rounded-lg border",children:[t.jsx(j.ResizablePanel,{defaultSize:k,minSize:20,children:p(V,$.length===0)}),$.length>0&&t.jsxs(t.Fragment,{children:[t.jsx(j.ResizableHandle,{withHandle:e.splitResizable!==!1}),t.jsx(j.ResizablePanel,{defaultSize:100-k,minSize:20,children:p($,!0)})]})]})})},oe=({schema:e,dataSource:l,className:c})=>{const[u,v]=o.useState(null),[m,C]=o.useState([]),[O,T]=o.useState({}),[E,g]=o.useState(!0),[x,N]=o.useState(null),D=e.open!==!1,V=e.drawerSide||"right";o.useEffect(()=>{(async()=>{if(!l){g(!1);return}try{const d=await l.getObjectSchema(e.objectName);v(d)}catch(d){N(d),g(!1)}})()},[e.objectName,l]),o.useEffect(()=>{(u||!l)&&(async()=>{if(e.mode==="create"||!e.recordId){T(e.initialData||e.initialValues||{}),g(!1);return}if(!l){T(e.initialData||e.initialValues||{}),g(!1);return}try{const d=await l.findOne(e.objectName,e.recordId);T(d||{})}catch(d){N(d)}finally{g(!1)}})()},[u,e.mode,e.recordId,e.initialData,e.initialValues,l,e.objectName]);const $=o.useCallback(s=>{const d=[];for(const f of s.fields){const n=typeof f=="string"?f:f.name;if(typeof f=="object")d.push(f);else if(u?.fields?.[n]){const S=u.fields[n];d.push({name:n,label:S.label||n,type:L.mapFieldTypeToFormType(S.type),required:S.required||!1,disabled:e.readOnly||e.mode==="view"||S.readonly,placeholder:S.placeholder,description:S.help||S.description,validation:L.buildValidationRules(S),field:S,options:S.options,multiple:S.multiple})}else d.push({name:n,label:n,type:"input"})}return d},[u,e.readOnly,e.mode]);o.useEffect(()=>{if(!u&&l)return;if(e.customFields?.length){C(e.customFields),g(!1);return}if(e.sections?.length){g(!1);return}if(!u)return;const s=e.fields||Object.keys(u.fields||{}),d=[];for(const f of s){const n=typeof f=="string"?f:f.name;if(!n)continue;const S=u.fields?.[n];S&&d.push({name:n,label:S.label||n,type:L.mapFieldTypeToFormType(S.type),required:S.required||!1,disabled:e.readOnly||e.mode==="view"||S.readonly,placeholder:S.placeholder,description:S.help||S.description,validation:L.buildValidationRules(S),field:S,options:S.options,multiple:S.multiple})}C(d),g(!1)},[u,e.fields,e.customFields,e.sections,e.readOnly,e.mode,l]);const I=o.useCallback(async s=>{if(!l)return e.onSuccess&&await e.onSuccess(s),e.onOpenChange?.(!1),s;try{let d;return e.mode==="create"?d=await l.create(e.objectName,s):e.mode==="edit"&&e.recordId&&(d=await l.update(e.objectName,e.recordId,s)),e.onSuccess&&await e.onSuccess(d),e.onOpenChange?.(!1),d}catch(d){throw e.onError&&e.onError(d),d}},[e,l]),k=o.useCallback(()=>{e.onCancel&&e.onCancel(),e.onOpenChange?.(!1)},[e]),M=o.useMemo(()=>e.drawerWidth?V==="left"||V==="right"?{width:e.drawerWidth,maxWidth:e.drawerWidth}:{height:e.drawerWidth,maxHeight:e.drawerWidth}:void 0,[e.drawerWidth,V]),a={type:"form",layout:e.layout==="vertical"||e.layout==="horizontal"?e.layout:"vertical",defaultValues:O,submitLabel:e.submitText||(e.mode==="create"?"Create":"Update"),cancelLabel:e.cancelText,showSubmit:e.showSubmit!==!1&&e.mode!=="view",showCancel:e.showCancel!==!1,onSubmit:I,onCancel:k},i=()=>x?t.jsxs("div",{className:"p-4 border border-red-300 bg-red-50 rounded-md",children:[t.jsx("h3",{className:"text-red-800 font-semibold",children:"Error loading form"}),t.jsx("p",{className:"text-red-600 text-sm mt-1",children:x.message})]}):E?t.jsxs("div",{className:"p-8 text-center",children:[t.jsx("div",{className:"inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900"}),t.jsx("p",{className:"mt-2 text-sm text-gray-600",children:"Loading form..."})]}):e.sections?.length?t.jsx("div",{className:"space-y-6",children:e.sections.map((s,d)=>t.jsx(Y,{label:s.label,description:s.description,columns:s.columns||1,children:t.jsx(R.SchemaRenderer,{schema:{...a,fields:$(s),showSubmit:d===e.sections.length-1&&a.showSubmit,showCancel:d===e.sections.length-1&&a.showCancel}})},s.name||s.label||d))}):t.jsx(R.SchemaRenderer,{schema:{...a,fields:m,columns:e.columns}});return t.jsx(j.Sheet,{open:D,onOpenChange:e.onOpenChange,children:t.jsxs(j.SheetContent,{side:V,className:j.cn("overflow-y-auto",c,e.className),style:M,children:[(e.title||e.description)&&t.jsxs(j.SheetHeader,{children:[e.title&&t.jsx(j.SheetTitle,{children:e.title}),e.description&&t.jsx(j.SheetDescription,{children:e.description})]}),t.jsx("div",{className:"py-4",children:i()})]})})},se={sm:"max-w-sm",default:"max-w-lg",lg:"max-w-2xl",xl:"max-w-4xl",full:"max-w-[95vw] w-full"},ae=({schema:e,dataSource:l,className:c})=>{const[u,v]=o.useState(null),[m,C]=o.useState([]),[O,T]=o.useState({}),[E,g]=o.useState(!0),[x,N]=o.useState(null),D=e.open!==!1,V=se[e.modalSize||"default"]||se.default;o.useEffect(()=>{(async()=>{if(!l){g(!1);return}try{const s=await l.getObjectSchema(e.objectName);v(s)}catch(s){N(s),g(!1)}})()},[e.objectName,l]),o.useEffect(()=>{(u||!l)&&(async()=>{if(e.mode==="create"||!e.recordId){T(e.initialData||e.initialValues||{}),g(!1);return}if(!l){T(e.initialData||e.initialValues||{}),g(!1);return}try{const s=await l.findOne(e.objectName,e.recordId);T(s||{})}catch(s){N(s)}finally{g(!1)}})()},[u,e.mode,e.recordId,e.initialData,e.initialValues,l,e.objectName]);const $=o.useCallback(i=>{const s=[];for(const d of i.fields){const f=typeof d=="string"?d:d.name;if(typeof d=="object")s.push(d);else if(u?.fields?.[f]){const n=u.fields[f];s.push({name:f,label:n.label||f,type:L.mapFieldTypeToFormType(n.type),required:n.required||!1,disabled:e.readOnly||e.mode==="view"||n.readonly,placeholder:n.placeholder,description:n.help||n.description,validation:L.buildValidationRules(n),field:n,options:n.options,multiple:n.multiple})}else s.push({name:f,label:f,type:"input"})}return s},[u,e.readOnly,e.mode]);o.useEffect(()=>{if(!u&&l)return;if(e.customFields?.length){C(e.customFields),g(!1);return}if(e.sections?.length){g(!1);return}if(!u)return;const i=e.fields||Object.keys(u.fields||{}),s=[];for(const d of i){const f=typeof d=="string"?d:d.name;if(!f)continue;const n=u.fields?.[f];n&&s.push({name:f,label:n.label||f,type:L.mapFieldTypeToFormType(n.type),required:n.required||!1,disabled:e.readOnly||e.mode==="view"||n.readonly,placeholder:n.placeholder,description:n.help||n.description,validation:L.buildValidationRules(n),field:n,options:n.options,multiple:n.multiple})}C(s),g(!1)},[u,e.fields,e.customFields,e.sections,e.readOnly,e.mode,l]);const I=o.useCallback(async i=>{if(!l)return e.onSuccess&&await e.onSuccess(i),e.onOpenChange?.(!1),i;try{let s;return e.mode==="create"?s=await l.create(e.objectName,i):e.mode==="edit"&&e.recordId&&(s=await l.update(e.objectName,e.recordId,i)),e.onSuccess&&await e.onSuccess(s),e.onOpenChange?.(!1),s}catch(s){throw e.onError&&e.onError(s),s}},[e,l]),k=o.useCallback(()=>{e.onCancel&&e.onCancel(),e.onOpenChange?.(!1)},[e]),p={type:"form",layout:e.layout==="vertical"||e.layout==="horizontal"?e.layout:"vertical",defaultValues:O,submitLabel:e.submitText||(e.mode==="create"?"Create":"Update"),cancelLabel:e.cancelText,showSubmit:e.showSubmit!==!1&&e.mode!=="view",showCancel:e.showCancel!==!1,onSubmit:I,onCancel:k},a=()=>x?t.jsxs("div",{className:"p-4 border border-red-300 bg-red-50 rounded-md",children:[t.jsx("h3",{className:"text-red-800 font-semibold",children:"Error loading form"}),t.jsx("p",{className:"text-red-600 text-sm mt-1",children:x.message})]}):E?t.jsxs("div",{className:"p-8 text-center",children:[t.jsx("div",{className:"inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900"}),t.jsx("p",{className:"mt-2 text-sm text-gray-600",children:"Loading form..."})]}):e.sections?.length?t.jsx("div",{className:"space-y-6",children:e.sections.map((i,s)=>t.jsx(Y,{label:i.label,description:i.description,columns:i.columns||1,children:t.jsx(R.SchemaRenderer,{schema:{...p,fields:$(i),showSubmit:s===e.sections.length-1&&p.showSubmit,showCancel:s===e.sections.length-1&&p.showCancel}})},i.name||i.label||s))}):t.jsx(R.SchemaRenderer,{schema:{...p,fields:m,columns:e.columns}});return t.jsx(j.Dialog,{open:D,onOpenChange:e.onOpenChange,children:t.jsxs(j.DialogContent,{className:j.cn(V,"max-h-[90vh] overflow-y-auto",c,e.className),children:[(e.title||e.description)&&t.jsxs(j.DialogHeader,{children:[e.title&&t.jsx(j.DialogTitle,{children:e.title}),e.description&&t.jsx(j.DialogDescription,{children:e.description})]}),t.jsx("div",{className:"py-2",children:a()})]})})},de=({schema:e,dataSource:l})=>{if(e.formType==="tabbed"&&e.sections?.length)return t.jsx(le,{schema:{...e,formType:"tabbed",sections:e.sections.map(c=>({name:c.name,label:c.label,description:c.description,columns:c.columns,fields:c.fields})),defaultTab:e.defaultTab,tabPosition:e.tabPosition},dataSource:l,className:e.className});if(e.formType==="wizard"&&e.sections?.length)return t.jsx(ie,{schema:{...e,formType:"wizard",sections:e.sections.map(c=>({name:c.name,label:c.label,description:c.description,columns:c.columns,fields:c.fields})),allowSkip:e.allowSkip,showStepIndicator:e.showStepIndicator,nextText:e.nextText,prevText:e.prevText,onStepChange:e.onStepChange},dataSource:l,className:e.className});if(e.formType==="split"&&e.sections?.length)return t.jsx(ne,{schema:{...e,formType:"split",sections:e.sections.map(c=>({name:c.name,label:c.label,description:c.description,columns:c.columns,fields:c.fields})),splitDirection:e.splitDirection,splitSize:e.splitSize,splitResizable:e.splitResizable},dataSource:l,className:e.className});if(e.formType==="drawer"){const{layout:c,...u}=e,v=e.layout==="vertical"||e.layout==="horizontal"?e.layout:void 0;return t.jsx(oe,{schema:{...u,layout:v,formType:"drawer",sections:e.sections?.map(m=>({name:m.name,label:m.label,description:m.description,columns:m.columns,fields:m.fields})),open:e.open,onOpenChange:e.onOpenChange,drawerSide:e.drawerSide,drawerWidth:e.drawerWidth},dataSource:l,className:e.className})}if(e.formType==="modal"){const{layout:c,...u}=e,v=e.layout==="vertical"||e.layout==="horizontal"?e.layout:void 0;return t.jsx(ae,{schema:{...u,layout:v,formType:"modal",sections:e.sections?.map(m=>({name:m.name,label:m.label,description:m.description,columns:m.columns,fields:m.fields})),open:e.open,onOpenChange:e.onOpenChange,modalSize:e.modalSize,modalCloseButton:e.modalCloseButton},dataSource:l,className:e.className})}return t.jsx(xe,{schema:e,dataSource:l})},xe=({schema:e,dataSource:l})=>{const[c,u]=o.useState(null),[v,m]=o.useState([]),[C,O]=o.useState(null),[T,E]=o.useState(!0),[g,x]=o.useState(null),N=e.customFields&&e.customFields.length>0;o.useEffect(()=>{N&&(O(e.initialData||e.initialValues||{}),E(!1))},[N,e.initialData,e.initialValues]),o.useEffect(()=>{const p=async()=>{try{if(!l)throw new Error("DataSource is required when using ObjectQL schema fetching (inline fields not provided)");const a=await l.getObjectSchema(e.objectName);if(!a)throw new Error(`No schema found for object "${e.objectName}"`);u(a)}catch(a){x(a),E(!1)}};N?u({name:e.objectName,fields:{}}):e.objectName&&l?p():N||E(!1)},[e.objectName,l,N]),o.useEffect(()=>{c&&!N&&(async()=>{if(!e.recordId||e.mode==="create"){O(e.initialData||e.initialValues||{}),E(!1);return}if(!N){if(!l){x(new Error("DataSource is required for fetching record data (inline data not provided)")),E(!1);return}E(!0);try{const a=await l.findOne(e.objectName,e.recordId);O(a)}catch(a){console.error("Failed to fetch record:",a),x(a)}finally{E(!1)}}})()},[e.objectName,e.recordId,e.mode,e.initialValues,e.initialData,l,c,N]),o.useEffect(()=>{if(N&&e.customFields){m(e.customFields),E(!1);return}if(!c)return;const p=[],a=e.fields||Object.keys(c.fields||{});(Array.isArray(a)?a:Object.keys(a)).forEach(d=>{const f=typeof d=="string"?d:d.name;if(!f)return;const n=c.fields?.[f];if(!n&&!N)return;const S=!n?.permissions||n?.permissions.write!==!1;if(e.mode!=="view"&&!S)return;const W=e.customFields?.find(b=>b.name===f);if(W)p.push(W);else if(n){const b={name:f,label:n.label||d,type:L.mapFieldTypeToFormType(n.type),required:n.required||!1,disabled:e.readOnly||e.mode==="view"||n.readonly,placeholder:n.placeholder,description:n.help||n.description,validation:L.buildValidationRules(n),field:n};if((n.type==="select"||n.type==="lookup"||n.type==="master_detail")&&(b.options=n.options||[],b.multiple=n.multiple),(n.type==="number"||n.type==="currency"||n.type==="percent")&&(b.inputType="number",b.min=n.min,b.max=n.max,b.step=n.precision?Math.pow(10,-n.precision):void 0),n.type==="date"&&(b.inputType="date"),n.type==="datetime"&&(b.inputType="datetime-local"),(n.type==="text"||n.type==="textarea"||n.type==="markdown"||n.type==="html")&&(b.maxLength=n.max_length,b.minLength=n.min_length),(n.type==="file"||n.type==="image")&&(b.inputType="file",b.multiple=n.multiple,b.accept=n.accept?n.accept.join(","):void 0,n.max_size)){const w=`Max size: ${L.formatFileSize(n.max_size)}`;b.description=b.description?`${b.description} (${w})`:w}n.type==="email"&&(b.inputType="email"),n.type==="phone"&&(b.inputType="tel"),n.type==="url"&&(b.inputType="url"),n.type==="password"&&(b.inputType="password"),n.type==="time"&&(b.inputType="time"),(n.type==="formula"||n.type==="summary"||n.type==="auto_number")&&(b.disabled=!0),n.visible_on&&(b.visible=w=>L.evaluateCondition(n.visible_on,w)),p.push(b)}}),m(p),!N&&e.recordId&&e.mode!=="create"&&l||E(!1)},[c,e.fields,e.customFields,e.readOnly,e.mode,N,e.recordId,l]);const D=o.useCallback(async(p,a)=>{if(p&&(p.nativeEvent||p._reactName==="onSubmit")&&(console.warn("ObjectForm: Received Event instead of data in handleSubmit! This suggests a Form renderer issue."),a===void 0&&(a=p,p={})),N&&!l)return e.onSuccess&&await e.onSuccess(p),p;if(!l)throw new Error("DataSource is required for form submission (inline mode not configured)");try{let i;if(e.mode==="create")i=await l.create(e.objectName,p);else if(e.mode==="edit"&&e.recordId)i=await l.update(e.objectName,e.recordId,p);else throw new Error("Invalid form mode or missing record ID");return e.onSuccess&&await e.onSuccess(i),i}catch(i){throw console.error("Failed to submit form:",i),e.onError&&e.onError(i),i}},[e,l,N]),V=o.useCallback(()=>{e.onCancel&&e.onCancel()},[e]),I={...o.useMemo(()=>{if(!c?.fields)return{};const p={};return Object.keys(c.fields).forEach(a=>{const i=c.fields[a];i.defaultValue!==void 0&&(p[a]=i.defaultValue)}),p},[c]),...C};if(g)return t.jsxs("div",{className:"p-3 sm:p-4 border border-red-300 bg-red-50 rounded-md",children:[t.jsx("h3",{className:"text-red-800 font-semibold",children:"Error loading form"}),t.jsx("p",{className:"text-red-600 text-sm mt-1",children:g.message})]});if(T)return t.jsxs("div",{className:"p-4 sm:p-8 text-center",children:[t.jsx("div",{className:"inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900"}),t.jsx("p",{className:"mt-2 text-sm text-gray-600",children:"Loading form..."})]});const k=e.layout==="vertical"||e.layout==="horizontal"?e.layout:"vertical";if(e.sections?.length&&(!e.formType||e.formType==="simple"))return t.jsx("div",{className:"w-full space-y-6",children:e.sections.map((p,a)=>{const i=p.fields.map(d=>typeof d=="string"?d:d.name),s=v.filter(d=>i.includes(d.name));return t.jsx(Y,{label:p.label,description:p.description,collapsible:p.collapsible,collapsed:p.collapsed,columns:p.columns,children:t.jsx(R.SchemaRenderer,{schema:{type:"form",fields:s,layout:k,defaultValues:I,showSubmit:a===e.sections.length-1&&e.showSubmit!==!1&&e.mode!=="view",showCancel:a===e.sections.length-1&&e.showCancel!==!1,submitLabel:e.submitText||(e.mode==="create"?"Create":"Update"),cancelLabel:e.cancelText,onSubmit:D,onCancel:V}})},p.name||p.label||a)})});const M={type:"form",fields:v,layout:k,columns:e.columns,submitLabel:e.submitText||(e.mode==="create"?"Create":"Update"),cancelLabel:e.cancelText,showSubmit:e.showSubmit!==!1&&e.mode!=="view",showCancel:e.showCancel!==!1,resetOnSubmit:e.showReset,defaultValues:I,onSubmit:D,onCancel:V,className:e.className};return t.jsx("div",{className:"w-full",children:t.jsx(R.SchemaRenderer,{schema:M})})},ue=({schema:e})=>t.jsx(de,{schema:e});K.ComponentRegistry.register("object-form",ue,{namespace:"plugin-form",label:"Object Form",category:"plugin",inputs:[{name:"objectName",type:"string",label:"Object Name",required:!0},{name:"fields",type:"array",label:"Fields"},{name:"mode",type:"enum",label:"Mode",enum:["create","edit","view"]},{name:"formType",type:"enum",label:"Form Type",enum:["simple","tabbed","wizard","split","drawer","modal"]},{name:"sections",type:"array",label:"Sections"},{name:"title",type:"string",label:"Title"},{name:"description",type:"string",label:"Description"},{name:"layout",type:"enum",label:"Layout",enum:["vertical","horizontal","inline","grid"]},{name:"columns",type:"number",label:"Columns"},{name:"defaultTab",type:"string",label:"Default Tab"},{name:"tabPosition",type:"enum",label:"Tab Position",enum:["top","bottom","left","right"]},{name:"allowSkip",type:"boolean",label:"Allow Skip Steps"},{name:"showStepIndicator",type:"boolean",label:"Show Step Indicator"},{name:"splitDirection",type:"enum",label:"Split Direction",enum:["horizontal","vertical"]},{name:"splitSize",type:"number",label:"Split Panel Size (%)"},{name:"splitResizable",type:"boolean",label:"Split Resizable"},{name:"drawerSide",type:"enum",label:"Drawer Side",enum:["top","bottom","left","right"]},{name:"drawerWidth",type:"string",label:"Drawer Width"},{name:"modalSize",type:"enum",label:"Modal Size",enum:["sm","default","lg","xl","full"]}]}),K.ComponentRegistry.register("form",ue,{namespace:"view",skipFallback:!0,label:"Data Form View",category:"view",inputs:[{name:"objectName",type:"string",label:"Object Name",required:!0},{name:"fields",type:"array",label:"Fields"},{name:"mode",type:"enum",label:"Mode",enum:["create","edit","view"]}]}),z.DrawerForm=oe,z.FormSection=Y,z.ModalForm=ae,z.ObjectForm=de,z.SplitForm=ne,z.TabbedForm=le,z.WizardForm=ie,Object.defineProperty(z,Symbol.toStringTag,{value:"Module"})}));
@@ -0,0 +1,23 @@
1
+ import { StoryObj } from '@storybook/react';
2
+ declare const meta: {
3
+ title: string;
4
+ component: import('react').ForwardRefExoticComponent<Omit<{
5
+ schema: import('../../core/src').SchemaNode;
6
+ } & Record<string, any>, "ref"> & import('react').RefAttributes<any>>;
7
+ parameters: {
8
+ layout: string;
9
+ };
10
+ tags: string[];
11
+ argTypes: {
12
+ schema: {
13
+ table: {
14
+ disable: true;
15
+ };
16
+ };
17
+ };
18
+ };
19
+ export default meta;
20
+ type Story = StoryObj<typeof meta>;
21
+ export declare const Default: Story;
22
+ export declare const WithSections: Story;
23
+ export declare const ComplexFields: Story;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * ObjectUI
3
+ * Copyright (c) 2024-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@object-ui/plugin-form",
3
- "version": "2.0.0",
3
+ "version": "3.0.1",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Form plugin for Object UI",
@@ -16,23 +16,23 @@
16
16
  },
17
17
  "dependencies": {
18
18
  "lucide-react": "^0.563.0",
19
- "@object-ui/core": "2.0.0",
20
- "@object-ui/components": "2.0.0",
21
- "@object-ui/fields": "2.0.0",
22
- "@object-ui/react": "2.0.0",
23
- "@object-ui/types": "2.0.0"
19
+ "@object-ui/components": "3.0.1",
20
+ "@object-ui/core": "3.0.1",
21
+ "@object-ui/fields": "3.0.1",
22
+ "@object-ui/react": "3.0.1",
23
+ "@object-ui/types": "3.0.1"
24
24
  },
25
25
  "peerDependencies": {
26
26
  "react": "^18.0.0 || ^19.0.0",
27
27
  "react-dom": "^18.0.0 || ^19.0.0"
28
28
  },
29
29
  "devDependencies": {
30
- "@vitejs/plugin-react": "^5.1.3",
31
- "msw": "^2.12.9",
30
+ "@vitejs/plugin-react": "^5.1.4",
31
+ "msw": "^2.12.10",
32
32
  "typescript": "^5.9.3",
33
33
  "vite": "^7.3.1",
34
34
  "vite-plugin-dts": "^4.5.4",
35
- "@object-ui/data-objectstack": "2.0.0"
35
+ "@object-ui/data-objectstack": "3.0.1"
36
36
  },
37
37
  "scripts": {
38
38
  "build": "vite build",
@@ -0,0 +1,85 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { SchemaRenderer, SchemaRendererProvider } from '@object-ui/react';
3
+ import type { BaseSchema } from '@object-ui/types';
4
+ import { createStorybookDataSource } from '@storybook-config/datasource';
5
+
6
+ const meta = {
7
+ title: 'Plugins/ObjectForm',
8
+ component: SchemaRenderer,
9
+ parameters: {
10
+ layout: 'centered',
11
+ },
12
+ tags: ['autodocs'],
13
+ argTypes: {
14
+ schema: { table: { disable: true } },
15
+ },
16
+ } satisfies Meta<any>;
17
+
18
+ export default meta;
19
+ type Story = StoryObj<typeof meta>;
20
+
21
+ const dataSource = createStorybookDataSource();
22
+
23
+ const renderStory = (args: any) => (
24
+ <SchemaRendererProvider dataSource={dataSource}>
25
+ <SchemaRenderer schema={args as unknown as BaseSchema} />
26
+ </SchemaRendererProvider>
27
+ );
28
+
29
+ export const Default: Story = {
30
+ render: renderStory,
31
+ args: {
32
+ type: 'object-form',
33
+ objectName: 'Contact',
34
+ customFields: [
35
+ { name: 'firstName', label: 'First Name', type: 'text', required: true },
36
+ { name: 'lastName', label: 'Last Name', type: 'text', required: true },
37
+ { name: 'email', label: 'Email', type: 'email', required: true },
38
+ { name: 'phone', label: 'Phone', type: 'tel' },
39
+ ],
40
+ className: 'w-full max-w-2xl',
41
+ } as any,
42
+ };
43
+
44
+ export const WithSections: Story = {
45
+ render: renderStory,
46
+ args: {
47
+ type: 'object-form',
48
+ objectName: 'Employee',
49
+ sections: [
50
+ {
51
+ title: 'Personal Information',
52
+ fields: [
53
+ { name: 'firstName', label: 'First Name', type: 'text', required: true },
54
+ { name: 'lastName', label: 'Last Name', type: 'text', required: true },
55
+ { name: 'dateOfBirth', label: 'Date of Birth', type: 'date' },
56
+ ],
57
+ },
58
+ {
59
+ title: 'Work Details',
60
+ fields: [
61
+ { name: 'department', label: 'Department', type: 'select', options: ['Engineering', 'Marketing', 'Sales', 'HR'] },
62
+ { name: 'role', label: 'Role', type: 'text' },
63
+ { name: 'startDate', label: 'Start Date', type: 'date' },
64
+ ],
65
+ },
66
+ ],
67
+ className: 'w-full max-w-2xl',
68
+ } as any,
69
+ };
70
+
71
+ export const ComplexFields: Story = {
72
+ render: renderStory,
73
+ args: {
74
+ type: 'object-form',
75
+ objectName: 'Product',
76
+ customFields: [
77
+ { name: 'name', label: 'Product Name', type: 'text', required: true },
78
+ { name: 'category', label: 'Category', type: 'select', options: ['Electronics', 'Clothing', 'Food', 'Books'], required: true },
79
+ { name: 'price', label: 'Price', type: 'number', required: true },
80
+ { name: 'inStock', label: 'In Stock', type: 'checkbox' },
81
+ { name: 'description', label: 'Description', type: 'textarea', rows: 4 },
82
+ ],
83
+ className: 'w-full max-w-2xl',
84
+ } as any,
85
+ };
@@ -511,7 +511,7 @@ const SimpleObjectForm: React.FC<ObjectFormProps> = ({
511
511
  // Render error state
512
512
  if (error) {
513
513
  return (
514
- <div className="p-4 border border-red-300 bg-red-50 rounded-md">
514
+ <div className="p-3 sm:p-4 border border-red-300 bg-red-50 rounded-md">
515
515
  <h3 className="text-red-800 font-semibold">Error loading form</h3>
516
516
  <p className="text-red-600 text-sm mt-1">{error.message}</p>
517
517
  </div>
@@ -521,7 +521,7 @@ const SimpleObjectForm: React.FC<ObjectFormProps> = ({
521
521
  // Render loading state
522
522
  if (loading) {
523
523
  return (
524
- <div className="p-8 text-center">
524
+ <div className="p-4 sm:p-8 text-center">
525
525
  <div className="inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900"></div>
526
526
  <p className="mt-2 text-sm text-gray-600">Loading form...</p>
527
527
  </div>
@@ -364,7 +364,7 @@ export const WizardForm: React.FC<WizardFormProps> = ({
364
364
  {/* Connector line */}
365
365
  {index !== totalSteps - 1 && (
366
366
  <div
367
- className="absolute top-4 left-8 -right-4 sm:left-10 sm:-right-2 h-0.5"
367
+ className="absolute top-3 sm:top-4 left-6 -right-4 sm:left-10 sm:-right-2 h-0.5"
368
368
  aria-hidden="true"
369
369
  >
370
370
  <div
@@ -385,24 +385,24 @@ export const WizardForm: React.FC<WizardFormProps> = ({
385
385
  onClick={() => handleStepClick(index)}
386
386
  disabled={!isClickable}
387
387
  >
388
- {/* Step circle */}
388
+ {/* Step circle - smaller on mobile */}
389
389
  <span
390
390
  className={cn(
391
- 'flex h-8 w-8 items-center justify-center rounded-full text-sm font-medium transition-colors',
391
+ 'flex h-6 w-6 sm:h-8 sm:w-8 items-center justify-center rounded-full text-xs sm:text-sm font-medium transition-colors',
392
392
  isCompleted && 'bg-primary text-primary-foreground',
393
393
  isActive && !isCompleted && 'border-2 border-primary bg-background text-primary',
394
394
  !isActive && !isCompleted && 'border-2 border-muted bg-background text-muted-foreground'
395
395
  )}
396
396
  >
397
397
  {isCompleted ? (
398
- <Check className="h-4 w-4" />
398
+ <Check className="h-3 w-3 sm:h-4 sm:w-4" />
399
399
  ) : (
400
400
  index + 1
401
401
  )}
402
402
  </span>
403
403
 
404
404
  {/* Step label */}
405
- <span className="ml-3 text-sm font-medium hidden sm:block">
405
+ <span className="ml-2 sm:ml-3 text-xs sm:text-sm font-medium hidden sm:block">
406
406
  <span
407
407
  className={cn(
408
408
  isActive ? 'text-foreground' : 'text-muted-foreground'
@@ -0,0 +1,286 @@
1
+ /**
2
+ * ObjectUI
3
+ * Copyright (c) 2024-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+
9
+ /**
10
+ * P3.4 Integration Test — Form Validation + Submit Workflow
11
+ *
12
+ * Tests the full lifecycle: required-field validation → inline errors →
13
+ * successful submit → form reset.
14
+ */
15
+
16
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
17
+ import { render, screen, waitFor } from '@testing-library/react';
18
+ import userEvent from '@testing-library/user-event';
19
+ import React from 'react';
20
+ import { ObjectForm } from '../ObjectForm';
21
+
22
+ // ─── Shared Fixtures ────────────────────────────────────────────────────
23
+
24
+ const mockObjectSchema = {
25
+ name: 'contacts',
26
+ fields: {
27
+ firstName: { label: 'First Name', type: 'text', required: true },
28
+ lastName: { label: 'Last Name', type: 'text', required: false },
29
+ email: { label: 'Email', type: 'email', required: true },
30
+ },
31
+ };
32
+
33
+ const createMockDataSource = () => ({
34
+ getObjectSchema: vi.fn().mockResolvedValue(mockObjectSchema),
35
+ findOne: vi.fn().mockResolvedValue({}),
36
+ find: vi.fn().mockResolvedValue([]),
37
+ create: vi.fn().mockResolvedValue({ id: '1' }),
38
+ update: vi.fn().mockResolvedValue({ id: '1' }),
39
+ delete: vi.fn().mockResolvedValue(true),
40
+ });
41
+
42
+ // ─── Tests ──────────────────────────────────────────────────────────────
43
+
44
+ describe('P3.4 Form Validation + Submit Workflow', () => {
45
+ let mockDataSource: ReturnType<typeof createMockDataSource>;
46
+
47
+ beforeEach(() => {
48
+ mockDataSource = createMockDataSource();
49
+ });
50
+
51
+ // --- Required field validation before submit ---
52
+
53
+ it('validates required fields and prevents submission when empty', async () => {
54
+ const user = userEvent.setup();
55
+ const onSuccess = vi.fn();
56
+
57
+ render(
58
+ <ObjectForm
59
+ schema={{
60
+ type: 'object-form',
61
+ objectName: 'contacts',
62
+ mode: 'create',
63
+ fields: ['firstName', 'email'],
64
+ onSuccess,
65
+ }}
66
+ dataSource={mockDataSource as any}
67
+ />,
68
+ );
69
+
70
+ // Wait for the form to load
71
+ await waitFor(() => {
72
+ expect(screen.getByText('First Name')).toBeInTheDocument();
73
+ });
74
+
75
+ // Click submit without filling in required fields
76
+ const submitButton = screen.getByRole('button', { name: /create/i });
77
+ await user.click(submitButton);
78
+
79
+ // The data source should NOT have been called
80
+ await waitFor(() => {
81
+ expect(mockDataSource.create).not.toHaveBeenCalled();
82
+ });
83
+ expect(onSuccess).not.toHaveBeenCalled();
84
+ });
85
+
86
+ // --- Inline validation errors ---
87
+
88
+ it('shows inline validation error messages for required fields', async () => {
89
+ const user = userEvent.setup();
90
+
91
+ render(
92
+ <ObjectForm
93
+ schema={{
94
+ type: 'object-form',
95
+ objectName: 'contacts',
96
+ mode: 'create',
97
+ fields: ['firstName', 'email'],
98
+ }}
99
+ dataSource={mockDataSource as any}
100
+ />,
101
+ );
102
+
103
+ await waitFor(() => {
104
+ expect(screen.getByText('First Name')).toBeInTheDocument();
105
+ });
106
+
107
+ // Submit with empty required fields
108
+ const submitButton = screen.getByRole('button', { name: /create/i });
109
+ await user.click(submitButton);
110
+
111
+ // Validation messages should appear
112
+ await waitFor(() => {
113
+ expect(screen.getByText(/first name is required/i)).toBeInTheDocument();
114
+ });
115
+ });
116
+
117
+ // --- Successful submit calls handler ---
118
+
119
+ it('calls onSuccess handler after successful submission', async () => {
120
+ const user = userEvent.setup();
121
+ const onSuccess = vi.fn();
122
+
123
+ render(
124
+ <ObjectForm
125
+ schema={{
126
+ type: 'object-form',
127
+ objectName: 'contacts',
128
+ mode: 'create',
129
+ fields: ['firstName', 'email'],
130
+ onSuccess,
131
+ }}
132
+ dataSource={mockDataSource as any}
133
+ />,
134
+ );
135
+
136
+ // Wait for the form to load
137
+ await waitFor(() => {
138
+ expect(screen.getByText('First Name')).toBeInTheDocument();
139
+ });
140
+
141
+ // Fill in the required fields
142
+ const inputs = screen.getAllByRole('textbox');
143
+ // First Name input
144
+ await user.type(inputs[0], 'John');
145
+ // Email input
146
+ await user.type(inputs[1], 'john@example.com');
147
+
148
+ // Submit
149
+ const submitButton = screen.getByRole('button', { name: /create/i });
150
+ await user.click(submitButton);
151
+
152
+ // dataSource.create should have been called
153
+ await waitFor(() => {
154
+ expect(mockDataSource.create).toHaveBeenCalledWith(
155
+ 'contacts',
156
+ expect.objectContaining({
157
+ firstName: 'John',
158
+ email: 'john@example.com',
159
+ }),
160
+ );
161
+ });
162
+
163
+ // onSuccess should have been called with result
164
+ await waitFor(() => {
165
+ expect(onSuccess).toHaveBeenCalledWith({ id: '1' });
166
+ });
167
+ });
168
+
169
+ // --- Form reset after submit ---
170
+
171
+ it('resets form fields after successful submission when showReset is true', async () => {
172
+ const user = userEvent.setup();
173
+
174
+ render(
175
+ <ObjectForm
176
+ schema={{
177
+ type: 'object-form',
178
+ objectName: 'contacts',
179
+ mode: 'create',
180
+ fields: ['firstName', 'email'],
181
+ showReset: true,
182
+ onSuccess: vi.fn(),
183
+ }}
184
+ dataSource={mockDataSource as any}
185
+ />,
186
+ );
187
+
188
+ await waitFor(() => {
189
+ expect(screen.getByText('First Name')).toBeInTheDocument();
190
+ });
191
+
192
+ const inputs = screen.getAllByRole('textbox');
193
+ await user.type(inputs[0], 'Jane');
194
+ await user.type(inputs[1], 'jane@example.com');
195
+
196
+ // Submit
197
+ const submitButton = screen.getByRole('button', { name: /create/i });
198
+ await user.click(submitButton);
199
+
200
+ // After successful submit the inputs should be cleared
201
+ await waitFor(() => {
202
+ expect(mockDataSource.create).toHaveBeenCalled();
203
+ });
204
+
205
+ await waitFor(() => {
206
+ expect(inputs[0]).toHaveValue('');
207
+ });
208
+ });
209
+
210
+ // --- Inline-field form (no dataSource) ---
211
+
212
+ it('supports inline customFields without a dataSource', async () => {
213
+ const user = userEvent.setup();
214
+ const onSuccess = vi.fn();
215
+
216
+ render(
217
+ <ObjectForm
218
+ schema={{
219
+ type: 'object-form',
220
+ objectName: 'inline_form',
221
+ mode: 'create',
222
+ customFields: [
223
+ { name: 'username', label: 'Username', type: 'input', required: true },
224
+ ],
225
+ onSuccess,
226
+ }}
227
+ />,
228
+ );
229
+
230
+ await waitFor(() => {
231
+ expect(screen.getByText('Username')).toBeInTheDocument();
232
+ });
233
+
234
+ // Submit empty — should not succeed
235
+ const submitButton = screen.getByRole('button', { name: /create/i });
236
+ await user.click(submitButton);
237
+ expect(onSuccess).not.toHaveBeenCalled();
238
+
239
+ // Fill in and resubmit
240
+ const input = screen.getByRole('textbox');
241
+ await user.type(input, 'admin');
242
+ await user.click(submitButton);
243
+
244
+ await waitFor(() => {
245
+ expect(onSuccess).toHaveBeenCalledWith(
246
+ expect.objectContaining({ username: 'admin' }),
247
+ );
248
+ });
249
+ });
250
+
251
+ // --- Error callback on failed submission ---
252
+
253
+ it('calls onError when dataSource.create rejects', async () => {
254
+ const user = userEvent.setup();
255
+ const onError = vi.fn();
256
+ mockDataSource.create.mockRejectedValueOnce(new Error('Network failure'));
257
+
258
+ render(
259
+ <ObjectForm
260
+ schema={{
261
+ type: 'object-form',
262
+ objectName: 'contacts',
263
+ mode: 'create',
264
+ fields: ['firstName', 'email'],
265
+ onError,
266
+ }}
267
+ dataSource={mockDataSource as any}
268
+ />,
269
+ );
270
+
271
+ await waitFor(() => {
272
+ expect(screen.getByText('First Name')).toBeInTheDocument();
273
+ });
274
+
275
+ const inputs = screen.getAllByRole('textbox');
276
+ await user.type(inputs[0], 'John');
277
+ await user.type(inputs[1], 'john@example.com');
278
+
279
+ const submitButton = screen.getByRole('button', { name: /create/i });
280
+ await user.click(submitButton);
281
+
282
+ await waitFor(() => {
283
+ expect(onError).toHaveBeenCalledWith(expect.any(Error));
284
+ });
285
+ });
286
+ });