@rilaykit/forms 12.0.0 → 13.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- 'use strict';var xe=require('react'),core=require('@rilaykit/core'),jsxRuntime=require('react/jsx-runtime');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var xe__default=/*#__PURE__*/_interopDefault(xe);var E=class o{constructor(e,r){this.rows=[];this.idGenerator=new core.IdGenerator;this.config=e,this.formId=r||`form-${Math.random().toString(36).substring(2,15)}`;}static create(e,r){return new o(e,r)}createFormField(e){let r=this.config.getComponent(e.type);if(!r)throw new Error(`No component found with type "${e.type}"`);let t;return (r.validation||e.validation)&&(t={validateOnChange:e.validation?.validateOnChange??r.validation?.validateOnChange,validateOnBlur:e.validation?.validateOnBlur??r.validation?.validateOnBlur,debounceMs:e.validation?.debounceMs??r.validation?.debounceMs,validate:(()=>{let i=r.validation?.validate,n=e.validation?.validate;if(!i)return n;if(!n)return i;let l=Array.isArray(i)?i:[i],u=Array.isArray(n)?n:[n];return [...l,...u]})()}),{id:e.id||this.idGenerator.next("field"),componentId:r.id,props:{...r.defaultProps,...e.props},validation:t,conditions:e.conditions}}createRow(e){if(e.length===0)throw new Error("At least one field is required");if(e.length>3)throw new Error("Maximum 3 fields per row");let r=e.map(t=>this.createFormField(t));return {id:this.idGenerator.next("row"),fields:r,maxColumns:e.length}}add(...e){let r,t=false;if(e.length===1&&Array.isArray(e[0])?(r=e[0],t=true):r=e,r.length===0)throw new Error("At least one field is required");if(t&&r.length>3)throw new Error("Maximum 3 fields per row");if(r.length===1){let i=this.createRow(r);return this.rows.push(i),this}if(r.length<=3){let i=this.createRow(r);return this.rows.push(i),this}for(let i of r){let n=this.createRow([i]);this.rows.push(n);}return this}addSeparateRows(e){for(let r of e)this.add(r);return this}setId(e){return this.formId=e,this}updateField(e,r){let t=this.findField(e);if(!t)throw new Error(`Field with ID "${e}" not found`);return Object.assign(t,{...r,props:{...t.props,...r.props}}),this}findField(e){for(let r of this.rows){let t=r.fields.find(i=>i.id===e);if(t)return t}return null}removeField(e){return this.rows=this.rows.map(r=>({...r,fields:r.fields.filter(t=>t.id!==e)})).filter(r=>r.fields.length>0),this}getField(e){return this.findField(e)||void 0}getFields(){return this.rows.flatMap(e=>e.fields)}getRows(){return [...this.rows]}clear(){return this.rows=[],this.idGenerator.reset(),this}setValidation(e){return this.formValidation=e,this}addFieldValidation(e,r){console.warn("addFieldValidation is deprecated. Use updateField with validation.validate property instead.");let t=this.findField(e);if(!t)throw new Error(`Field with ID "${e}" not found`);let i={...t.validation,...r};return this.updateField(e,{validation:i})}addFieldConditions(e,r){let t=this.findField(e);if(!t)throw new Error(`Field with ID "${e}" not found`);let i={...t.conditions,...r};return this.updateField(e,{conditions:i})}clone(e){let r=new o(this.config,e||`${this.formId}-clone`);return r.rows=core.deepClone(this.rows),r}validate(){let e=[],r=this.getFields(),t=r.map(i=>i.id);try{core.ensureUnique(t,"field");}catch(i){e.push(i instanceof Error?i.message:String(i));}for(let i of r)this.config.hasComponent(i.componentId)||e.push(`Component "${i.componentId}" not found for field "${i.id}"`);for(let i of this.rows)i.fields.length>3&&e.push(`Row "${i.id}" has ${i.fields.length} fields, maximum is 3`),i.fields.length===0&&e.push(`Row "${i.id}" is empty`);return e}build(){let e=this.validate();if(e.length>0)throw new Error(`Form validation failed: ${e.join(", ")}`);return {id:this.formId,rows:[...this.rows],allFields:this.getFields(),config:this.config,renderConfig:this.config.getFormRenderConfig(),validation:this.formValidation}}toJSON(){return {id:this.formId,rows:this.rows}}fromJSON(e){return e.id&&(this.formId=e.id),e.rows&&(this.rows=e.rows),this}getStats(){let e=this.getFields(),r=this.rows.map(t=>t.fields.length);return {totalFields:e.length,totalRows:this.rows.length,averageFieldsPerRow:this.rows.length>0?e.length/this.rows.length:0,maxFieldsInRow:r.length>0?Math.max(...r):0,minFieldsInRow:r.length>0?Math.min(...r):0}}};function Ge(o,e={},r={}){return xe.useMemo(()=>{if(!o)return {visible:r.visible??true,disabled:r.disabled??false,required:r.required??false,readonly:r.readonly??false};let t=i=>{try{return i&&typeof i=="object"&&"build"in i?core.evaluateCondition(i.build(),e):core.evaluateCondition(i,e)}catch(n){return console.warn("Error evaluating condition:",n),false}};return {visible:o.visible?t(o.visible):r.visible??true,disabled:o.disabled?t(o.disabled):r.disabled??false,required:o.required?t(o.required):r.required??false,readonly:o.readonly?t(o.readonly):r.readonly??false}},[o,e,r])}function H(o,e={}){return xe.useMemo(()=>{let r={};for(let[t,i]of Object.entries(o))if(r[t]={visible:true,disabled:false,required:false,readonly:false},i){let n=l=>{try{return l&&typeof l=="object"&&"build"in l?core.evaluateCondition(l.build(),e):core.evaluateCondition(l,e)}catch(u){return console.warn(`Error evaluating condition for field ${t}:`,u),false}};r[t]={visible:i.visible?n(i.visible):true,disabled:i.disabled?n(i.disabled):false,required:i.required?n(i.required):false,readonly:i.readonly?n(i.readonly):false};}return r},[o,e])}function W({formConfig:o,formValues:e}){let r=xe.useMemo(()=>{let f={};for(let s of o.allFields)s.conditions&&(f[s.id]=s.conditions);return f},[o.allFields]),t=xe.useMemo(()=>Object.keys(r).length>0,[r]),i=H(t?r:{},t?e:{}),n=xe.useCallback(f=>i[f],[i]),l=xe.useCallback(f=>{let s=i[f];return s?s.visible:true},[i]),u=xe.useCallback(f=>{let s=i[f];return s?s.disabled:false},[i]),F=xe.useCallback(f=>{let s=i[f];return s?s.required:false},[i]),g=xe.useCallback(f=>{let s=i[f];return s?s.readonly:false},[i]);return xe.useMemo(()=>({fieldConditions:i,hasConditionalFields:t,getFieldCondition:n,isFieldVisible:l,isFieldDisabled:u,isFieldRequired:F,isFieldReadonly:g}),[i,t,n,l,u,F,g])}function ce(o,e){switch(e.type){case "SET_VALUE":return {...o,values:{...o.values,[e.fieldId]:e.value},isDirty:true};case "SET_FIELD_ERRORS":return {...o,errors:{...o.errors,[e.fieldId]:e.errors}};case "SET_FIELD_VALIDATION_STATE":return {...o,validationState:{...o.validationState,[e.fieldId]:e.state}};case "SET_FIELD_TOUCHED":return {...o,touched:{...o.touched,[e.fieldId]:true}};case "SET_SUBMITTING":return {...o,isSubmitting:e.isSubmitting};case "RESET":return {values:e.values||{},errors:{},validationState:{},touched:{},isDirty:false,isSubmitting:false};default:return o}}function J({defaultValues:o={},onFieldChange:e}){let r={values:o,errors:{},validationState:{},touched:{},isDirty:false,isSubmitting:false},[t,i]=xe.useReducer(ce,r),n=xe.useRef(e);n.current=e;let l=xe.useCallback((d,p)=>{i({type:"SET_VALUE",fieldId:d,value:p}),n.current?.(d,p,{...t.values,[d]:p});},[t.values]),u=xe.useCallback(d=>{i({type:"SET_FIELD_TOUCHED",fieldId:d});},[]),F=xe.useCallback((d,p)=>{i({type:"SET_FIELD_ERRORS",fieldId:d,errors:p});},[]),g=xe.useCallback(d=>{i({type:"SET_FIELD_ERRORS",fieldId:d,errors:[]});},[]),f=xe.useCallback((d,p)=>{i({type:"SET_FIELD_VALIDATION_STATE",fieldId:d,state:p});},[]),s=xe.useCallback(d=>{i({type:"SET_SUBMITTING",isSubmitting:d});},[]),m=xe.useCallback(d=>{i({type:"RESET",values:d});},[]),c=xe.useCallback(()=>{let d=Object.values(t.errors).some(a=>a.length>0),p=Object.values(t.validationState).some(a=>a==="invalid");return !d&&!p},[t.errors,t.validationState]);return {formState:t,setValue:l,setFieldTouched:u,setError:F,clearError:g,setFieldValidationState:f,setSubmitting:s,reset:m,isFormValid:c}}function Q({formState:o,onSubmit:e,validateForm:r,setSubmitting:t}){let i=xe.useRef(e);return i.current=e,{submit:xe.useCallback(async l=>{l?.preventDefault();try{return t(!0),(await r()).isValid?(i.current&&await i.current(o.values),!0):!1}catch(u){return console.error("Error during form submission:",u),false}finally{t(false);}},[o.values,r,t])}}function B(){return {isValid:true,errors:[]}}function K({formConfig:o,formState:e,conditionsHelpers:r,setFieldValidationState:t,setError:i}){let n=xe.useRef(o),l=xe.useRef(r),u=xe.useRef(t),F=xe.useRef(i);n.current=o,l.current=r,u.current=t,F.current=i;let g=xe.useCallback(async(s,m)=>{let c=n.current.allFields.find(a=>a.id===s);if(!c)return B();if(!l.current.isFieldVisible(s))return F.current(s,[]),u.current(s,"valid"),B();if(!c.validation||!core.hasUnifiedValidation(c.validation))return F.current(s,[]),u.current(s,"valid"),B();let d=m!==void 0?m:e.values[s],p=core.createValidationContext({fieldId:s,formId:n.current.id,allFormData:{...e.values,[s]:d}});u.current(s,"validating");try{let a=await core.validateWithUnifiedConfig(c.validation,d,p),h=l.current.isFieldRequired(s),v=d==null||d==="";if(h&&v&&!a.errors.some(C=>C.code==="REQUIRED"||C.message.toLowerCase().includes("required"))){let C={isValid:!1,errors:[{message:"This field is required",code:"CONDITIONAL_REQUIRED"},...a.errors]};return F.current(s,C.errors),u.current(s,"invalid"),C}return F.current(s,a.errors),u.current(s,a.isValid?"valid":"invalid"),a}catch(a){let h={isValid:false,errors:[{message:a instanceof Error?a.message:"Validation failed",code:"VALIDATION_ERROR"}]};return F.current(s,h.errors),u.current(s,"invalid"),h}},[e.values]),f=xe.useCallback(async()=>{let s=n.current.allFields.filter(a=>{let h=l.current.isFieldVisible(a.id),v=a.validation&&core.hasUnifiedValidation(a.validation);return h&&v}),m=n.current.allFields.filter(a=>!l.current.isFieldVisible(a.id));for(let a of m)F.current(a.id,[]),u.current(a.id,"valid");let c=await Promise.all(s.map(a=>g(a.id))),d=c.some(a=>!a.isValid),p=B();if(n.current.validation&&core.hasUnifiedValidation(n.current.validation)){let a=Object.keys(e.values).reduce((v,R)=>(l.current.isFieldVisible(R)&&(v[R]=e.values[R]),v),{}),h=core.createValidationContext({formId:n.current.id,allFormData:a});try{p=await core.validateFormWithUnifiedConfig(n.current.validation,a,h);}catch(v){p={isValid:false,errors:[{message:v instanceof Error?v.message:"Form validation failed",code:"FORM_VALIDATION_ERROR"}]};}}return {isValid:!d&&p.isValid,errors:[...c.flatMap(a=>a.errors),...p.errors]}},[e.values,g]);return {validateField:g,validateForm:f}}function Re({formConfig:o,enabled:e=true}){let r=core.getGlobalMonitor(),t=xe.useRef(null),i=xe.useRef(0),n=xe.useRef(0);xe.useEffect(()=>{r&&e&&(t.current=r.getProfiler());},[r,e]);let l=xe.useCallback(m=>{if(!r||!e)return;i.current++;let c={formId:o.id,fieldCount:o.allFields.length,timestamp:Date.now(),duration:0,renderDuration:0,validationDuration:0,validationErrors:0,renderCount:m||i.current};r.track("component_render",`form_${o.id}`,{formId:o.id,fieldCount:o.allFields.length,renderCount:i.current},c,"low");},[r,e,o.id,o.allFields.length]),u=xe.useCallback((m,c)=>{if(!r||!e)return;let d=t.current?.getMetrics(`form_validation_${o.id}`),p={formId:o.id,fieldCount:c||o.allFields.length,timestamp:Date.now(),duration:d?.duration||0,renderDuration:0,validationDuration:d?.duration||0,validationErrors:m,renderCount:i.current};r.track("form_validation",`form_${o.id}`,{formId:o.id,validationErrors:m,fieldCount:c||o.allFields.length},p,m>0?"medium":"low");},[r,e,o.id,o.allFields.length]),F=xe.useCallback((m,c)=>{if(!r||!e)return;let d=t.current?.getMetrics(`form_submission_${o.id}`),p={formId:o.id,fieldCount:c||o.allFields.length,timestamp:Date.now(),duration:d?.duration||0,renderDuration:0,validationDuration:0,validationErrors:m?0:1,renderCount:i.current};r.track("form_submission",`form_${o.id}`,{formId:o.id,success:m,fieldCount:c||o.allFields.length,fieldChanges:n.current},p,m?"low":"high");},[r,e,o.id,o.allFields.length]),g=xe.useCallback((m,c)=>{!r||!e||(n.current++,r.track("component_update",`field_${m}`,{formId:o.id,fieldId:m,componentType:c,changeCount:n.current},void 0,"low"));},[r,e,o.id]),f=xe.useCallback(m=>{!t.current||!e||t.current.start(m,{formId:o.id,renderCount:i.current});},[e,o.id]),s=xe.useCallback(m=>{if(!t.current||!e)return null;let c=t.current.end(m);return c?{...c,formId:o.id,fieldCount:o.allFields.length,renderDuration:c.duration,validationDuration:0,validationErrors:0}:null},[e,o.id,o.allFields.length]);return {trackFormRender:l,trackFormValidation:u,trackFormSubmission:F,trackFieldChange:g,startPerformanceTracking:f,endPerformanceTracking:s}}var Y=xe.createContext(null);function $({children:o,formConfig:e,defaultValues:r={},onSubmit:t,onFieldChange:i,className:n}){let l=xe.useRef(e.id),{formState:u,setValue:F,setFieldTouched:g,reset:f,setError:s,clearError:m,setFieldValidationState:c,setSubmitting:d,isFormValid:p}=J({defaultValues:r,onFieldChange:i}),{fieldConditions:a,hasConditionalFields:h,getFieldCondition:v,isFieldVisible:R,isFieldDisabled:C,isFieldRequired:V,isFieldReadonly:x}=W({formConfig:e,formValues:u.values}),P=xe.useMemo(()=>({hasConditionalFields:h,getFieldCondition:v,isFieldVisible:R,isFieldDisabled:C,isFieldRequired:V,isFieldReadonly:x}),[h,v,R,C,V,x]),{validateField:D,validateForm:b}=K({formConfig:e,formState:u,conditionsHelpers:P,setFieldValidationState:c,setError:s}),{submit:I}=Q({formState:u,onSubmit:t,validateForm:b,setSubmitting:d});xe.useEffect(()=>{(l.current===null||e.id!==l.current)&&(l.current=e.id,f(r));},[e.id,f]);let N=xe.useMemo(()=>e,[e]),se=xe.useMemo(()=>({formState:u,formConfig:N,fieldConditions:a,conditionsHelpers:P,setValue:F,setFieldTouched:g,validateField:D,validateForm:b,isFormValid:p,reset:f,submit:I,setError:s,clearError:m}),[u,N,a,P,F,g,D,b,p,f,I,s,m]);return jsxRuntime.jsx(Y.Provider,{value:se,children:jsxRuntime.jsx("form",{onSubmit:I,className:n,noValidate:true,children:o})})}function y(){let o=xe.useContext(Y);if(!o)throw new Error("useFormContext must be used within a FormProvider");return o}function Se({formConfig:o,defaultValues:e,onSubmit:r,onFieldChange:t,children:i}){let n=xe.useMemo(()=>o instanceof E?o.build():o,[o]);return jsxRuntime.jsx($,{formConfig:n,defaultValues:e,onSubmit:r,onFieldChange:t,children:i})}var L=xe__default.default.memo(function({fieldId:e,disabled:r=false,customProps:t={},className:i,forceVisible:n=false}){let{formState:l,formConfig:u,setValue:F,setFieldTouched:g,validateField:f,conditionsHelpers:s}=y(),m=u.allFields.find(b=>b.id===e);if(!m)throw new Error(`Field with ID "${e}" not found`);let c=u.config.getComponent(m.componentId);if(!c)throw new Error(`Component with ID "${m.componentId}" not found`);let d=xe.useMemo(()=>({value:l.values[e],errors:l.errors[e]||[],validationState:l.validationState[e]||"idle",isTouched:l.touched[e]||false}),[l.values[e],l.errors[e],l.validationState[e],l.touched[e]]),p=d.validationState==="validating",a=xe.useMemo(()=>({isVisible:n||s.isFieldVisible(e),isFieldDisabled:r||s.isFieldDisabled(e),isFieldRequired:s.isFieldRequired(e),isFieldReadonly:s.isFieldReadonly(e)}),[n,e,r,s,l.values]);if(!a.isVisible)return null;let h=xe.useCallback(async b=>{F(e,b),(m.validation?.validateOnChange||d.isTouched)&&await f(e,b);},[e,F,f,m.validation?.validateOnChange,d.isTouched]),v=xe.useCallback(async()=>{d.isTouched||g(e),m.validation?.validateOnBlur!==false&&await f(e);},[e,d.isTouched,g,f,m.validation?.validateOnBlur]),R=xe.useMemo(()=>({...c.defaultProps??{},...m.props,...t,disabled:a.isFieldDisabled,required:a.isFieldRequired,readOnly:a.isFieldReadonly}),[c.defaultProps,m.props,t,a.isFieldDisabled,a.isFieldRequired,a.isFieldReadonly]),C=xe.useMemo(()=>({id:e,props:R,value:d.value,onChange:h,onBlur:v,disabled:a.isFieldDisabled,error:d.errors,isValidating:p,touched:d.isTouched}),[e,R,d.value,h,v,a.isFieldDisabled,d.errors,p,d.isTouched]),V=c.renderer(C),x=u.renderConfig?.fieldRenderer,P=c.useFieldRenderer!==false,D=x&&P?x({children:V,id:e,...R,error:d.errors,isValidating:p,touched:d.isTouched}):V;return jsxRuntime.jsx("div",{className:i,"data-field-id":e,"data-field-type":c.type,"data-field-visible":a.isVisible,"data-field-disabled":a.isFieldDisabled,"data-field-required":a.isFieldRequired,"data-field-readonly":a.isFieldReadonly,children:D})});var ie=xe__default.default.memo(function({row:e,className:r,...t}){let{formConfig:i}=y(),n=xe.useMemo(()=>e.fields.map(u=>jsxRuntime.jsx(L,{fieldId:u.id},u.id)),[e.fields]),l=xe.useMemo(()=>({row:e,children:n,className:r}),[e,n,r]);return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"FormRow",renderer:i.renderConfig?.rowRenderer,props:l,...t,children:n})}),oe=ie;var Be=xe__default.default.memo(function({className:e,...r}){let{formConfig:t}=y(),i=xe.useMemo(()=>t.rows.map(l=>jsxRuntime.jsx(oe,{row:l},l.id)),[t.rows]),n=xe.useMemo(()=>({formConfig:t,children:i,className:e}),[t,i,e]);return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"FormBody",renderer:t.renderConfig?.bodyRenderer,props:n,...r,children:i})});var Ue=xe__default.default.memo(function({className:e,isSubmitting:r,...t}){let{formState:i,submit:n,formConfig:l}=y(),u=xe.useMemo(()=>({isSubmitting:r??i.isSubmitting,onSubmit:n,className:e}),[r,i.isSubmitting,n,e]);return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"FormSubmitButton",renderer:l.renderConfig?.submitButtonRenderer,props:u,...t})});exports.Form=Se;exports.FormBody=Be;exports.FormBuilder=E;exports.FormField=L;exports.FormProvider=$;exports.FormRow=ie;exports.FormSubmitButton=Ue;exports.form=E;exports.useConditionEvaluation=Ge;exports.useFormConditions=W;exports.useFormContext=y;exports.useFormMonitoring=Re;exports.useFormState=J;exports.useFormSubmission=Q;exports.useFormValidation=K;exports.useMultipleConditionEvaluation=H;
1
+ 'use strict';var xe=require('react'),core=require('@rilaykit/core'),jsxRuntime=require('react/jsx-runtime');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var xe__default=/*#__PURE__*/_interopDefault(xe);var E=class o{constructor(e,r){this.rows=[];this.idGenerator=new core.IdGenerator;this.config=e,this.formId=r||`form-${Math.random().toString(36).substring(2,15)}`;}static create(e,r){return new o(e,r)}createFormField(e){let r=this.config.getComponent(e.type);if(!r)throw new Error(`No component found with type "${e.type}"`);let t;return (r.validation||e.validation)&&(t={validateOnChange:e.validation?.validateOnChange??r.validation?.validateOnChange,validateOnBlur:e.validation?.validateOnBlur??r.validation?.validateOnBlur,debounceMs:e.validation?.debounceMs??r.validation?.debounceMs,validate:(()=>{let i=r.validation?.validate,n=e.validation?.validate;if(!i)return n;if(!n)return i;let l=Array.isArray(i)?i:[i],u=Array.isArray(n)?n:[n];return [...l,...u]})()}),{id:e.id||this.idGenerator.next("field"),componentId:r.id,props:{...r.defaultProps,...e.props},validation:t,conditions:e.conditions}}createRow(e){if(e.length===0)throw new Error("At least one field is required");if(e.length>3)throw new Error("Maximum 3 fields per row");let r=e.map(t=>this.createFormField(t));return {id:this.idGenerator.next("row"),fields:r,maxColumns:e.length}}add(...e){let r,t=false;if(e.length===1&&Array.isArray(e[0])?(r=e[0],t=true):r=e,r.length===0)throw new Error("At least one field is required");if(t&&r.length>3)throw new Error("Maximum 3 fields per row");if(r.length===1){let i=this.createRow(r);return this.rows.push(i),this}if(r.length<=3){let i=this.createRow(r);return this.rows.push(i),this}for(let i of r){let n=this.createRow([i]);this.rows.push(n);}return this}addSeparateRows(e){for(let r of e)this.add(r);return this}setId(e){return this.formId=e,this}updateField(e,r){let t=this.findField(e);if(!t)throw new Error(`Field with ID "${e}" not found`);return Object.assign(t,{...r,props:{...t.props,...r.props}}),this}findField(e){for(let r of this.rows){let t=r.fields.find(i=>i.id===e);if(t)return t}return null}removeField(e){return this.rows=this.rows.map(r=>({...r,fields:r.fields.filter(t=>t.id!==e)})).filter(r=>r.fields.length>0),this}getField(e){return this.findField(e)||void 0}getFields(){return this.rows.flatMap(e=>e.fields)}getRows(){return [...this.rows]}clear(){return this.rows=[],this.idGenerator.reset(),this}setValidation(e){return this.formValidation=e,this}addFieldValidation(e,r){console.warn("addFieldValidation is deprecated. Use updateField with validation.validate property instead.");let t=this.findField(e);if(!t)throw new Error(`Field with ID "${e}" not found`);let i={...t.validation,...r};return this.updateField(e,{validation:i})}addFieldConditions(e,r){let t=this.findField(e);if(!t)throw new Error(`Field with ID "${e}" not found`);let i={...t.conditions,...r};return this.updateField(e,{conditions:i})}clone(e){let r=new o(this.config,e||`${this.formId}-clone`);return r.rows=core.deepClone(this.rows),r}validate(){let e=[],r=this.getFields(),t=r.map(i=>i.id);try{core.ensureUnique(t,"field");}catch(i){e.push(i instanceof Error?i.message:String(i));}for(let i of r)this.config.hasComponent(i.componentId)||e.push(`Component "${i.componentId}" not found for field "${i.id}"`);for(let i of this.rows)i.fields.length>3&&e.push(`Row "${i.id}" has ${i.fields.length} fields, maximum is 3`),i.fields.length===0&&e.push(`Row "${i.id}" is empty`);return e}build(){let e=this.validate();if(e.length>0)throw new Error(`Form validation failed: ${e.join(", ")}`);return {id:this.formId,rows:[...this.rows],allFields:this.getFields(),config:this.config,renderConfig:this.config.getFormRenderConfig(),validation:this.formValidation}}toJSON(){return {id:this.formId,rows:this.rows}}fromJSON(e){return e.id&&(this.formId=e.id),e.rows&&(this.rows=e.rows),this}getStats(){let e=this.getFields(),r=this.rows.map(t=>t.fields.length);return {totalFields:e.length,totalRows:this.rows.length,averageFieldsPerRow:this.rows.length>0?e.length/this.rows.length:0,maxFieldsInRow:r.length>0?Math.max(...r):0,minFieldsInRow:r.length>0?Math.min(...r):0}}};function Ge(o,e={},r={}){return xe.useMemo(()=>{if(!o)return {visible:r.visible??true,disabled:r.disabled??false,required:r.required??false,readonly:r.readonly??false};let t=i=>{try{return i&&typeof i=="object"&&"build"in i?core.evaluateCondition(i.build(),e):core.evaluateCondition(i,e)}catch(n){return console.warn("Error evaluating condition:",n),false}};return {visible:o.visible?t(o.visible):r.visible??true,disabled:o.disabled?t(o.disabled):r.disabled??false,required:o.required?t(o.required):r.required??false,readonly:o.readonly?t(o.readonly):r.readonly??false}},[o,e,r])}function H(o,e={}){return xe.useMemo(()=>{let r={};for(let[t,i]of Object.entries(o))if(r[t]={visible:true,disabled:false,required:false,readonly:false},i){let n=l=>{try{return l&&typeof l=="object"&&"build"in l?core.evaluateCondition(l.build(),e):core.evaluateCondition(l,e)}catch(u){return console.warn(`Error evaluating condition for field ${t}:`,u),false}};r[t]={visible:i.visible?n(i.visible):true,disabled:i.disabled?n(i.disabled):false,required:i.required?n(i.required):false,readonly:i.readonly?n(i.readonly):false};}return r},[o,e])}function W({formConfig:o,formValues:e}){let r=xe.useMemo(()=>{let f={};for(let s of o.allFields)s.conditions&&(f[s.id]=s.conditions);return f},[o.allFields]),t=xe.useMemo(()=>Object.keys(r).length>0,[r]),i=H(t?r:{},t?e:{}),n=xe.useCallback(f=>i[f],[i]),l=xe.useCallback(f=>{let s=i[f];return s?s.visible:true},[i]),u=xe.useCallback(f=>{let s=i[f];return s?s.disabled:false},[i]),F=xe.useCallback(f=>{let s=i[f];return s?s.required:false},[i]),g=xe.useCallback(f=>{let s=i[f];return s?s.readonly:false},[i]);return xe.useMemo(()=>({fieldConditions:i,hasConditionalFields:t,getFieldCondition:n,isFieldVisible:l,isFieldDisabled:u,isFieldRequired:F,isFieldReadonly:g}),[i,t,n,l,u,F,g])}function ce(o,e){switch(e.type){case "SET_VALUE":return {...o,values:{...o.values,[e.fieldId]:e.value},isDirty:true};case "SET_FIELD_ERRORS":return {...o,errors:{...o.errors,[e.fieldId]:e.errors}};case "SET_FIELD_VALIDATION_STATE":return {...o,validationState:{...o.validationState,[e.fieldId]:e.state}};case "SET_FIELD_TOUCHED":return {...o,touched:{...o.touched,[e.fieldId]:true}};case "SET_SUBMITTING":return {...o,isSubmitting:e.isSubmitting};case "RESET":return {values:e.values||{},errors:{},validationState:{},touched:{},isDirty:false,isSubmitting:false};default:return o}}function J({defaultValues:o={},onFieldChange:e}){let r={values:o,errors:{},validationState:{},touched:{},isDirty:false,isSubmitting:false},[t,i]=xe.useReducer(ce,r),n=xe.useRef(e);n.current=e;let l=xe.useCallback((d,p)=>{i({type:"SET_VALUE",fieldId:d,value:p}),n.current?.(d,p,{...t.values,[d]:p});},[t.values]),u=xe.useCallback(d=>{i({type:"SET_FIELD_TOUCHED",fieldId:d});},[]),F=xe.useCallback((d,p)=>{i({type:"SET_FIELD_ERRORS",fieldId:d,errors:p});},[]),g=xe.useCallback(d=>{i({type:"SET_FIELD_ERRORS",fieldId:d,errors:[]});},[]),f=xe.useCallback((d,p)=>{i({type:"SET_FIELD_VALIDATION_STATE",fieldId:d,state:p});},[]),s=xe.useCallback(d=>{i({type:"SET_SUBMITTING",isSubmitting:d});},[]),m=xe.useCallback(d=>{i({type:"RESET",values:d});},[]),c=xe.useCallback(()=>{let d=Object.values(t.errors).some(a=>a.length>0),p=Object.values(t.validationState).some(a=>a==="invalid");return !d&&!p},[t.errors,t.validationState]);return {formState:t,setValue:l,setFieldTouched:u,setError:F,clearError:g,setFieldValidationState:f,setSubmitting:s,reset:m,isFormValid:c}}function Q({formState:o,onSubmit:e,validateForm:r,setSubmitting:t}){let i=xe.useRef(e);return i.current=e,{submit:xe.useCallback(async l=>{l?.preventDefault();try{return t(!0),(await r()).isValid?(i.current&&await i.current(o.values),!0):!1}catch(u){return console.error("Error during form submission:",u),false}finally{t(false);}},[o.values,r,t])}}function B(){return {isValid:true,errors:[]}}function K({formConfig:o,formState:e,conditionsHelpers:r,setFieldValidationState:t,setError:i}){let n=xe.useRef(o),l=xe.useRef(r),u=xe.useRef(t),F=xe.useRef(i);n.current=o,l.current=r,u.current=t,F.current=i;let g=xe.useCallback(async(s,m)=>{let c=n.current.allFields.find(a=>a.id===s);if(!c)return B();if(!l.current.isFieldVisible(s))return F.current(s,[]),u.current(s,"valid"),B();if(!c.validation||!core.hasUnifiedValidation(c.validation))return F.current(s,[]),u.current(s,"valid"),B();let d=m!==void 0?m:e.values[s],p=core.createValidationContext({fieldId:s,formId:n.current.id,allFormData:{...e.values,[s]:d}});u.current(s,"validating");try{let a=await core.validateWithUnifiedConfig(c.validation,d,p),h=l.current.isFieldRequired(s),v=d==null||d==="";if(h&&v&&!a.errors.some(C=>C.code==="REQUIRED"||C.message.toLowerCase().includes("required"))){let C={isValid:!1,errors:[{message:"This field is required",code:"CONDITIONAL_REQUIRED"},...a.errors]};return F.current(s,C.errors),u.current(s,"invalid"),C}return F.current(s,a.errors),u.current(s,a.isValid?"valid":"invalid"),a}catch(a){let h={isValid:false,errors:[{message:a instanceof Error?a.message:"Validation failed",code:"VALIDATION_ERROR"}]};return F.current(s,h.errors),u.current(s,"invalid"),h}},[e.values]),f=xe.useCallback(async()=>{let s=n.current.allFields.filter(a=>{let h=l.current.isFieldVisible(a.id),v=a.validation&&core.hasUnifiedValidation(a.validation);return h&&v}),m=n.current.allFields.filter(a=>!l.current.isFieldVisible(a.id));for(let a of m)F.current(a.id,[]),u.current(a.id,"valid");let c=await Promise.all(s.map(a=>g(a.id))),d=c.some(a=>!a.isValid),p=B();if(n.current.validation&&core.hasUnifiedValidation(n.current.validation)){let a=Object.keys(e.values).reduce((v,R)=>(l.current.isFieldVisible(R)&&(v[R]=e.values[R]),v),{}),h=core.createValidationContext({formId:n.current.id,allFormData:a});try{p=await core.validateFormWithUnifiedConfig(n.current.validation,a,h);}catch(v){p={isValid:false,errors:[{message:v instanceof Error?v.message:"Form validation failed",code:"FORM_VALIDATION_ERROR"}]};}}return {isValid:!d&&p.isValid,errors:[...c.flatMap(a=>a.errors),...p.errors]}},[e.values,g]);return {validateField:g,validateForm:f}}function Re({formConfig:o,enabled:e=true}){let r=core.getGlobalMonitor(),t=xe.useRef(null),i=xe.useRef(0),n=xe.useRef(0);xe.useEffect(()=>{r&&e&&(t.current=r.getProfiler());},[r,e]);let l=xe.useCallback(m=>{if(!r||!e)return;i.current++;let c={formId:o.id,fieldCount:o.allFields.length,timestamp:Date.now(),duration:0,renderDuration:0,validationDuration:0,validationErrors:0,renderCount:m||i.current};r.track("component_render",`form_${o.id}`,{formId:o.id,fieldCount:o.allFields.length,renderCount:i.current},c,"low");},[r,e,o.id,o.allFields.length]),u=xe.useCallback((m,c)=>{if(!r||!e)return;let d=t.current?.getMetrics(`form_validation_${o.id}`),p={formId:o.id,fieldCount:c||o.allFields.length,timestamp:Date.now(),duration:d?.duration||0,renderDuration:0,validationDuration:d?.duration||0,validationErrors:m,renderCount:i.current};r.track("form_validation",`form_${o.id}`,{formId:o.id,validationErrors:m,fieldCount:c||o.allFields.length},p,m>0?"medium":"low");},[r,e,o.id,o.allFields.length]),F=xe.useCallback((m,c)=>{if(!r||!e)return;let d=t.current?.getMetrics(`form_submission_${o.id}`),p={formId:o.id,fieldCount:c||o.allFields.length,timestamp:Date.now(),duration:d?.duration||0,renderDuration:0,validationDuration:0,validationErrors:m?0:1,renderCount:i.current};r.track("form_submission",`form_${o.id}`,{formId:o.id,success:m,fieldCount:c||o.allFields.length,fieldChanges:n.current},p,m?"low":"high");},[r,e,o.id,o.allFields.length]),g=xe.useCallback((m,c)=>{!r||!e||(n.current++,r.track("component_update",`field_${m}`,{formId:o.id,fieldId:m,componentType:c,changeCount:n.current},void 0,"low"));},[r,e,o.id]),f=xe.useCallback(m=>{!t.current||!e||t.current.start(m,{formId:o.id,renderCount:i.current});},[e,o.id]),s=xe.useCallback(m=>{if(!t.current||!e)return null;let c=t.current.end(m);return c?{...c,formId:o.id,fieldCount:o.allFields.length,renderDuration:c.duration,validationDuration:0,validationErrors:0}:null},[e,o.id,o.allFields.length]);return {trackFormRender:l,trackFormValidation:u,trackFormSubmission:F,trackFieldChange:g,startPerformanceTracking:f,endPerformanceTracking:s}}var Y=xe.createContext(null);function $({children:o,formConfig:e,defaultValues:r={},onSubmit:t,onFieldChange:i,className:n}){let l=xe.useRef(e.id),{formState:u,setValue:F,setFieldTouched:g,reset:f,setError:s,clearError:m,setFieldValidationState:c,setSubmitting:d,isFormValid:p}=J({defaultValues:r,onFieldChange:i}),{fieldConditions:a,hasConditionalFields:h,getFieldCondition:v,isFieldVisible:R,isFieldDisabled:C,isFieldRequired:V,isFieldReadonly:x}=W({formConfig:e,formValues:u.values}),P=xe.useMemo(()=>({hasConditionalFields:h,getFieldCondition:v,isFieldVisible:R,isFieldDisabled:C,isFieldRequired:V,isFieldReadonly:x}),[h,v,R,C,V,x]),{validateField:D,validateForm:b}=K({formConfig:e,formState:u,conditionsHelpers:P,setFieldValidationState:c,setError:s}),{submit:I}=Q({formState:u,onSubmit:t,validateForm:b,setSubmitting:d});xe.useEffect(()=>{(l.current===null||e.id!==l.current)&&(l.current=e.id,f(r));},[e.id,f]);let N=xe.useMemo(()=>e,[e]),se=xe.useMemo(()=>({formState:u,formConfig:N,fieldConditions:a,conditionsHelpers:P,setValue:F,setFieldTouched:g,validateField:D,validateForm:b,isFormValid:p,reset:f,submit:I,setError:s,clearError:m}),[u,N,a,P,F,g,D,b,p,f,I,s,m]);return jsxRuntime.jsx(Y.Provider,{value:se,children:jsxRuntime.jsx("form",{onSubmit:I,className:n,noValidate:true,children:o})})}function y(){let o=xe.useContext(Y);if(!o)throw new Error("useFormContext must be used within a FormProvider");return o}function Se({formConfig:o,defaultValues:e,onSubmit:r,onFieldChange:t,children:i}){let n=xe.useMemo(()=>o instanceof E?o.build():o,[o]);return jsxRuntime.jsx($,{formConfig:n,defaultValues:e,onSubmit:r,onFieldChange:t,children:i})}var L=xe__default.default.memo(function({fieldId:e,disabled:r=false,customProps:t={},className:i,forceVisible:n=false}){let{formState:l,formConfig:u,setValue:F,setFieldTouched:g,validateField:f,conditionsHelpers:s}=y(),m=u.allFields.find(b=>b.id===e);if(!m)throw new Error(`Field with ID "${e}" not found`);let c=u.config.getComponent(m.componentId);if(!c)throw new Error(`Component with ID "${m.componentId}" not found`);let d=xe.useMemo(()=>({value:l.values[e],errors:l.errors[e]||[],validationState:l.validationState[e]||"idle",isTouched:l.touched[e]||false}),[l.values[e],l.errors[e],l.validationState[e],l.touched[e]]),p=d.validationState==="validating",a=xe.useMemo(()=>({isVisible:n||s.isFieldVisible(e),isFieldDisabled:r||s.isFieldDisabled(e),isFieldRequired:s.isFieldRequired(e),isFieldReadonly:s.isFieldReadonly(e)}),[n,e,r,s,l.values]),h=xe.useCallback(async b=>{F(e,b),(m.validation?.validateOnChange||d.isTouched)&&await f(e,b);},[e,F,f,m.validation?.validateOnChange,d.isTouched]),v=xe.useCallback(async()=>{d.isTouched||g(e),m.validation?.validateOnBlur!==false&&await f(e);},[e,d.isTouched,g,f,m.validation?.validateOnBlur]),R=xe.useMemo(()=>({...c.defaultProps??{},...m.props,...t,disabled:a.isFieldDisabled,required:a.isFieldRequired,readOnly:a.isFieldReadonly}),[c.defaultProps,m.props,t,a.isFieldDisabled,a.isFieldRequired,a.isFieldReadonly]),C=xe.useMemo(()=>({id:e,props:R,value:d.value,onChange:h,onBlur:v,disabled:a.isFieldDisabled,error:d.errors,isValidating:p,touched:d.isTouched}),[e,R,d.value,h,v,a.isFieldDisabled,d.errors,p,d.isTouched]);if(!a.isVisible)return null;let V=c.renderer(C),x=u.renderConfig?.fieldRenderer,P=c.useFieldRenderer!==false,D=x&&P?x({children:V,id:e,...R,error:d.errors,isValidating:p,touched:d.isTouched}):V;return jsxRuntime.jsx("div",{className:i,"data-field-id":e,"data-field-type":c.type,"data-field-visible":a.isVisible,"data-field-disabled":a.isFieldDisabled,"data-field-required":a.isFieldRequired,"data-field-readonly":a.isFieldReadonly,children:D})});var ie=xe__default.default.memo(function({row:e,className:r,...t}){let{formConfig:i}=y(),n=xe.useMemo(()=>e.fields.map(u=>jsxRuntime.jsx(L,{fieldId:u.id},u.id)),[e.fields]),l=xe.useMemo(()=>({row:e,children:n,className:r}),[e,n,r]);return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"FormRow",renderer:i.renderConfig?.rowRenderer,props:l,...t,children:n})}),oe=ie;var Be=xe__default.default.memo(function({className:e,...r}){let{formConfig:t}=y(),i=xe.useMemo(()=>t.rows.map(l=>jsxRuntime.jsx(oe,{row:l},l.id)),[t.rows]),n=xe.useMemo(()=>({formConfig:t,children:i,className:e}),[t,i,e]);return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"FormBody",renderer:t.renderConfig?.bodyRenderer,props:n,...r,children:i})});var Ue=xe__default.default.memo(function({className:e,isSubmitting:r,...t}){let{formState:i,submit:n,formConfig:l}=y(),u=xe.useMemo(()=>({isSubmitting:r??i.isSubmitting,onSubmit:n,className:e}),[r,i.isSubmitting,n,e]);return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"FormSubmitButton",renderer:l.renderConfig?.submitButtonRenderer,props:u,...t})});exports.Form=Se;exports.FormBody=Be;exports.FormBuilder=E;exports.FormField=L;exports.FormProvider=$;exports.FormRow=ie;exports.FormSubmitButton=Ue;exports.form=E;exports.useConditionEvaluation=Ge;exports.useFormConditions=W;exports.useFormContext=y;exports.useFormMonitoring=Re;exports.useFormState=J;exports.useFormSubmission=Q;exports.useFormValidation=K;exports.useMultipleConditionEvaluation=H;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import xe,{createContext,useMemo,useCallback,useContext,useReducer,useRef,useEffect}from'react';import {ComponentRendererWrapper,IdGenerator,deepClone,ensureUnique,hasUnifiedValidation,createValidationContext,validateWithUnifiedConfig,validateFormWithUnifiedConfig,getGlobalMonitor,evaluateCondition}from'@rilaykit/core';import {jsx}from'react/jsx-runtime';var E=class o{constructor(e,r){this.rows=[];this.idGenerator=new IdGenerator;this.config=e,this.formId=r||`form-${Math.random().toString(36).substring(2,15)}`;}static create(e,r){return new o(e,r)}createFormField(e){let r=this.config.getComponent(e.type);if(!r)throw new Error(`No component found with type "${e.type}"`);let t;return (r.validation||e.validation)&&(t={validateOnChange:e.validation?.validateOnChange??r.validation?.validateOnChange,validateOnBlur:e.validation?.validateOnBlur??r.validation?.validateOnBlur,debounceMs:e.validation?.debounceMs??r.validation?.debounceMs,validate:(()=>{let i=r.validation?.validate,n=e.validation?.validate;if(!i)return n;if(!n)return i;let l=Array.isArray(i)?i:[i],u=Array.isArray(n)?n:[n];return [...l,...u]})()}),{id:e.id||this.idGenerator.next("field"),componentId:r.id,props:{...r.defaultProps,...e.props},validation:t,conditions:e.conditions}}createRow(e){if(e.length===0)throw new Error("At least one field is required");if(e.length>3)throw new Error("Maximum 3 fields per row");let r=e.map(t=>this.createFormField(t));return {id:this.idGenerator.next("row"),fields:r,maxColumns:e.length}}add(...e){let r,t=false;if(e.length===1&&Array.isArray(e[0])?(r=e[0],t=true):r=e,r.length===0)throw new Error("At least one field is required");if(t&&r.length>3)throw new Error("Maximum 3 fields per row");if(r.length===1){let i=this.createRow(r);return this.rows.push(i),this}if(r.length<=3){let i=this.createRow(r);return this.rows.push(i),this}for(let i of r){let n=this.createRow([i]);this.rows.push(n);}return this}addSeparateRows(e){for(let r of e)this.add(r);return this}setId(e){return this.formId=e,this}updateField(e,r){let t=this.findField(e);if(!t)throw new Error(`Field with ID "${e}" not found`);return Object.assign(t,{...r,props:{...t.props,...r.props}}),this}findField(e){for(let r of this.rows){let t=r.fields.find(i=>i.id===e);if(t)return t}return null}removeField(e){return this.rows=this.rows.map(r=>({...r,fields:r.fields.filter(t=>t.id!==e)})).filter(r=>r.fields.length>0),this}getField(e){return this.findField(e)||void 0}getFields(){return this.rows.flatMap(e=>e.fields)}getRows(){return [...this.rows]}clear(){return this.rows=[],this.idGenerator.reset(),this}setValidation(e){return this.formValidation=e,this}addFieldValidation(e,r){console.warn("addFieldValidation is deprecated. Use updateField with validation.validate property instead.");let t=this.findField(e);if(!t)throw new Error(`Field with ID "${e}" not found`);let i={...t.validation,...r};return this.updateField(e,{validation:i})}addFieldConditions(e,r){let t=this.findField(e);if(!t)throw new Error(`Field with ID "${e}" not found`);let i={...t.conditions,...r};return this.updateField(e,{conditions:i})}clone(e){let r=new o(this.config,e||`${this.formId}-clone`);return r.rows=deepClone(this.rows),r}validate(){let e=[],r=this.getFields(),t=r.map(i=>i.id);try{ensureUnique(t,"field");}catch(i){e.push(i instanceof Error?i.message:String(i));}for(let i of r)this.config.hasComponent(i.componentId)||e.push(`Component "${i.componentId}" not found for field "${i.id}"`);for(let i of this.rows)i.fields.length>3&&e.push(`Row "${i.id}" has ${i.fields.length} fields, maximum is 3`),i.fields.length===0&&e.push(`Row "${i.id}" is empty`);return e}build(){let e=this.validate();if(e.length>0)throw new Error(`Form validation failed: ${e.join(", ")}`);return {id:this.formId,rows:[...this.rows],allFields:this.getFields(),config:this.config,renderConfig:this.config.getFormRenderConfig(),validation:this.formValidation}}toJSON(){return {id:this.formId,rows:this.rows}}fromJSON(e){return e.id&&(this.formId=e.id),e.rows&&(this.rows=e.rows),this}getStats(){let e=this.getFields(),r=this.rows.map(t=>t.fields.length);return {totalFields:e.length,totalRows:this.rows.length,averageFieldsPerRow:this.rows.length>0?e.length/this.rows.length:0,maxFieldsInRow:r.length>0?Math.max(...r):0,minFieldsInRow:r.length>0?Math.min(...r):0}}};function Ge(o,e={},r={}){return useMemo(()=>{if(!o)return {visible:r.visible??true,disabled:r.disabled??false,required:r.required??false,readonly:r.readonly??false};let t=i=>{try{return i&&typeof i=="object"&&"build"in i?evaluateCondition(i.build(),e):evaluateCondition(i,e)}catch(n){return console.warn("Error evaluating condition:",n),false}};return {visible:o.visible?t(o.visible):r.visible??true,disabled:o.disabled?t(o.disabled):r.disabled??false,required:o.required?t(o.required):r.required??false,readonly:o.readonly?t(o.readonly):r.readonly??false}},[o,e,r])}function H(o,e={}){return useMemo(()=>{let r={};for(let[t,i]of Object.entries(o))if(r[t]={visible:true,disabled:false,required:false,readonly:false},i){let n=l=>{try{return l&&typeof l=="object"&&"build"in l?evaluateCondition(l.build(),e):evaluateCondition(l,e)}catch(u){return console.warn(`Error evaluating condition for field ${t}:`,u),false}};r[t]={visible:i.visible?n(i.visible):true,disabled:i.disabled?n(i.disabled):false,required:i.required?n(i.required):false,readonly:i.readonly?n(i.readonly):false};}return r},[o,e])}function W({formConfig:o,formValues:e}){let r=useMemo(()=>{let f={};for(let s of o.allFields)s.conditions&&(f[s.id]=s.conditions);return f},[o.allFields]),t=useMemo(()=>Object.keys(r).length>0,[r]),i=H(t?r:{},t?e:{}),n=useCallback(f=>i[f],[i]),l=useCallback(f=>{let s=i[f];return s?s.visible:true},[i]),u=useCallback(f=>{let s=i[f];return s?s.disabled:false},[i]),F=useCallback(f=>{let s=i[f];return s?s.required:false},[i]),g=useCallback(f=>{let s=i[f];return s?s.readonly:false},[i]);return useMemo(()=>({fieldConditions:i,hasConditionalFields:t,getFieldCondition:n,isFieldVisible:l,isFieldDisabled:u,isFieldRequired:F,isFieldReadonly:g}),[i,t,n,l,u,F,g])}function ce(o,e){switch(e.type){case "SET_VALUE":return {...o,values:{...o.values,[e.fieldId]:e.value},isDirty:true};case "SET_FIELD_ERRORS":return {...o,errors:{...o.errors,[e.fieldId]:e.errors}};case "SET_FIELD_VALIDATION_STATE":return {...o,validationState:{...o.validationState,[e.fieldId]:e.state}};case "SET_FIELD_TOUCHED":return {...o,touched:{...o.touched,[e.fieldId]:true}};case "SET_SUBMITTING":return {...o,isSubmitting:e.isSubmitting};case "RESET":return {values:e.values||{},errors:{},validationState:{},touched:{},isDirty:false,isSubmitting:false};default:return o}}function J({defaultValues:o={},onFieldChange:e}){let r={values:o,errors:{},validationState:{},touched:{},isDirty:false,isSubmitting:false},[t,i]=useReducer(ce,r),n=useRef(e);n.current=e;let l=useCallback((d,p)=>{i({type:"SET_VALUE",fieldId:d,value:p}),n.current?.(d,p,{...t.values,[d]:p});},[t.values]),u=useCallback(d=>{i({type:"SET_FIELD_TOUCHED",fieldId:d});},[]),F=useCallback((d,p)=>{i({type:"SET_FIELD_ERRORS",fieldId:d,errors:p});},[]),g=useCallback(d=>{i({type:"SET_FIELD_ERRORS",fieldId:d,errors:[]});},[]),f=useCallback((d,p)=>{i({type:"SET_FIELD_VALIDATION_STATE",fieldId:d,state:p});},[]),s=useCallback(d=>{i({type:"SET_SUBMITTING",isSubmitting:d});},[]),m=useCallback(d=>{i({type:"RESET",values:d});},[]),c=useCallback(()=>{let d=Object.values(t.errors).some(a=>a.length>0),p=Object.values(t.validationState).some(a=>a==="invalid");return !d&&!p},[t.errors,t.validationState]);return {formState:t,setValue:l,setFieldTouched:u,setError:F,clearError:g,setFieldValidationState:f,setSubmitting:s,reset:m,isFormValid:c}}function Q({formState:o,onSubmit:e,validateForm:r,setSubmitting:t}){let i=useRef(e);return i.current=e,{submit:useCallback(async l=>{l?.preventDefault();try{return t(!0),(await r()).isValid?(i.current&&await i.current(o.values),!0):!1}catch(u){return console.error("Error during form submission:",u),false}finally{t(false);}},[o.values,r,t])}}function B(){return {isValid:true,errors:[]}}function K({formConfig:o,formState:e,conditionsHelpers:r,setFieldValidationState:t,setError:i}){let n=useRef(o),l=useRef(r),u=useRef(t),F=useRef(i);n.current=o,l.current=r,u.current=t,F.current=i;let g=useCallback(async(s,m)=>{let c=n.current.allFields.find(a=>a.id===s);if(!c)return B();if(!l.current.isFieldVisible(s))return F.current(s,[]),u.current(s,"valid"),B();if(!c.validation||!hasUnifiedValidation(c.validation))return F.current(s,[]),u.current(s,"valid"),B();let d=m!==void 0?m:e.values[s],p=createValidationContext({fieldId:s,formId:n.current.id,allFormData:{...e.values,[s]:d}});u.current(s,"validating");try{let a=await validateWithUnifiedConfig(c.validation,d,p),h=l.current.isFieldRequired(s),v=d==null||d==="";if(h&&v&&!a.errors.some(C=>C.code==="REQUIRED"||C.message.toLowerCase().includes("required"))){let C={isValid:!1,errors:[{message:"This field is required",code:"CONDITIONAL_REQUIRED"},...a.errors]};return F.current(s,C.errors),u.current(s,"invalid"),C}return F.current(s,a.errors),u.current(s,a.isValid?"valid":"invalid"),a}catch(a){let h={isValid:false,errors:[{message:a instanceof Error?a.message:"Validation failed",code:"VALIDATION_ERROR"}]};return F.current(s,h.errors),u.current(s,"invalid"),h}},[e.values]),f=useCallback(async()=>{let s=n.current.allFields.filter(a=>{let h=l.current.isFieldVisible(a.id),v=a.validation&&hasUnifiedValidation(a.validation);return h&&v}),m=n.current.allFields.filter(a=>!l.current.isFieldVisible(a.id));for(let a of m)F.current(a.id,[]),u.current(a.id,"valid");let c=await Promise.all(s.map(a=>g(a.id))),d=c.some(a=>!a.isValid),p=B();if(n.current.validation&&hasUnifiedValidation(n.current.validation)){let a=Object.keys(e.values).reduce((v,R)=>(l.current.isFieldVisible(R)&&(v[R]=e.values[R]),v),{}),h=createValidationContext({formId:n.current.id,allFormData:a});try{p=await validateFormWithUnifiedConfig(n.current.validation,a,h);}catch(v){p={isValid:false,errors:[{message:v instanceof Error?v.message:"Form validation failed",code:"FORM_VALIDATION_ERROR"}]};}}return {isValid:!d&&p.isValid,errors:[...c.flatMap(a=>a.errors),...p.errors]}},[e.values,g]);return {validateField:g,validateForm:f}}function Re({formConfig:o,enabled:e=true}){let r=getGlobalMonitor(),t=useRef(null),i=useRef(0),n=useRef(0);useEffect(()=>{r&&e&&(t.current=r.getProfiler());},[r,e]);let l=useCallback(m=>{if(!r||!e)return;i.current++;let c={formId:o.id,fieldCount:o.allFields.length,timestamp:Date.now(),duration:0,renderDuration:0,validationDuration:0,validationErrors:0,renderCount:m||i.current};r.track("component_render",`form_${o.id}`,{formId:o.id,fieldCount:o.allFields.length,renderCount:i.current},c,"low");},[r,e,o.id,o.allFields.length]),u=useCallback((m,c)=>{if(!r||!e)return;let d=t.current?.getMetrics(`form_validation_${o.id}`),p={formId:o.id,fieldCount:c||o.allFields.length,timestamp:Date.now(),duration:d?.duration||0,renderDuration:0,validationDuration:d?.duration||0,validationErrors:m,renderCount:i.current};r.track("form_validation",`form_${o.id}`,{formId:o.id,validationErrors:m,fieldCount:c||o.allFields.length},p,m>0?"medium":"low");},[r,e,o.id,o.allFields.length]),F=useCallback((m,c)=>{if(!r||!e)return;let d=t.current?.getMetrics(`form_submission_${o.id}`),p={formId:o.id,fieldCount:c||o.allFields.length,timestamp:Date.now(),duration:d?.duration||0,renderDuration:0,validationDuration:0,validationErrors:m?0:1,renderCount:i.current};r.track("form_submission",`form_${o.id}`,{formId:o.id,success:m,fieldCount:c||o.allFields.length,fieldChanges:n.current},p,m?"low":"high");},[r,e,o.id,o.allFields.length]),g=useCallback((m,c)=>{!r||!e||(n.current++,r.track("component_update",`field_${m}`,{formId:o.id,fieldId:m,componentType:c,changeCount:n.current},void 0,"low"));},[r,e,o.id]),f=useCallback(m=>{!t.current||!e||t.current.start(m,{formId:o.id,renderCount:i.current});},[e,o.id]),s=useCallback(m=>{if(!t.current||!e)return null;let c=t.current.end(m);return c?{...c,formId:o.id,fieldCount:o.allFields.length,renderDuration:c.duration,validationDuration:0,validationErrors:0}:null},[e,o.id,o.allFields.length]);return {trackFormRender:l,trackFormValidation:u,trackFormSubmission:F,trackFieldChange:g,startPerformanceTracking:f,endPerformanceTracking:s}}var Y=createContext(null);function $({children:o,formConfig:e,defaultValues:r={},onSubmit:t,onFieldChange:i,className:n}){let l=useRef(e.id),{formState:u,setValue:F,setFieldTouched:g,reset:f,setError:s,clearError:m,setFieldValidationState:c,setSubmitting:d,isFormValid:p}=J({defaultValues:r,onFieldChange:i}),{fieldConditions:a,hasConditionalFields:h,getFieldCondition:v,isFieldVisible:R,isFieldDisabled:C,isFieldRequired:V,isFieldReadonly:x}=W({formConfig:e,formValues:u.values}),P=useMemo(()=>({hasConditionalFields:h,getFieldCondition:v,isFieldVisible:R,isFieldDisabled:C,isFieldRequired:V,isFieldReadonly:x}),[h,v,R,C,V,x]),{validateField:D,validateForm:b}=K({formConfig:e,formState:u,conditionsHelpers:P,setFieldValidationState:c,setError:s}),{submit:I}=Q({formState:u,onSubmit:t,validateForm:b,setSubmitting:d});useEffect(()=>{(l.current===null||e.id!==l.current)&&(l.current=e.id,f(r));},[e.id,f]);let N=useMemo(()=>e,[e]),se=useMemo(()=>({formState:u,formConfig:N,fieldConditions:a,conditionsHelpers:P,setValue:F,setFieldTouched:g,validateField:D,validateForm:b,isFormValid:p,reset:f,submit:I,setError:s,clearError:m}),[u,N,a,P,F,g,D,b,p,f,I,s,m]);return jsx(Y.Provider,{value:se,children:jsx("form",{onSubmit:I,className:n,noValidate:true,children:o})})}function y(){let o=useContext(Y);if(!o)throw new Error("useFormContext must be used within a FormProvider");return o}function Se({formConfig:o,defaultValues:e,onSubmit:r,onFieldChange:t,children:i}){let n=useMemo(()=>o instanceof E?o.build():o,[o]);return jsx($,{formConfig:n,defaultValues:e,onSubmit:r,onFieldChange:t,children:i})}var L=xe.memo(function({fieldId:e,disabled:r=false,customProps:t={},className:i,forceVisible:n=false}){let{formState:l,formConfig:u,setValue:F,setFieldTouched:g,validateField:f,conditionsHelpers:s}=y(),m=u.allFields.find(b=>b.id===e);if(!m)throw new Error(`Field with ID "${e}" not found`);let c=u.config.getComponent(m.componentId);if(!c)throw new Error(`Component with ID "${m.componentId}" not found`);let d=useMemo(()=>({value:l.values[e],errors:l.errors[e]||[],validationState:l.validationState[e]||"idle",isTouched:l.touched[e]||false}),[l.values[e],l.errors[e],l.validationState[e],l.touched[e]]),p=d.validationState==="validating",a=useMemo(()=>({isVisible:n||s.isFieldVisible(e),isFieldDisabled:r||s.isFieldDisabled(e),isFieldRequired:s.isFieldRequired(e),isFieldReadonly:s.isFieldReadonly(e)}),[n,e,r,s,l.values]);if(!a.isVisible)return null;let h=useCallback(async b=>{F(e,b),(m.validation?.validateOnChange||d.isTouched)&&await f(e,b);},[e,F,f,m.validation?.validateOnChange,d.isTouched]),v=useCallback(async()=>{d.isTouched||g(e),m.validation?.validateOnBlur!==false&&await f(e);},[e,d.isTouched,g,f,m.validation?.validateOnBlur]),R=useMemo(()=>({...c.defaultProps??{},...m.props,...t,disabled:a.isFieldDisabled,required:a.isFieldRequired,readOnly:a.isFieldReadonly}),[c.defaultProps,m.props,t,a.isFieldDisabled,a.isFieldRequired,a.isFieldReadonly]),C=useMemo(()=>({id:e,props:R,value:d.value,onChange:h,onBlur:v,disabled:a.isFieldDisabled,error:d.errors,isValidating:p,touched:d.isTouched}),[e,R,d.value,h,v,a.isFieldDisabled,d.errors,p,d.isTouched]),V=c.renderer(C),x=u.renderConfig?.fieldRenderer,P=c.useFieldRenderer!==false,D=x&&P?x({children:V,id:e,...R,error:d.errors,isValidating:p,touched:d.isTouched}):V;return jsx("div",{className:i,"data-field-id":e,"data-field-type":c.type,"data-field-visible":a.isVisible,"data-field-disabled":a.isFieldDisabled,"data-field-required":a.isFieldRequired,"data-field-readonly":a.isFieldReadonly,children:D})});var ie=xe.memo(function({row:e,className:r,...t}){let{formConfig:i}=y(),n=useMemo(()=>e.fields.map(u=>jsx(L,{fieldId:u.id},u.id)),[e.fields]),l=useMemo(()=>({row:e,children:n,className:r}),[e,n,r]);return jsx(ComponentRendererWrapper,{name:"FormRow",renderer:i.renderConfig?.rowRenderer,props:l,...t,children:n})}),oe=ie;var Be=xe.memo(function({className:e,...r}){let{formConfig:t}=y(),i=useMemo(()=>t.rows.map(l=>jsx(oe,{row:l},l.id)),[t.rows]),n=useMemo(()=>({formConfig:t,children:i,className:e}),[t,i,e]);return jsx(ComponentRendererWrapper,{name:"FormBody",renderer:t.renderConfig?.bodyRenderer,props:n,...r,children:i})});var Ue=xe.memo(function({className:e,isSubmitting:r,...t}){let{formState:i,submit:n,formConfig:l}=y(),u=useMemo(()=>({isSubmitting:r??i.isSubmitting,onSubmit:n,className:e}),[r,i.isSubmitting,n,e]);return jsx(ComponentRendererWrapper,{name:"FormSubmitButton",renderer:l.renderConfig?.submitButtonRenderer,props:u,...t})});export{Se as Form,Be as FormBody,E as FormBuilder,L as FormField,$ as FormProvider,ie as FormRow,Ue as FormSubmitButton,E as form,Ge as useConditionEvaluation,W as useFormConditions,y as useFormContext,Re as useFormMonitoring,J as useFormState,Q as useFormSubmission,K as useFormValidation,H as useMultipleConditionEvaluation};
1
+ import xe,{createContext,useMemo,useCallback,useContext,useReducer,useRef,useEffect}from'react';import {ComponentRendererWrapper,IdGenerator,deepClone,ensureUnique,hasUnifiedValidation,createValidationContext,validateWithUnifiedConfig,validateFormWithUnifiedConfig,getGlobalMonitor,evaluateCondition}from'@rilaykit/core';import {jsx}from'react/jsx-runtime';var E=class o{constructor(e,r){this.rows=[];this.idGenerator=new IdGenerator;this.config=e,this.formId=r||`form-${Math.random().toString(36).substring(2,15)}`;}static create(e,r){return new o(e,r)}createFormField(e){let r=this.config.getComponent(e.type);if(!r)throw new Error(`No component found with type "${e.type}"`);let t;return (r.validation||e.validation)&&(t={validateOnChange:e.validation?.validateOnChange??r.validation?.validateOnChange,validateOnBlur:e.validation?.validateOnBlur??r.validation?.validateOnBlur,debounceMs:e.validation?.debounceMs??r.validation?.debounceMs,validate:(()=>{let i=r.validation?.validate,n=e.validation?.validate;if(!i)return n;if(!n)return i;let l=Array.isArray(i)?i:[i],u=Array.isArray(n)?n:[n];return [...l,...u]})()}),{id:e.id||this.idGenerator.next("field"),componentId:r.id,props:{...r.defaultProps,...e.props},validation:t,conditions:e.conditions}}createRow(e){if(e.length===0)throw new Error("At least one field is required");if(e.length>3)throw new Error("Maximum 3 fields per row");let r=e.map(t=>this.createFormField(t));return {id:this.idGenerator.next("row"),fields:r,maxColumns:e.length}}add(...e){let r,t=false;if(e.length===1&&Array.isArray(e[0])?(r=e[0],t=true):r=e,r.length===0)throw new Error("At least one field is required");if(t&&r.length>3)throw new Error("Maximum 3 fields per row");if(r.length===1){let i=this.createRow(r);return this.rows.push(i),this}if(r.length<=3){let i=this.createRow(r);return this.rows.push(i),this}for(let i of r){let n=this.createRow([i]);this.rows.push(n);}return this}addSeparateRows(e){for(let r of e)this.add(r);return this}setId(e){return this.formId=e,this}updateField(e,r){let t=this.findField(e);if(!t)throw new Error(`Field with ID "${e}" not found`);return Object.assign(t,{...r,props:{...t.props,...r.props}}),this}findField(e){for(let r of this.rows){let t=r.fields.find(i=>i.id===e);if(t)return t}return null}removeField(e){return this.rows=this.rows.map(r=>({...r,fields:r.fields.filter(t=>t.id!==e)})).filter(r=>r.fields.length>0),this}getField(e){return this.findField(e)||void 0}getFields(){return this.rows.flatMap(e=>e.fields)}getRows(){return [...this.rows]}clear(){return this.rows=[],this.idGenerator.reset(),this}setValidation(e){return this.formValidation=e,this}addFieldValidation(e,r){console.warn("addFieldValidation is deprecated. Use updateField with validation.validate property instead.");let t=this.findField(e);if(!t)throw new Error(`Field with ID "${e}" not found`);let i={...t.validation,...r};return this.updateField(e,{validation:i})}addFieldConditions(e,r){let t=this.findField(e);if(!t)throw new Error(`Field with ID "${e}" not found`);let i={...t.conditions,...r};return this.updateField(e,{conditions:i})}clone(e){let r=new o(this.config,e||`${this.formId}-clone`);return r.rows=deepClone(this.rows),r}validate(){let e=[],r=this.getFields(),t=r.map(i=>i.id);try{ensureUnique(t,"field");}catch(i){e.push(i instanceof Error?i.message:String(i));}for(let i of r)this.config.hasComponent(i.componentId)||e.push(`Component "${i.componentId}" not found for field "${i.id}"`);for(let i of this.rows)i.fields.length>3&&e.push(`Row "${i.id}" has ${i.fields.length} fields, maximum is 3`),i.fields.length===0&&e.push(`Row "${i.id}" is empty`);return e}build(){let e=this.validate();if(e.length>0)throw new Error(`Form validation failed: ${e.join(", ")}`);return {id:this.formId,rows:[...this.rows],allFields:this.getFields(),config:this.config,renderConfig:this.config.getFormRenderConfig(),validation:this.formValidation}}toJSON(){return {id:this.formId,rows:this.rows}}fromJSON(e){return e.id&&(this.formId=e.id),e.rows&&(this.rows=e.rows),this}getStats(){let e=this.getFields(),r=this.rows.map(t=>t.fields.length);return {totalFields:e.length,totalRows:this.rows.length,averageFieldsPerRow:this.rows.length>0?e.length/this.rows.length:0,maxFieldsInRow:r.length>0?Math.max(...r):0,minFieldsInRow:r.length>0?Math.min(...r):0}}};function Ge(o,e={},r={}){return useMemo(()=>{if(!o)return {visible:r.visible??true,disabled:r.disabled??false,required:r.required??false,readonly:r.readonly??false};let t=i=>{try{return i&&typeof i=="object"&&"build"in i?evaluateCondition(i.build(),e):evaluateCondition(i,e)}catch(n){return console.warn("Error evaluating condition:",n),false}};return {visible:o.visible?t(o.visible):r.visible??true,disabled:o.disabled?t(o.disabled):r.disabled??false,required:o.required?t(o.required):r.required??false,readonly:o.readonly?t(o.readonly):r.readonly??false}},[o,e,r])}function H(o,e={}){return useMemo(()=>{let r={};for(let[t,i]of Object.entries(o))if(r[t]={visible:true,disabled:false,required:false,readonly:false},i){let n=l=>{try{return l&&typeof l=="object"&&"build"in l?evaluateCondition(l.build(),e):evaluateCondition(l,e)}catch(u){return console.warn(`Error evaluating condition for field ${t}:`,u),false}};r[t]={visible:i.visible?n(i.visible):true,disabled:i.disabled?n(i.disabled):false,required:i.required?n(i.required):false,readonly:i.readonly?n(i.readonly):false};}return r},[o,e])}function W({formConfig:o,formValues:e}){let r=useMemo(()=>{let f={};for(let s of o.allFields)s.conditions&&(f[s.id]=s.conditions);return f},[o.allFields]),t=useMemo(()=>Object.keys(r).length>0,[r]),i=H(t?r:{},t?e:{}),n=useCallback(f=>i[f],[i]),l=useCallback(f=>{let s=i[f];return s?s.visible:true},[i]),u=useCallback(f=>{let s=i[f];return s?s.disabled:false},[i]),F=useCallback(f=>{let s=i[f];return s?s.required:false},[i]),g=useCallback(f=>{let s=i[f];return s?s.readonly:false},[i]);return useMemo(()=>({fieldConditions:i,hasConditionalFields:t,getFieldCondition:n,isFieldVisible:l,isFieldDisabled:u,isFieldRequired:F,isFieldReadonly:g}),[i,t,n,l,u,F,g])}function ce(o,e){switch(e.type){case "SET_VALUE":return {...o,values:{...o.values,[e.fieldId]:e.value},isDirty:true};case "SET_FIELD_ERRORS":return {...o,errors:{...o.errors,[e.fieldId]:e.errors}};case "SET_FIELD_VALIDATION_STATE":return {...o,validationState:{...o.validationState,[e.fieldId]:e.state}};case "SET_FIELD_TOUCHED":return {...o,touched:{...o.touched,[e.fieldId]:true}};case "SET_SUBMITTING":return {...o,isSubmitting:e.isSubmitting};case "RESET":return {values:e.values||{},errors:{},validationState:{},touched:{},isDirty:false,isSubmitting:false};default:return o}}function J({defaultValues:o={},onFieldChange:e}){let r={values:o,errors:{},validationState:{},touched:{},isDirty:false,isSubmitting:false},[t,i]=useReducer(ce,r),n=useRef(e);n.current=e;let l=useCallback((d,p)=>{i({type:"SET_VALUE",fieldId:d,value:p}),n.current?.(d,p,{...t.values,[d]:p});},[t.values]),u=useCallback(d=>{i({type:"SET_FIELD_TOUCHED",fieldId:d});},[]),F=useCallback((d,p)=>{i({type:"SET_FIELD_ERRORS",fieldId:d,errors:p});},[]),g=useCallback(d=>{i({type:"SET_FIELD_ERRORS",fieldId:d,errors:[]});},[]),f=useCallback((d,p)=>{i({type:"SET_FIELD_VALIDATION_STATE",fieldId:d,state:p});},[]),s=useCallback(d=>{i({type:"SET_SUBMITTING",isSubmitting:d});},[]),m=useCallback(d=>{i({type:"RESET",values:d});},[]),c=useCallback(()=>{let d=Object.values(t.errors).some(a=>a.length>0),p=Object.values(t.validationState).some(a=>a==="invalid");return !d&&!p},[t.errors,t.validationState]);return {formState:t,setValue:l,setFieldTouched:u,setError:F,clearError:g,setFieldValidationState:f,setSubmitting:s,reset:m,isFormValid:c}}function Q({formState:o,onSubmit:e,validateForm:r,setSubmitting:t}){let i=useRef(e);return i.current=e,{submit:useCallback(async l=>{l?.preventDefault();try{return t(!0),(await r()).isValid?(i.current&&await i.current(o.values),!0):!1}catch(u){return console.error("Error during form submission:",u),false}finally{t(false);}},[o.values,r,t])}}function B(){return {isValid:true,errors:[]}}function K({formConfig:o,formState:e,conditionsHelpers:r,setFieldValidationState:t,setError:i}){let n=useRef(o),l=useRef(r),u=useRef(t),F=useRef(i);n.current=o,l.current=r,u.current=t,F.current=i;let g=useCallback(async(s,m)=>{let c=n.current.allFields.find(a=>a.id===s);if(!c)return B();if(!l.current.isFieldVisible(s))return F.current(s,[]),u.current(s,"valid"),B();if(!c.validation||!hasUnifiedValidation(c.validation))return F.current(s,[]),u.current(s,"valid"),B();let d=m!==void 0?m:e.values[s],p=createValidationContext({fieldId:s,formId:n.current.id,allFormData:{...e.values,[s]:d}});u.current(s,"validating");try{let a=await validateWithUnifiedConfig(c.validation,d,p),h=l.current.isFieldRequired(s),v=d==null||d==="";if(h&&v&&!a.errors.some(C=>C.code==="REQUIRED"||C.message.toLowerCase().includes("required"))){let C={isValid:!1,errors:[{message:"This field is required",code:"CONDITIONAL_REQUIRED"},...a.errors]};return F.current(s,C.errors),u.current(s,"invalid"),C}return F.current(s,a.errors),u.current(s,a.isValid?"valid":"invalid"),a}catch(a){let h={isValid:false,errors:[{message:a instanceof Error?a.message:"Validation failed",code:"VALIDATION_ERROR"}]};return F.current(s,h.errors),u.current(s,"invalid"),h}},[e.values]),f=useCallback(async()=>{let s=n.current.allFields.filter(a=>{let h=l.current.isFieldVisible(a.id),v=a.validation&&hasUnifiedValidation(a.validation);return h&&v}),m=n.current.allFields.filter(a=>!l.current.isFieldVisible(a.id));for(let a of m)F.current(a.id,[]),u.current(a.id,"valid");let c=await Promise.all(s.map(a=>g(a.id))),d=c.some(a=>!a.isValid),p=B();if(n.current.validation&&hasUnifiedValidation(n.current.validation)){let a=Object.keys(e.values).reduce((v,R)=>(l.current.isFieldVisible(R)&&(v[R]=e.values[R]),v),{}),h=createValidationContext({formId:n.current.id,allFormData:a});try{p=await validateFormWithUnifiedConfig(n.current.validation,a,h);}catch(v){p={isValid:false,errors:[{message:v instanceof Error?v.message:"Form validation failed",code:"FORM_VALIDATION_ERROR"}]};}}return {isValid:!d&&p.isValid,errors:[...c.flatMap(a=>a.errors),...p.errors]}},[e.values,g]);return {validateField:g,validateForm:f}}function Re({formConfig:o,enabled:e=true}){let r=getGlobalMonitor(),t=useRef(null),i=useRef(0),n=useRef(0);useEffect(()=>{r&&e&&(t.current=r.getProfiler());},[r,e]);let l=useCallback(m=>{if(!r||!e)return;i.current++;let c={formId:o.id,fieldCount:o.allFields.length,timestamp:Date.now(),duration:0,renderDuration:0,validationDuration:0,validationErrors:0,renderCount:m||i.current};r.track("component_render",`form_${o.id}`,{formId:o.id,fieldCount:o.allFields.length,renderCount:i.current},c,"low");},[r,e,o.id,o.allFields.length]),u=useCallback((m,c)=>{if(!r||!e)return;let d=t.current?.getMetrics(`form_validation_${o.id}`),p={formId:o.id,fieldCount:c||o.allFields.length,timestamp:Date.now(),duration:d?.duration||0,renderDuration:0,validationDuration:d?.duration||0,validationErrors:m,renderCount:i.current};r.track("form_validation",`form_${o.id}`,{formId:o.id,validationErrors:m,fieldCount:c||o.allFields.length},p,m>0?"medium":"low");},[r,e,o.id,o.allFields.length]),F=useCallback((m,c)=>{if(!r||!e)return;let d=t.current?.getMetrics(`form_submission_${o.id}`),p={formId:o.id,fieldCount:c||o.allFields.length,timestamp:Date.now(),duration:d?.duration||0,renderDuration:0,validationDuration:0,validationErrors:m?0:1,renderCount:i.current};r.track("form_submission",`form_${o.id}`,{formId:o.id,success:m,fieldCount:c||o.allFields.length,fieldChanges:n.current},p,m?"low":"high");},[r,e,o.id,o.allFields.length]),g=useCallback((m,c)=>{!r||!e||(n.current++,r.track("component_update",`field_${m}`,{formId:o.id,fieldId:m,componentType:c,changeCount:n.current},void 0,"low"));},[r,e,o.id]),f=useCallback(m=>{!t.current||!e||t.current.start(m,{formId:o.id,renderCount:i.current});},[e,o.id]),s=useCallback(m=>{if(!t.current||!e)return null;let c=t.current.end(m);return c?{...c,formId:o.id,fieldCount:o.allFields.length,renderDuration:c.duration,validationDuration:0,validationErrors:0}:null},[e,o.id,o.allFields.length]);return {trackFormRender:l,trackFormValidation:u,trackFormSubmission:F,trackFieldChange:g,startPerformanceTracking:f,endPerformanceTracking:s}}var Y=createContext(null);function $({children:o,formConfig:e,defaultValues:r={},onSubmit:t,onFieldChange:i,className:n}){let l=useRef(e.id),{formState:u,setValue:F,setFieldTouched:g,reset:f,setError:s,clearError:m,setFieldValidationState:c,setSubmitting:d,isFormValid:p}=J({defaultValues:r,onFieldChange:i}),{fieldConditions:a,hasConditionalFields:h,getFieldCondition:v,isFieldVisible:R,isFieldDisabled:C,isFieldRequired:V,isFieldReadonly:x}=W({formConfig:e,formValues:u.values}),P=useMemo(()=>({hasConditionalFields:h,getFieldCondition:v,isFieldVisible:R,isFieldDisabled:C,isFieldRequired:V,isFieldReadonly:x}),[h,v,R,C,V,x]),{validateField:D,validateForm:b}=K({formConfig:e,formState:u,conditionsHelpers:P,setFieldValidationState:c,setError:s}),{submit:I}=Q({formState:u,onSubmit:t,validateForm:b,setSubmitting:d});useEffect(()=>{(l.current===null||e.id!==l.current)&&(l.current=e.id,f(r));},[e.id,f]);let N=useMemo(()=>e,[e]),se=useMemo(()=>({formState:u,formConfig:N,fieldConditions:a,conditionsHelpers:P,setValue:F,setFieldTouched:g,validateField:D,validateForm:b,isFormValid:p,reset:f,submit:I,setError:s,clearError:m}),[u,N,a,P,F,g,D,b,p,f,I,s,m]);return jsx(Y.Provider,{value:se,children:jsx("form",{onSubmit:I,className:n,noValidate:true,children:o})})}function y(){let o=useContext(Y);if(!o)throw new Error("useFormContext must be used within a FormProvider");return o}function Se({formConfig:o,defaultValues:e,onSubmit:r,onFieldChange:t,children:i}){let n=useMemo(()=>o instanceof E?o.build():o,[o]);return jsx($,{formConfig:n,defaultValues:e,onSubmit:r,onFieldChange:t,children:i})}var L=xe.memo(function({fieldId:e,disabled:r=false,customProps:t={},className:i,forceVisible:n=false}){let{formState:l,formConfig:u,setValue:F,setFieldTouched:g,validateField:f,conditionsHelpers:s}=y(),m=u.allFields.find(b=>b.id===e);if(!m)throw new Error(`Field with ID "${e}" not found`);let c=u.config.getComponent(m.componentId);if(!c)throw new Error(`Component with ID "${m.componentId}" not found`);let d=useMemo(()=>({value:l.values[e],errors:l.errors[e]||[],validationState:l.validationState[e]||"idle",isTouched:l.touched[e]||false}),[l.values[e],l.errors[e],l.validationState[e],l.touched[e]]),p=d.validationState==="validating",a=useMemo(()=>({isVisible:n||s.isFieldVisible(e),isFieldDisabled:r||s.isFieldDisabled(e),isFieldRequired:s.isFieldRequired(e),isFieldReadonly:s.isFieldReadonly(e)}),[n,e,r,s,l.values]),h=useCallback(async b=>{F(e,b),(m.validation?.validateOnChange||d.isTouched)&&await f(e,b);},[e,F,f,m.validation?.validateOnChange,d.isTouched]),v=useCallback(async()=>{d.isTouched||g(e),m.validation?.validateOnBlur!==false&&await f(e);},[e,d.isTouched,g,f,m.validation?.validateOnBlur]),R=useMemo(()=>({...c.defaultProps??{},...m.props,...t,disabled:a.isFieldDisabled,required:a.isFieldRequired,readOnly:a.isFieldReadonly}),[c.defaultProps,m.props,t,a.isFieldDisabled,a.isFieldRequired,a.isFieldReadonly]),C=useMemo(()=>({id:e,props:R,value:d.value,onChange:h,onBlur:v,disabled:a.isFieldDisabled,error:d.errors,isValidating:p,touched:d.isTouched}),[e,R,d.value,h,v,a.isFieldDisabled,d.errors,p,d.isTouched]);if(!a.isVisible)return null;let V=c.renderer(C),x=u.renderConfig?.fieldRenderer,P=c.useFieldRenderer!==false,D=x&&P?x({children:V,id:e,...R,error:d.errors,isValidating:p,touched:d.isTouched}):V;return jsx("div",{className:i,"data-field-id":e,"data-field-type":c.type,"data-field-visible":a.isVisible,"data-field-disabled":a.isFieldDisabled,"data-field-required":a.isFieldRequired,"data-field-readonly":a.isFieldReadonly,children:D})});var ie=xe.memo(function({row:e,className:r,...t}){let{formConfig:i}=y(),n=useMemo(()=>e.fields.map(u=>jsx(L,{fieldId:u.id},u.id)),[e.fields]),l=useMemo(()=>({row:e,children:n,className:r}),[e,n,r]);return jsx(ComponentRendererWrapper,{name:"FormRow",renderer:i.renderConfig?.rowRenderer,props:l,...t,children:n})}),oe=ie;var Be=xe.memo(function({className:e,...r}){let{formConfig:t}=y(),i=useMemo(()=>t.rows.map(l=>jsx(oe,{row:l},l.id)),[t.rows]),n=useMemo(()=>({formConfig:t,children:i,className:e}),[t,i,e]);return jsx(ComponentRendererWrapper,{name:"FormBody",renderer:t.renderConfig?.bodyRenderer,props:n,...r,children:i})});var Ue=xe.memo(function({className:e,isSubmitting:r,...t}){let{formState:i,submit:n,formConfig:l}=y(),u=useMemo(()=>({isSubmitting:r??i.isSubmitting,onSubmit:n,className:e}),[r,i.isSubmitting,n,e]);return jsx(ComponentRendererWrapper,{name:"FormSubmitButton",renderer:l.renderConfig?.submitButtonRenderer,props:u,...t})});export{Se as Form,Be as FormBody,E as FormBuilder,L as FormField,$ as FormProvider,ie as FormRow,Ue as FormSubmitButton,E as form,Ge as useConditionEvaluation,W as useFormConditions,y as useFormContext,Re as useFormMonitoring,J as useFormState,Q as useFormSubmission,K as useFormValidation,H as useMultipleConditionEvaluation};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rilaykit/forms",
3
- "version": "12.0.0",
3
+ "version": "13.0.0",
4
4
  "description": "Form building utilities and components for RilayKit",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",