@rilaykit/forms 9.0.1 → 11.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.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { ril, FieldValidationConfig, ConditionalBehavior, FormFieldConfig, FormFieldRow, FormValidationConfig, FormValidator, FormConfiguration, ComponentRendererBaseProps, FormBodyRendererProps, ValidationError, ValidationResult, MonitoringConfig, FormPerformanceMetrics, FormRowRendererProps, FormSubmitButtonRendererProps } from '@rilaykit/core';
2
+ import { ril, FieldValidationConfig, ConditionalBehavior, FormFieldConfig, FormFieldRow, FormValidationConfig, FormConfiguration, ComponentRendererBaseProps, FormBodyRendererProps, ValidationError, ValidationResult, MonitoringConfig, FormPerformanceMetrics, FormRowRendererProps, FormSubmitButtonRendererProps } from '@rilaykit/core';
3
3
  import React$1 from 'react';
4
4
 
5
5
  /**
@@ -364,7 +364,6 @@ declare class form<C extends Record<string, any> = Record<string, never>> {
364
364
  * ]);
365
365
  * ```
366
366
  */
367
- addValidators(validators: FormValidator[]): this;
368
367
  /**
369
368
  * Adds validation to a specific field by ID
370
369
  *
@@ -384,7 +383,8 @@ declare class form<C extends Record<string, any> = Record<string, never>> {
384
383
  * });
385
384
  * ```
386
385
  */
387
- addFieldValidation(fieldId: string, validationConfig: FieldValidationConfig): this;
386
+ /** @deprecated Use updateField with new validation.validate property instead */
387
+ addFieldValidation(fieldId: string, validationConfig: any): this;
388
388
  /**
389
389
  * Adds conditions to a specific field by ID
390
390
  *
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { ril, FieldValidationConfig, ConditionalBehavior, FormFieldConfig, FormFieldRow, FormValidationConfig, FormValidator, FormConfiguration, ComponentRendererBaseProps, FormBodyRendererProps, ValidationError, ValidationResult, MonitoringConfig, FormPerformanceMetrics, FormRowRendererProps, FormSubmitButtonRendererProps } from '@rilaykit/core';
2
+ import { ril, FieldValidationConfig, ConditionalBehavior, FormFieldConfig, FormFieldRow, FormValidationConfig, FormConfiguration, ComponentRendererBaseProps, FormBodyRendererProps, ValidationError, ValidationResult, MonitoringConfig, FormPerformanceMetrics, FormRowRendererProps, FormSubmitButtonRendererProps } from '@rilaykit/core';
3
3
  import React$1 from 'react';
4
4
 
5
5
  /**
@@ -364,7 +364,6 @@ declare class form<C extends Record<string, any> = Record<string, never>> {
364
364
  * ]);
365
365
  * ```
366
366
  */
367
- addValidators(validators: FormValidator[]): this;
368
367
  /**
369
368
  * Adds validation to a specific field by ID
370
369
  *
@@ -384,7 +383,8 @@ declare class form<C extends Record<string, any> = Record<string, never>> {
384
383
  * });
385
384
  * ```
386
385
  */
387
- addFieldValidation(fieldId: string, validationConfig: FieldValidationConfig): this;
386
+ /** @deprecated Use updateField with new validation.validate property instead */
387
+ addFieldValidation(fieldId: string, validationConfig: any): this;
388
388
  /**
389
389
  * Adds conditions to a specific field by ID
390
390
  *
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- 'use strict';var Ve=require('react'),core=require('@rilaykit/core'),jsxRuntime=require('react/jsx-runtime');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var Ve__default=/*#__PURE__*/_interopDefault(Ve);var V=class i{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 i(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,validators:[...r.validation?.validators||[],...e.validation?.validators||[]]}),{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 o=this.createRow(r);return this.rows.push(o),this}if(r.length<=3){let o=this.createRow(r);return this.rows.push(o),this}for(let o of r){let d=this.createRow([o]);this.rows.push(d);}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(o=>o.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}addValidators(e){return this.formValidation||(this.formValidation={validators:[]}),this.formValidation={...this.formValidation,validators:[...this.formValidation.validators||[],...e]},this}addFieldValidation(e,r){let t=this.findField(e);if(!t)throw new Error(`Field with ID "${e}" not found`);let o={...t.validation,...r,validators:[...t.validation?.validators||[],...r.validators||[]]};return this.updateField(e,{validation:o})}addFieldConditions(e,r){let t=this.findField(e);if(!t)throw new Error(`Field with ID "${e}" not found`);let o={...t.conditions,...r};return this.updateField(e,{conditions:o})}clone(e){let r=new i(this.config,e||`${this.formId}-clone`);return r.rows=core.deepClone(this.rows),r}validate(){let e=[],r=this.getFields(),t=r.map(o=>o.id);try{core.ensureUnique(t,"field");}catch(o){e.push(o instanceof Error?o.message:String(o));}for(let o of r)this.config.hasComponent(o.componentId)||e.push(`Component "${o.componentId}" not found for field "${o.id}"`);for(let o of this.rows)o.fields.length>3&&e.push(`Row "${o.id}" has ${o.fields.length} fields, maximum is 3`),o.fields.length===0&&e.push(`Row "${o.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 Le(i,e={},r={}){return Ve.useMemo(()=>{if(!i)return {visible:r.visible??true,disabled:r.disabled??false,required:r.required??false,readonly:r.readonly??false};let t=o=>{try{return o&&typeof o=="object"&&"build"in o?core.evaluateCondition(o.build(),e):core.evaluateCondition(o,e)}catch(d){return console.warn("Error evaluating condition:",d),false}};return {visible:i.visible?t(i.visible):r.visible??true,disabled:i.disabled?t(i.disabled):r.disabled??false,required:i.required?t(i.required):r.required??false,readonly:i.readonly?t(i.readonly):r.readonly??false}},[i,e,r])}function G(i,e={}){return Ve.useMemo(()=>{let r={};for(let[t,o]of Object.entries(i))if(r[t]={visible:true,disabled:false,required:false,readonly:false},o){let d=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:o.visible?d(o.visible):true,disabled:o.disabled?d(o.disabled):false,required:o.required?d(o.required):false,readonly:o.readonly?d(o.readonly):false};}return r},[i,e])}function H({formConfig:i,formValues:e}){let r=Ve.useMemo(()=>{let f={};for(let n of i.allFields)n.conditions&&(f[n.id]=n.conditions);return f},[i.allFields]),t=Ve.useMemo(()=>Object.keys(r).length>0,[r]),o=G(t?r:{},t?e:{}),d=Ve.useCallback(f=>o[f],[o]),l=Ve.useCallback(f=>{let n=o[f];return n?n.visible:true},[o]),u=Ve.useCallback(f=>{let n=o[f];return n?n.disabled:false},[o]),p=Ve.useCallback(f=>{let n=o[f];return n?n.required:false},[o]),g=Ve.useCallback(f=>{let n=o[f];return n?n.readonly:false},[o]);return Ve.useMemo(()=>({fieldConditions:o,hasConditionalFields:t,getFieldCondition:d,isFieldVisible:l,isFieldDisabled:u,isFieldRequired:p,isFieldReadonly:g}),[o,t,d,l,u,p,g])}function ce(i,e){switch(e.type){case "SET_VALUE":return {...i,values:{...i.values,[e.fieldId]:e.value},isDirty:true};case "SET_FIELD_ERRORS":return {...i,errors:{...i.errors,[e.fieldId]:e.errors}};case "SET_FIELD_VALIDATION_STATE":return {...i,validationState:{...i.validationState,[e.fieldId]:e.state}};case "SET_FIELD_TOUCHED":return {...i,touched:{...i.touched,[e.fieldId]:true}};case "SET_SUBMITTING":return {...i,isSubmitting:e.isSubmitting};case "RESET":return {values:e.values||{},errors:{},validationState:{},touched:{},isDirty:false,isSubmitting:false};default:return i}}function W({defaultValues:i={},onFieldChange:e}){let r={values:i,errors:{},validationState:{},touched:{},isDirty:false,isSubmitting:false},[t,o]=Ve.useReducer(ce,r),d=Ve.useRef(e);d.current=e;let l=Ve.useCallback((s,F)=>{o({type:"SET_VALUE",fieldId:s,value:F}),d.current?.(s,F,{...t.values,[s]:F});},[t.values]),u=Ve.useCallback(s=>{o({type:"SET_FIELD_TOUCHED",fieldId:s});},[]),p=Ve.useCallback((s,F)=>{o({type:"SET_FIELD_ERRORS",fieldId:s,errors:F});},[]),g=Ve.useCallback(s=>{o({type:"SET_FIELD_ERRORS",fieldId:s,errors:[]});},[]),f=Ve.useCallback((s,F)=>{o({type:"SET_FIELD_VALIDATION_STATE",fieldId:s,state:F});},[]),n=Ve.useCallback(s=>{o({type:"SET_SUBMITTING",isSubmitting:s});},[]),m=Ve.useCallback(s=>{o({type:"RESET",values:s});},[]),c=Ve.useCallback(()=>{let s=Object.values(t.errors).some(a=>a.length>0),F=Object.values(t.validationState).some(a=>a==="invalid");return !s&&!F},[t.errors,t.validationState]);return {formState:t,setValue:l,setFieldTouched:u,setError:p,clearError:g,setFieldValidationState:f,setSubmitting:n,reset:m,isFormValid:c}}function J({formState:i,onSubmit:e,validateForm:r,setSubmitting:t}){let o=Ve.useRef(e);return o.current=e,{submit:Ve.useCallback(async l=>{l?.preventDefault();try{return t(!0),(await r()).isValid?(o.current&&await o.current(i.values),!0):!1}catch(u){return console.error("Error during form submission:",u),false}finally{t(false);}},[i.values,r,t])}}function B(){return {isValid:true,errors:[]}}function K({formConfig:i,formState:e,conditionsHelpers:r,setFieldValidationState:t,setError:o}){let d=Ve.useRef(i),l=Ve.useRef(r),u=Ve.useRef(t),p=Ve.useRef(o);d.current=i,l.current=r,u.current=t,p.current=o;let g=Ve.useCallback(async(n,m)=>{let c=d.current.allFields.find(a=>a.id===n);if(!c)return B();if(!l.current.isFieldVisible(n))return p.current(n,[]),u.current(n,"valid"),B();if(!c.validation?.validators?.length)return p.current(n,[]),u.current(n,"valid"),B();let s=m!==void 0?m:e.values[n],F=core.createValidationContext({fieldId:n,formId:d.current.id,allFormData:{...e.values,[n]:s}});u.current(n,"validating");try{let a=await core.runValidatorsAsync(c.validation.validators,s,F),h=l.current.isFieldRequired(n),v=s==null||s==="";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 p.current(n,C.errors),u.current(n,"invalid"),C}return p.current(n,a.errors),u.current(n,a.isValid?"valid":"invalid"),a}catch(a){let h={isValid:false,errors:[{message:a instanceof Error?a.message:"Validation failed",code:"VALIDATION_ERROR"}]};return p.current(n,h.errors),u.current(n,"invalid"),h}},[e.values]),f=Ve.useCallback(async()=>{let n=d.current.allFields.filter(a=>{let h=l.current.isFieldVisible(a.id),v=a.validation?.validators&&a.validation.validators.length>0;return h&&v}),m=d.current.allFields.filter(a=>!l.current.isFieldVisible(a.id));for(let a of m)p.current(a.id,[]),u.current(a.id,"valid");let c=await Promise.all(n.map(a=>g(a.id))),s=c.some(a=>!a.isValid),F=B();if(d.current.validation?.validators?.length){let a=Object.keys(e.values).reduce((v,R)=>(l.current.isFieldVisible(R)&&(v[R]=e.values[R]),v),{}),h=core.createValidationContext({formId:d.current.id,allFormData:a});try{F=await core.runValidatorsAsync(d.current.validation.validators,a,h);}catch(v){F={isValid:false,errors:[{message:v instanceof Error?v.message:"Form validation failed",code:"FORM_VALIDATION_ERROR"}]};}}return {isValid:!s&&F.isValid,errors:[...c.flatMap(a=>a.errors),...F.errors]}},[e.values,g]);return {validateField:g,validateForm:f}}function ve({formConfig:i,enabled:e=true}){let r=core.getGlobalMonitor(),t=Ve.useRef(null),o=Ve.useRef(0),d=Ve.useRef(0);Ve.useEffect(()=>{r&&e&&(t.current=r.getProfiler());},[r,e]);let l=Ve.useCallback(m=>{if(!r||!e)return;o.current++;let c={formId:i.id,fieldCount:i.allFields.length,timestamp:Date.now(),duration:0,renderDuration:0,validationDuration:0,validationErrors:0,renderCount:m||o.current};r.track("component_render",`form_${i.id}`,{formId:i.id,fieldCount:i.allFields.length,renderCount:o.current},c,"low");},[r,e,i.id,i.allFields.length]),u=Ve.useCallback((m,c)=>{if(!r||!e)return;let s=t.current?.getMetrics(`form_validation_${i.id}`),F={formId:i.id,fieldCount:c||i.allFields.length,timestamp:Date.now(),duration:s?.duration||0,renderDuration:0,validationDuration:s?.duration||0,validationErrors:m,renderCount:o.current};r.track("form_validation",`form_${i.id}`,{formId:i.id,validationErrors:m,fieldCount:c||i.allFields.length},F,m>0?"medium":"low");},[r,e,i.id,i.allFields.length]),p=Ve.useCallback((m,c)=>{if(!r||!e)return;let s=t.current?.getMetrics(`form_submission_${i.id}`),F={formId:i.id,fieldCount:c||i.allFields.length,timestamp:Date.now(),duration:s?.duration||0,renderDuration:0,validationDuration:0,validationErrors:m?0:1,renderCount:o.current};r.track("form_submission",`form_${i.id}`,{formId:i.id,success:m,fieldCount:c||i.allFields.length,fieldChanges:d.current},F,m?"low":"high");},[r,e,i.id,i.allFields.length]),g=Ve.useCallback((m,c)=>{!r||!e||(d.current++,r.track("component_update",`field_${m}`,{formId:i.id,fieldId:m,componentType:c,changeCount:d.current},void 0,"low"));},[r,e,i.id]),f=Ve.useCallback(m=>{!t.current||!e||t.current.start(m,{formId:i.id,renderCount:o.current});},[e,i.id]),n=Ve.useCallback(m=>{if(!t.current||!e)return null;let c=t.current.end(m);return c?{...c,formId:i.id,fieldCount:i.allFields.length,renderDuration:c.duration,validationDuration:0,validationErrors:0}:null},[e,i.id,i.allFields.length]);return {trackFormRender:l,trackFormValidation:u,trackFormSubmission:p,trackFieldChange:g,startPerformanceTracking:f,endPerformanceTracking:n}}var Y=Ve.createContext(null);function A({children:i,formConfig:e,defaultValues:r={},onSubmit:t,onFieldChange:o,className:d}){let l=Ve.useRef(e.id),{formState:u,setValue:p,setFieldTouched:g,reset:f,setError:n,clearError:m,setFieldValidationState:c,setSubmitting:s,isFormValid:F}=W({defaultValues:r,onFieldChange:o}),{fieldConditions:a,hasConditionalFields:h,getFieldCondition:v,isFieldVisible:R,isFieldDisabled:C,isFieldRequired:E,isFieldReadonly:T}=H({formConfig:e,formValues:u.values}),y=Ve.useMemo(()=>({hasConditionalFields:h,getFieldCondition:v,isFieldVisible:R,isFieldDisabled:C,isFieldRequired:E,isFieldReadonly:T}),[h,v,R,C,E,T]),{validateField:D,validateForm:_}=K({formConfig:e,formState:u,conditionsHelpers:y,setFieldValidationState:c,setError:n}),{submit:O}=J({formState:u,onSubmit:t,validateForm:_,setSubmitting:s});Ve.useEffect(()=>{(l.current===null||e.id!==l.current)&&(l.current=e.id,console.log("resetting form",r),f(r));},[e.id,f]);let L=Ve.useMemo(()=>e,[e]),se=Ve.useMemo(()=>({formState:u,formConfig:L,fieldConditions:a,conditionsHelpers:y,setValue:p,setFieldTouched:g,validateField:D,validateForm:_,isFormValid:F,reset:f,submit:O,setError:n,clearError:m}),[u,L,a,y,p,g,D,_,F,f,O,n,m]);return jsxRuntime.jsx(Y.Provider,{value:se,children:jsxRuntime.jsx("form",{onSubmit:O,className:d,noValidate:true,children:i})})}function b(){let i=Ve.useContext(Y);if(!i)throw new Error("useFormContext must be used within a FormProvider");return i}function we({formConfig:i,defaultValues:e,onSubmit:r,onFieldChange:t,children:o}){let d=Ve.useMemo(()=>i instanceof V?i.build():i,[i]);return jsxRuntime.jsx(A,{formConfig:d,defaultValues:e,onSubmit:r,onFieldChange:t,children:o})}var $=Ve__default.default.memo(function({fieldId:e,disabled:r=false,customProps:t={},className:o,forceVisible:d=false}){let{formState:l,formConfig:u,setValue:p,setFieldTouched:g,validateField:f,conditionsHelpers:n}=b(),m=u.allFields.find(y=>y.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 s=Ve.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]]),F=s.validationState==="validating",a=Ve.useMemo(()=>({isVisible:d||n.isFieldVisible(e),isFieldDisabled:r||n.isFieldDisabled(e),isFieldRequired:n.isFieldRequired(e),isFieldReadonly:n.isFieldReadonly(e)}),[d,n.isFieldVisible(e),r,n.isFieldDisabled(e),n.isFieldRequired(e),n.isFieldReadonly(e)]);if(!a.isVisible)return null;let h=Ve.useCallback(async y=>{p(e,y),(m.validation?.validateOnChange||s.isTouched)&&await f(e,y);},[e,p,f,m.validation?.validateOnChange,s.isTouched]),v=Ve.useCallback(async()=>{s.isTouched||g(e),m.validation?.validateOnBlur!==false&&await f(e);},[e,s.isTouched,g,f,m.validation?.validateOnBlur]),R=Ve.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=Ve.useMemo(()=>({id:e,props:R,value:s.value,onChange:h,onBlur:v,disabled:a.isFieldDisabled,error:s.errors,isValidating:F,touched:s.isTouched}),[e,R,s.value,h,v,a.isFieldDisabled,s.errors,F,s.isTouched]),E=Ve.useMemo(()=>c.renderer(C),[c.renderer,C]),T=Ve.useMemo(()=>{let y=u.renderConfig?.fieldRenderer,D=c.useFieldRenderer!==false;return y&&D?y({children:E,id:e,...R,error:s.errors,isValidating:F,touched:s.isTouched}):E},[u.renderConfig?.fieldRenderer,c.useFieldRenderer,E,e,R,s.errors,F,s.isTouched]);return jsxRuntime.jsx("div",{className:o,"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:T})});var oe=Ve__default.default.memo(function({row:e,className:r,...t}){let{formConfig:o}=b(),d=Ve.useMemo(()=>e.fields.map(u=>jsxRuntime.jsx($,{fieldId:u.id},u.id)),[e.fields]),l=Ve.useMemo(()=>({row:e,children:d,className:r}),[e,d,r]);return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"FormRow",renderer:o.renderConfig?.rowRenderer,props:l,...t,children:d})}),ie=oe;var Me=Ve__default.default.memo(function({className:e,...r}){let{formConfig:t}=b(),o=Ve.useMemo(()=>t.rows.map(l=>jsxRuntime.jsx(ie,{row:l},l.id)),[t.rows]),d=Ve.useMemo(()=>({formConfig:t,children:o,className:e}),[t,o,e]);return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"FormBody",renderer:t.renderConfig?.bodyRenderer,props:d,...r,children:o})});var Oe=Ve__default.default.memo(function({className:e,isSubmitting:r,...t}){let{formState:o,submit:d,formConfig:l}=b(),u=Ve.useMemo(()=>({isSubmitting:r??o.isSubmitting,onSubmit:d,className:e}),[r,o.isSubmitting,d,e]);return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"FormSubmitButton",renderer:l.renderConfig?.submitButtonRenderer,props:u,...t})});exports.Form=we;exports.FormBody=Me;exports.FormBuilder=V;exports.FormField=$;exports.FormProvider=A;exports.FormRow=oe;exports.FormSubmitButton=Oe;exports.form=V;exports.useConditionEvaluation=Le;exports.useFormConditions=H;exports.useFormContext=b;exports.useFormMonitoring=ve;exports.useFormState=W;exports.useFormSubmission=J;exports.useFormValidation=K;exports.useMultipleConditionEvaluation=G;
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,s=e.validation?.validate;if(!i)return s;if(!s)return i;let l=Array.isArray(i)?i:[i],u=Array.isArray(s)?s:[s];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 s=this.createRow([i]);this.rows.push(s);}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(s){return console.warn("Error evaluating condition:",s),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 s=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?s(i.visible):true,disabled:i.disabled?s(i.disabled):false,required:i.required?s(i.required):false,readonly:i.readonly?s(i.readonly):false};}return r},[o,e])}function W({formConfig:o,formValues:e}){let r=xe.useMemo(()=>{let f={};for(let n of o.allFields)n.conditions&&(f[n.id]=n.conditions);return f},[o.allFields]),t=xe.useMemo(()=>Object.keys(r).length>0,[r]),i=H(t?r:{},t?e:{}),s=xe.useCallback(f=>i[f],[i]),l=xe.useCallback(f=>{let n=i[f];return n?n.visible:true},[i]),u=xe.useCallback(f=>{let n=i[f];return n?n.disabled:false},[i]),F=xe.useCallback(f=>{let n=i[f];return n?n.required:false},[i]),g=xe.useCallback(f=>{let n=i[f];return n?n.readonly:false},[i]);return xe.useMemo(()=>({fieldConditions:i,hasConditionalFields:t,getFieldCondition:s,isFieldVisible:l,isFieldDisabled:u,isFieldRequired:F,isFieldReadonly:g}),[i,t,s,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),s=xe.useRef(e);s.current=e;let l=xe.useCallback((d,p)=>{i({type:"SET_VALUE",fieldId:d,value:p}),s.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});},[]),n=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:n,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 s=xe.useRef(o),l=xe.useRef(r),u=xe.useRef(t),F=xe.useRef(i);s.current=o,l.current=r,u.current=t,F.current=i;let g=xe.useCallback(async(n,m)=>{let c=s.current.allFields.find(a=>a.id===n);if(!c)return B();if(!l.current.isFieldVisible(n))return F.current(n,[]),u.current(n,"valid"),B();if(!c.validation||!core.hasUnifiedValidation(c.validation))return F.current(n,[]),u.current(n,"valid"),B();let d=m!==void 0?m:e.values[n],p=core.createValidationContext({fieldId:n,formId:s.current.id,allFormData:{...e.values,[n]:d}});u.current(n,"validating");try{let a=await core.validateWithUnifiedConfig(c.validation,d,p),h=l.current.isFieldRequired(n),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(n,C.errors),u.current(n,"invalid"),C}return F.current(n,a.errors),u.current(n,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(n,h.errors),u.current(n,"invalid"),h}},[e.values]),f=xe.useCallback(async()=>{let n=s.current.allFields.filter(a=>{let h=l.current.isFieldVisible(a.id),v=a.validation&&core.hasUnifiedValidation(a.validation);return h&&v}),m=s.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(n.map(a=>g(a.id))),d=c.some(a=>!a.isValid),p=B();if(s.current.validation&&core.hasUnifiedValidation(s.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:s.current.id,allFormData:a});try{p=await core.validateFormWithUnifiedConfig(s.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),s=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:s.current},p,m?"low":"high");},[r,e,o.id,o.allFields.length]),g=xe.useCallback((m,c)=>{!r||!e||(s.current++,r.track("component_update",`field_${m}`,{formId:o.id,fieldId:m,componentType:c,changeCount:s.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]),n=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:n}}var Y=xe.createContext(null);function $({children:o,formConfig:e,defaultValues:r={},onSubmit:t,onFieldChange:i,className:s}){let l=xe.useRef(e.id),{formState:u,setValue:F,setFieldTouched:g,reset:f,setError:n,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:n}),{submit:O}=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:O,setError:n,clearError:m}),[u,N,a,P,F,g,D,b,p,f,O,n,m]);return jsxRuntime.jsx(Y.Provider,{value:se,children:jsxRuntime.jsx("form",{onSubmit:O,className:s,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 s=xe.useMemo(()=>o instanceof E?o.build():o,[o]);return jsxRuntime.jsx($,{formConfig:s,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:s=false}){let{formState:l,formConfig:u,setValue:F,setFieldTouched:g,validateField:f,conditionsHelpers:n}=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:s||n.isFieldVisible(e),isFieldDisabled:r||n.isFieldDisabled(e),isFieldRequired:n.isFieldRequired(e),isFieldReadonly:n.isFieldReadonly(e)}),[s,n.isFieldVisible(e),r,n.isFieldDisabled(e),n.isFieldRequired(e),n.isFieldReadonly(e)]);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(),s=xe.useMemo(()=>e.fields.map(u=>jsxRuntime.jsx(L,{fieldId:u.id},u.id)),[e.fields]),l=xe.useMemo(()=>({row:e,children:s,className:r}),[e,s,r]);return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"FormRow",renderer:i.renderConfig?.rowRenderer,props:l,...t,children:s})}),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]),s=xe.useMemo(()=>({formConfig:t,children:i,className:e}),[t,i,e]);return jsxRuntime.jsx(core.ComponentRendererWrapper,{name:"FormBody",renderer:t.renderConfig?.bodyRenderer,props:s,...r,children:i})});var Ue=xe__default.default.memo(function({className:e,isSubmitting:r,...t}){let{formState:i,submit:s,formConfig:l}=y(),u=xe.useMemo(()=>({isSubmitting:r??i.isSubmitting,onSubmit:s,className:e}),[r,i.isSubmitting,s,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 Ve,{createContext,useMemo,useCallback,useContext,useReducer,useRef,useEffect}from'react';import {ComponentRendererWrapper,IdGenerator,deepClone,ensureUnique,createValidationContext,runValidatorsAsync,getGlobalMonitor,evaluateCondition}from'@rilaykit/core';import {jsx}from'react/jsx-runtime';var V=class i{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 i(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,validators:[...r.validation?.validators||[],...e.validation?.validators||[]]}),{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 o=this.createRow(r);return this.rows.push(o),this}if(r.length<=3){let o=this.createRow(r);return this.rows.push(o),this}for(let o of r){let d=this.createRow([o]);this.rows.push(d);}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(o=>o.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}addValidators(e){return this.formValidation||(this.formValidation={validators:[]}),this.formValidation={...this.formValidation,validators:[...this.formValidation.validators||[],...e]},this}addFieldValidation(e,r){let t=this.findField(e);if(!t)throw new Error(`Field with ID "${e}" not found`);let o={...t.validation,...r,validators:[...t.validation?.validators||[],...r.validators||[]]};return this.updateField(e,{validation:o})}addFieldConditions(e,r){let t=this.findField(e);if(!t)throw new Error(`Field with ID "${e}" not found`);let o={...t.conditions,...r};return this.updateField(e,{conditions:o})}clone(e){let r=new i(this.config,e||`${this.formId}-clone`);return r.rows=deepClone(this.rows),r}validate(){let e=[],r=this.getFields(),t=r.map(o=>o.id);try{ensureUnique(t,"field");}catch(o){e.push(o instanceof Error?o.message:String(o));}for(let o of r)this.config.hasComponent(o.componentId)||e.push(`Component "${o.componentId}" not found for field "${o.id}"`);for(let o of this.rows)o.fields.length>3&&e.push(`Row "${o.id}" has ${o.fields.length} fields, maximum is 3`),o.fields.length===0&&e.push(`Row "${o.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 Le(i,e={},r={}){return useMemo(()=>{if(!i)return {visible:r.visible??true,disabled:r.disabled??false,required:r.required??false,readonly:r.readonly??false};let t=o=>{try{return o&&typeof o=="object"&&"build"in o?evaluateCondition(o.build(),e):evaluateCondition(o,e)}catch(d){return console.warn("Error evaluating condition:",d),false}};return {visible:i.visible?t(i.visible):r.visible??true,disabled:i.disabled?t(i.disabled):r.disabled??false,required:i.required?t(i.required):r.required??false,readonly:i.readonly?t(i.readonly):r.readonly??false}},[i,e,r])}function G(i,e={}){return useMemo(()=>{let r={};for(let[t,o]of Object.entries(i))if(r[t]={visible:true,disabled:false,required:false,readonly:false},o){let d=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:o.visible?d(o.visible):true,disabled:o.disabled?d(o.disabled):false,required:o.required?d(o.required):false,readonly:o.readonly?d(o.readonly):false};}return r},[i,e])}function H({formConfig:i,formValues:e}){let r=useMemo(()=>{let f={};for(let n of i.allFields)n.conditions&&(f[n.id]=n.conditions);return f},[i.allFields]),t=useMemo(()=>Object.keys(r).length>0,[r]),o=G(t?r:{},t?e:{}),d=useCallback(f=>o[f],[o]),l=useCallback(f=>{let n=o[f];return n?n.visible:true},[o]),u=useCallback(f=>{let n=o[f];return n?n.disabled:false},[o]),p=useCallback(f=>{let n=o[f];return n?n.required:false},[o]),g=useCallback(f=>{let n=o[f];return n?n.readonly:false},[o]);return useMemo(()=>({fieldConditions:o,hasConditionalFields:t,getFieldCondition:d,isFieldVisible:l,isFieldDisabled:u,isFieldRequired:p,isFieldReadonly:g}),[o,t,d,l,u,p,g])}function ce(i,e){switch(e.type){case "SET_VALUE":return {...i,values:{...i.values,[e.fieldId]:e.value},isDirty:true};case "SET_FIELD_ERRORS":return {...i,errors:{...i.errors,[e.fieldId]:e.errors}};case "SET_FIELD_VALIDATION_STATE":return {...i,validationState:{...i.validationState,[e.fieldId]:e.state}};case "SET_FIELD_TOUCHED":return {...i,touched:{...i.touched,[e.fieldId]:true}};case "SET_SUBMITTING":return {...i,isSubmitting:e.isSubmitting};case "RESET":return {values:e.values||{},errors:{},validationState:{},touched:{},isDirty:false,isSubmitting:false};default:return i}}function W({defaultValues:i={},onFieldChange:e}){let r={values:i,errors:{},validationState:{},touched:{},isDirty:false,isSubmitting:false},[t,o]=useReducer(ce,r),d=useRef(e);d.current=e;let l=useCallback((s,F)=>{o({type:"SET_VALUE",fieldId:s,value:F}),d.current?.(s,F,{...t.values,[s]:F});},[t.values]),u=useCallback(s=>{o({type:"SET_FIELD_TOUCHED",fieldId:s});},[]),p=useCallback((s,F)=>{o({type:"SET_FIELD_ERRORS",fieldId:s,errors:F});},[]),g=useCallback(s=>{o({type:"SET_FIELD_ERRORS",fieldId:s,errors:[]});},[]),f=useCallback((s,F)=>{o({type:"SET_FIELD_VALIDATION_STATE",fieldId:s,state:F});},[]),n=useCallback(s=>{o({type:"SET_SUBMITTING",isSubmitting:s});},[]),m=useCallback(s=>{o({type:"RESET",values:s});},[]),c=useCallback(()=>{let s=Object.values(t.errors).some(a=>a.length>0),F=Object.values(t.validationState).some(a=>a==="invalid");return !s&&!F},[t.errors,t.validationState]);return {formState:t,setValue:l,setFieldTouched:u,setError:p,clearError:g,setFieldValidationState:f,setSubmitting:n,reset:m,isFormValid:c}}function J({formState:i,onSubmit:e,validateForm:r,setSubmitting:t}){let o=useRef(e);return o.current=e,{submit:useCallback(async l=>{l?.preventDefault();try{return t(!0),(await r()).isValid?(o.current&&await o.current(i.values),!0):!1}catch(u){return console.error("Error during form submission:",u),false}finally{t(false);}},[i.values,r,t])}}function B(){return {isValid:true,errors:[]}}function K({formConfig:i,formState:e,conditionsHelpers:r,setFieldValidationState:t,setError:o}){let d=useRef(i),l=useRef(r),u=useRef(t),p=useRef(o);d.current=i,l.current=r,u.current=t,p.current=o;let g=useCallback(async(n,m)=>{let c=d.current.allFields.find(a=>a.id===n);if(!c)return B();if(!l.current.isFieldVisible(n))return p.current(n,[]),u.current(n,"valid"),B();if(!c.validation?.validators?.length)return p.current(n,[]),u.current(n,"valid"),B();let s=m!==void 0?m:e.values[n],F=createValidationContext({fieldId:n,formId:d.current.id,allFormData:{...e.values,[n]:s}});u.current(n,"validating");try{let a=await runValidatorsAsync(c.validation.validators,s,F),h=l.current.isFieldRequired(n),v=s==null||s==="";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 p.current(n,C.errors),u.current(n,"invalid"),C}return p.current(n,a.errors),u.current(n,a.isValid?"valid":"invalid"),a}catch(a){let h={isValid:false,errors:[{message:a instanceof Error?a.message:"Validation failed",code:"VALIDATION_ERROR"}]};return p.current(n,h.errors),u.current(n,"invalid"),h}},[e.values]),f=useCallback(async()=>{let n=d.current.allFields.filter(a=>{let h=l.current.isFieldVisible(a.id),v=a.validation?.validators&&a.validation.validators.length>0;return h&&v}),m=d.current.allFields.filter(a=>!l.current.isFieldVisible(a.id));for(let a of m)p.current(a.id,[]),u.current(a.id,"valid");let c=await Promise.all(n.map(a=>g(a.id))),s=c.some(a=>!a.isValid),F=B();if(d.current.validation?.validators?.length){let a=Object.keys(e.values).reduce((v,R)=>(l.current.isFieldVisible(R)&&(v[R]=e.values[R]),v),{}),h=createValidationContext({formId:d.current.id,allFormData:a});try{F=await runValidatorsAsync(d.current.validation.validators,a,h);}catch(v){F={isValid:false,errors:[{message:v instanceof Error?v.message:"Form validation failed",code:"FORM_VALIDATION_ERROR"}]};}}return {isValid:!s&&F.isValid,errors:[...c.flatMap(a=>a.errors),...F.errors]}},[e.values,g]);return {validateField:g,validateForm:f}}function ve({formConfig:i,enabled:e=true}){let r=getGlobalMonitor(),t=useRef(null),o=useRef(0),d=useRef(0);useEffect(()=>{r&&e&&(t.current=r.getProfiler());},[r,e]);let l=useCallback(m=>{if(!r||!e)return;o.current++;let c={formId:i.id,fieldCount:i.allFields.length,timestamp:Date.now(),duration:0,renderDuration:0,validationDuration:0,validationErrors:0,renderCount:m||o.current};r.track("component_render",`form_${i.id}`,{formId:i.id,fieldCount:i.allFields.length,renderCount:o.current},c,"low");},[r,e,i.id,i.allFields.length]),u=useCallback((m,c)=>{if(!r||!e)return;let s=t.current?.getMetrics(`form_validation_${i.id}`),F={formId:i.id,fieldCount:c||i.allFields.length,timestamp:Date.now(),duration:s?.duration||0,renderDuration:0,validationDuration:s?.duration||0,validationErrors:m,renderCount:o.current};r.track("form_validation",`form_${i.id}`,{formId:i.id,validationErrors:m,fieldCount:c||i.allFields.length},F,m>0?"medium":"low");},[r,e,i.id,i.allFields.length]),p=useCallback((m,c)=>{if(!r||!e)return;let s=t.current?.getMetrics(`form_submission_${i.id}`),F={formId:i.id,fieldCount:c||i.allFields.length,timestamp:Date.now(),duration:s?.duration||0,renderDuration:0,validationDuration:0,validationErrors:m?0:1,renderCount:o.current};r.track("form_submission",`form_${i.id}`,{formId:i.id,success:m,fieldCount:c||i.allFields.length,fieldChanges:d.current},F,m?"low":"high");},[r,e,i.id,i.allFields.length]),g=useCallback((m,c)=>{!r||!e||(d.current++,r.track("component_update",`field_${m}`,{formId:i.id,fieldId:m,componentType:c,changeCount:d.current},void 0,"low"));},[r,e,i.id]),f=useCallback(m=>{!t.current||!e||t.current.start(m,{formId:i.id,renderCount:o.current});},[e,i.id]),n=useCallback(m=>{if(!t.current||!e)return null;let c=t.current.end(m);return c?{...c,formId:i.id,fieldCount:i.allFields.length,renderDuration:c.duration,validationDuration:0,validationErrors:0}:null},[e,i.id,i.allFields.length]);return {trackFormRender:l,trackFormValidation:u,trackFormSubmission:p,trackFieldChange:g,startPerformanceTracking:f,endPerformanceTracking:n}}var Y=createContext(null);function A({children:i,formConfig:e,defaultValues:r={},onSubmit:t,onFieldChange:o,className:d}){let l=useRef(e.id),{formState:u,setValue:p,setFieldTouched:g,reset:f,setError:n,clearError:m,setFieldValidationState:c,setSubmitting:s,isFormValid:F}=W({defaultValues:r,onFieldChange:o}),{fieldConditions:a,hasConditionalFields:h,getFieldCondition:v,isFieldVisible:R,isFieldDisabled:C,isFieldRequired:E,isFieldReadonly:T}=H({formConfig:e,formValues:u.values}),y=useMemo(()=>({hasConditionalFields:h,getFieldCondition:v,isFieldVisible:R,isFieldDisabled:C,isFieldRequired:E,isFieldReadonly:T}),[h,v,R,C,E,T]),{validateField:D,validateForm:_}=K({formConfig:e,formState:u,conditionsHelpers:y,setFieldValidationState:c,setError:n}),{submit:O}=J({formState:u,onSubmit:t,validateForm:_,setSubmitting:s});useEffect(()=>{(l.current===null||e.id!==l.current)&&(l.current=e.id,console.log("resetting form",r),f(r));},[e.id,f]);let L=useMemo(()=>e,[e]),se=useMemo(()=>({formState:u,formConfig:L,fieldConditions:a,conditionsHelpers:y,setValue:p,setFieldTouched:g,validateField:D,validateForm:_,isFormValid:F,reset:f,submit:O,setError:n,clearError:m}),[u,L,a,y,p,g,D,_,F,f,O,n,m]);return jsx(Y.Provider,{value:se,children:jsx("form",{onSubmit:O,className:d,noValidate:true,children:i})})}function b(){let i=useContext(Y);if(!i)throw new Error("useFormContext must be used within a FormProvider");return i}function we({formConfig:i,defaultValues:e,onSubmit:r,onFieldChange:t,children:o}){let d=useMemo(()=>i instanceof V?i.build():i,[i]);return jsx(A,{formConfig:d,defaultValues:e,onSubmit:r,onFieldChange:t,children:o})}var $=Ve.memo(function({fieldId:e,disabled:r=false,customProps:t={},className:o,forceVisible:d=false}){let{formState:l,formConfig:u,setValue:p,setFieldTouched:g,validateField:f,conditionsHelpers:n}=b(),m=u.allFields.find(y=>y.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 s=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]]),F=s.validationState==="validating",a=useMemo(()=>({isVisible:d||n.isFieldVisible(e),isFieldDisabled:r||n.isFieldDisabled(e),isFieldRequired:n.isFieldRequired(e),isFieldReadonly:n.isFieldReadonly(e)}),[d,n.isFieldVisible(e),r,n.isFieldDisabled(e),n.isFieldRequired(e),n.isFieldReadonly(e)]);if(!a.isVisible)return null;let h=useCallback(async y=>{p(e,y),(m.validation?.validateOnChange||s.isTouched)&&await f(e,y);},[e,p,f,m.validation?.validateOnChange,s.isTouched]),v=useCallback(async()=>{s.isTouched||g(e),m.validation?.validateOnBlur!==false&&await f(e);},[e,s.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:s.value,onChange:h,onBlur:v,disabled:a.isFieldDisabled,error:s.errors,isValidating:F,touched:s.isTouched}),[e,R,s.value,h,v,a.isFieldDisabled,s.errors,F,s.isTouched]),E=useMemo(()=>c.renderer(C),[c.renderer,C]),T=useMemo(()=>{let y=u.renderConfig?.fieldRenderer,D=c.useFieldRenderer!==false;return y&&D?y({children:E,id:e,...R,error:s.errors,isValidating:F,touched:s.isTouched}):E},[u.renderConfig?.fieldRenderer,c.useFieldRenderer,E,e,R,s.errors,F,s.isTouched]);return jsx("div",{className:o,"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:T})});var oe=Ve.memo(function({row:e,className:r,...t}){let{formConfig:o}=b(),d=useMemo(()=>e.fields.map(u=>jsx($,{fieldId:u.id},u.id)),[e.fields]),l=useMemo(()=>({row:e,children:d,className:r}),[e,d,r]);return jsx(ComponentRendererWrapper,{name:"FormRow",renderer:o.renderConfig?.rowRenderer,props:l,...t,children:d})}),ie=oe;var Me=Ve.memo(function({className:e,...r}){let{formConfig:t}=b(),o=useMemo(()=>t.rows.map(l=>jsx(ie,{row:l},l.id)),[t.rows]),d=useMemo(()=>({formConfig:t,children:o,className:e}),[t,o,e]);return jsx(ComponentRendererWrapper,{name:"FormBody",renderer:t.renderConfig?.bodyRenderer,props:d,...r,children:o})});var Oe=Ve.memo(function({className:e,isSubmitting:r,...t}){let{formState:o,submit:d,formConfig:l}=b(),u=useMemo(()=>({isSubmitting:r??o.isSubmitting,onSubmit:d,className:e}),[r,o.isSubmitting,d,e]);return jsx(ComponentRendererWrapper,{name:"FormSubmitButton",renderer:l.renderConfig?.submitButtonRenderer,props:u,...t})});export{we as Form,Me as FormBody,V as FormBuilder,$ as FormField,A as FormProvider,oe as FormRow,Oe as FormSubmitButton,V as form,Le as useConditionEvaluation,H as useFormConditions,b as useFormContext,ve as useFormMonitoring,W as useFormState,J as useFormSubmission,K as useFormValidation,G 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,s=e.validation?.validate;if(!i)return s;if(!s)return i;let l=Array.isArray(i)?i:[i],u=Array.isArray(s)?s:[s];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 s=this.createRow([i]);this.rows.push(s);}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(s){return console.warn("Error evaluating condition:",s),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 s=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?s(i.visible):true,disabled:i.disabled?s(i.disabled):false,required:i.required?s(i.required):false,readonly:i.readonly?s(i.readonly):false};}return r},[o,e])}function W({formConfig:o,formValues:e}){let r=useMemo(()=>{let f={};for(let n of o.allFields)n.conditions&&(f[n.id]=n.conditions);return f},[o.allFields]),t=useMemo(()=>Object.keys(r).length>0,[r]),i=H(t?r:{},t?e:{}),s=useCallback(f=>i[f],[i]),l=useCallback(f=>{let n=i[f];return n?n.visible:true},[i]),u=useCallback(f=>{let n=i[f];return n?n.disabled:false},[i]),F=useCallback(f=>{let n=i[f];return n?n.required:false},[i]),g=useCallback(f=>{let n=i[f];return n?n.readonly:false},[i]);return useMemo(()=>({fieldConditions:i,hasConditionalFields:t,getFieldCondition:s,isFieldVisible:l,isFieldDisabled:u,isFieldRequired:F,isFieldReadonly:g}),[i,t,s,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),s=useRef(e);s.current=e;let l=useCallback((d,p)=>{i({type:"SET_VALUE",fieldId:d,value:p}),s.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});},[]),n=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:n,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 s=useRef(o),l=useRef(r),u=useRef(t),F=useRef(i);s.current=o,l.current=r,u.current=t,F.current=i;let g=useCallback(async(n,m)=>{let c=s.current.allFields.find(a=>a.id===n);if(!c)return B();if(!l.current.isFieldVisible(n))return F.current(n,[]),u.current(n,"valid"),B();if(!c.validation||!hasUnifiedValidation(c.validation))return F.current(n,[]),u.current(n,"valid"),B();let d=m!==void 0?m:e.values[n],p=createValidationContext({fieldId:n,formId:s.current.id,allFormData:{...e.values,[n]:d}});u.current(n,"validating");try{let a=await validateWithUnifiedConfig(c.validation,d,p),h=l.current.isFieldRequired(n),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(n,C.errors),u.current(n,"invalid"),C}return F.current(n,a.errors),u.current(n,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(n,h.errors),u.current(n,"invalid"),h}},[e.values]),f=useCallback(async()=>{let n=s.current.allFields.filter(a=>{let h=l.current.isFieldVisible(a.id),v=a.validation&&hasUnifiedValidation(a.validation);return h&&v}),m=s.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(n.map(a=>g(a.id))),d=c.some(a=>!a.isValid),p=B();if(s.current.validation&&hasUnifiedValidation(s.current.validation)){let a=Object.keys(e.values).reduce((v,R)=>(l.current.isFieldVisible(R)&&(v[R]=e.values[R]),v),{}),h=createValidationContext({formId:s.current.id,allFormData:a});try{p=await validateFormWithUnifiedConfig(s.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),s=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:s.current},p,m?"low":"high");},[r,e,o.id,o.allFields.length]),g=useCallback((m,c)=>{!r||!e||(s.current++,r.track("component_update",`field_${m}`,{formId:o.id,fieldId:m,componentType:c,changeCount:s.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]),n=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:n}}var Y=createContext(null);function $({children:o,formConfig:e,defaultValues:r={},onSubmit:t,onFieldChange:i,className:s}){let l=useRef(e.id),{formState:u,setValue:F,setFieldTouched:g,reset:f,setError:n,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:n}),{submit:O}=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:O,setError:n,clearError:m}),[u,N,a,P,F,g,D,b,p,f,O,n,m]);return jsx(Y.Provider,{value:se,children:jsx("form",{onSubmit:O,className:s,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 s=useMemo(()=>o instanceof E?o.build():o,[o]);return jsx($,{formConfig:s,defaultValues:e,onSubmit:r,onFieldChange:t,children:i})}var L=xe.memo(function({fieldId:e,disabled:r=false,customProps:t={},className:i,forceVisible:s=false}){let{formState:l,formConfig:u,setValue:F,setFieldTouched:g,validateField:f,conditionsHelpers:n}=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:s||n.isFieldVisible(e),isFieldDisabled:r||n.isFieldDisabled(e),isFieldRequired:n.isFieldRequired(e),isFieldReadonly:n.isFieldReadonly(e)}),[s,n.isFieldVisible(e),r,n.isFieldDisabled(e),n.isFieldRequired(e),n.isFieldReadonly(e)]);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(),s=useMemo(()=>e.fields.map(u=>jsx(L,{fieldId:u.id},u.id)),[e.fields]),l=useMemo(()=>({row:e,children:s,className:r}),[e,s,r]);return jsx(ComponentRendererWrapper,{name:"FormRow",renderer:i.renderConfig?.rowRenderer,props:l,...t,children:s})}),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]),s=useMemo(()=>({formConfig:t,children:i,className:e}),[t,i,e]);return jsx(ComponentRendererWrapper,{name:"FormBody",renderer:t.renderConfig?.bodyRenderer,props:s,...r,children:i})});var Ue=xe.memo(function({className:e,isSubmitting:r,...t}){let{formState:i,submit:s,formConfig:l}=y(),u=useMemo(()=>({isSubmitting:r??i.isSubmitting,onSubmit:s,className:e}),[r,i.isSubmitting,s,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": "9.0.1",
3
+ "version": "11.0.0",
4
4
  "description": "Form building utilities and components for RilayKit",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -32,7 +32,7 @@
32
32
  "url": "https://github.com/andyoucreate/rilay/issues"
33
33
  },
34
34
  "dependencies": {
35
- "@rilaykit/core": "9.0.1"
35
+ "@rilaykit/core": "11.0.0"
36
36
  },
37
37
  "peerDependencies": {
38
38
  "react": ">=18.0.0",