@rilaykit/forms 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
'use strict';var er=require('react'),jsxRuntime=require('react/jsx-runtime'),core=require('@rilaykit/core');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var er__default=/*#__PURE__*/_interopDefault(er);function j(i,r){switch(r.type){case "SET_VALUE":{let o={...i.values,[r.fieldId]:r.value};return {...i,values:o,isDirty:true}}case "SET_ERROR":return {...i,errors:{...i.errors,[r.fieldId]:r.errors},isValid:false};case "SET_WARNING":return {...i,warnings:{...i.warnings,[r.fieldId]:r.warnings}};case "CLEAR_ERROR":{let o={...i.errors};return delete o[r.fieldId],{...i,errors:o}}case "CLEAR_WARNING":{let o={...i.warnings};return delete o[r.fieldId],{...i,warnings:o}}case "MARK_TOUCHED":return {...i,touched:new Set([...i.touched,r.fieldId])};case "SET_VALIDATING":{let o=new Set(i.isValidating);return r.isValidating?o.add(r.fieldId):o.delete(r.fieldId),{...i,isValidating:o}}case "SET_SUBMITTING":return {...i,isSubmitting:r.isSubmitting};case "RESET":return {values:r.values||{},errors:{},warnings:{},touched:new Set,isValidating:new Set,isDirty:false,isValid:true,isSubmitting:false};case "UPDATE_VALIDATION_STATE":{let o=Object.keys(i.errors).some(s=>i.errors[s].length>0);return {...i,isValid:!o}}default:return i}}var U=er.createContext(null);function _({children:i,formConfig:r,defaultValues:o={},onSubmit:s,onFieldChange:e,className:a}){let m={values:o,errors:{},warnings:{},touched:new Set,isValidating:new Set,isDirty:false,isValid:true,isSubmitting:false},[d,l]=er.useReducer(j,m),t=er.useRef(new Map),h=er.useRef(s),f=er.useRef(e);h.current=s,f.current=e;let R=er.useCallback((n,c)=>{l({type:"SET_ERROR",fieldId:n,errors:c}),l({type:"UPDATE_VALIDATION_STATE"});},[]),E=er.useCallback((n,c)=>{l({type:"SET_WARNING",fieldId:n,warnings:c});},[]),y=er.useCallback(n=>{l({type:"CLEAR_ERROR",fieldId:n}),l({type:"UPDATE_VALIDATION_STATE"});},[]),w=er.useCallback(n=>{l({type:"CLEAR_WARNING",fieldId:n});},[]),P=er.useCallback(n=>{l({type:"MARK_TOUCHED",fieldId:n});},[]),S=er.useCallback((n,c)=>{l({type:"SET_VALIDATING",fieldId:n,isValidating:c});},[]),F=er.useCallback((n,c)=>{if(l({type:"SET_VALUE",fieldId:n,value:c}),d.errors[n]&&d.errors[n].length>0&&(l({type:"CLEAR_ERROR",fieldId:n}),l({type:"UPDATE_VALIDATION_STATE"})),f.current){let u={...d.values,[n]:c};f.current(n,c,u);}},[d.errors,d.values]),v=er.useMemo(()=>r,[r]),b=er.useCallback(async(n,c)=>{let u=v.allFields.find(T=>T.id===n);if(!u?.validation?.validator)return {isValid:true,errors:[]};let z=c!==void 0?c:d.values[n],B=t.current.get(n);B&&clearTimeout(B);let Z={fieldId:n,formData:d.values,fieldProps:u.props,touched:d.touched.has(n),dirty:d.isDirty},O=u.validation.debounceMs||0;return new Promise(T=>{let L=async()=>{S(n,true);try{let g=await u.validation.validator(z,Z,u.props);g.errors.length>0?R(n,g.errors):y(n),g.warnings&&g.warnings.length>0?E(n,g.warnings):w(n),T(g);}catch(g){let M={isValid:false,errors:[{code:"validation_error",message:g instanceof Error?g.message:"Validation error"}]};R(n,M.errors),T(M);}finally{S(n,false);}};if(O>0){let g=setTimeout(L,O);t.current.set(n,g);}else L();})},[v,d.values,d.touched,d.isDirty,R,E,y,w,S]),I=er.useCallback(async()=>{let n=v.allFields.map(u=>b(u.id));return (await Promise.all(n)).every(u=>u.isValid)},[v,b]),D=er.useCallback(n=>{l({type:"RESET",values:n});},[]),A=er.useCallback(async n=>{if(n?.preventDefault(),!h.current)return true;l({type:"SET_SUBMITTING",isSubmitting:true});try{return await I()?(await h.current(d.values),!0):!1}catch(c){return console.error("Error during form submission:",c),false}finally{l({type:"SET_SUBMITTING",isSubmitting:false});}},[d.values,I]),K=er.useMemo(()=>({formState:d,formConfig:v,setValue:F,setError:R,setWarning:E,clearError:y,clearWarning:w,markFieldTouched:P,setFieldValidating:S,validateField:b,validateAllFields:I,reset:D,submit:A}),[d,v,F,R,E,y,w,P,S,b,I,D,A]);return jsxRuntime.jsx(U.Provider,{value:K,children:jsxRuntime.jsx("form",{onSubmit:A,className:a,noValidate:true,children:i})})}function C(){let i=er.useContext(U);if(!i)throw new Error("useFormContext must be used within a FormProvider");return i}function rr({formConfig:i,defaultValues:r,onSubmit:o,onFieldChange:s,children:e}){return jsxRuntime.jsx(_,{formConfig:i,defaultValues:r,onSubmit:o,onFieldChange:s,className:"streamline-form",children:e})}function W({fieldId:i,disabled:r=false,customProps:o={},className:s}){let{formState:e,formConfig:a,setValue:m,markFieldTouched:d,validateField:l}=C(),t=er.useMemo(()=>a.allFields.find(F=>F.id===i),[a.allFields,i]);if(!t)throw new Error(`Field with ID "${i}" not found`);let h=er.useMemo(()=>a.config.getComponent(t.componentId),[a.config,t.componentId]);if(!h)throw new Error(`Component with ID "${t.componentId}" not found`);let f=er.useMemo(()=>({value:e.values[t.id],errors:e.errors[t.id]||[],warnings:e.warnings[t.id]||[],touched:e.touched.has(t.id),validating:e.isValidating.has(t.id)}),[e.values,e.errors,e.warnings,e.touched,e.isValidating,t.id]),R=er.useCallback(F=>{let v=f.errors.length>0;m(t.id,F),(t.validation?.validateOnChange||v&&t.validation?.validator||f.touched&&t.validation?.validator)&&l(t.id,F);},[t.id,t.validation,m,l,f.errors.length,f.touched]),E=er.useCallback(()=>{d(t.id),(t.validation?.validateOnBlur||t.validation?.validator)&&l(t.id);},[t.id,t.validation,d,l]),y=er.useMemo(()=>{if(!t.conditional)return true;try{return t.conditional.condition(e.values)}catch(F){return console.warn(`Conditional evaluation failed for field "${t.id}":`,F),true}},[t.conditional,e.values,t.id]),w=er.useMemo(()=>{if(!t.conditional||!y)return {};switch(t.conditional.action){case "disable":return {disabled:true};case "require":return {required:true};default:return {}}},[t.conditional,y]);if(!y&&t.conditional?.action==="hide")return null;let P=er.useMemo(()=>({...h.defaultProps,...t.props,...o,...w}),[h.defaultProps,t.props,o,w]),S=er.useMemo(()=>({id:t.id,props:P,value:f.value,onChange:R,onBlur:E,error:f.errors,warnings:f.warnings,touched:f.touched,disabled:r||w.disabled,isValidating:f.validating}),[t.id,P,f.value,R,E,f.errors,f.warnings,f.touched,r,w.disabled,f.validating]);return jsxRuntime.jsx("div",{className:s,"data-field-id":t.id,"data-field-type":h.type,children:h.renderer(S)})}var q=er__default.default.memo(W);function H({row:i,className:r}){let{formConfig:o}=C(),s=o.renderConfig?.rowRenderer;if(!s)throw new Error(`No rowRenderer configured for form "${o.id}". Please configure a rowRenderer using config.setRowRenderer() or config.setFormRenderConfig().`);let e=i.fields.map(m=>jsxRuntime.jsx(q,{fieldId:m.id},m.id)),a={row:i,children:e,className:r,spacing:i.spacing,alignment:i.alignment};return s(a)}var J=H;function sr({className:i}){let{formConfig:r}=C(),o=r.renderConfig?.bodyRenderer;if(!o)throw new Error(`No bodyRenderer configured for form "${r.id}". Please configure a bodyRenderer using config.setBodyRenderer() or config.setFormRenderConfig().`);let s=er.useMemo(()=>r.rows.map(a=>jsxRuntime.jsx(J,{row:a},a.id)),[r.rows]);return o({formConfig:r,children:s,className:i})}function dr({className:i,children:r}){let{formState:o,submit:s,formConfig:e}=C(),a=e.renderConfig?.submitButtonRenderer;if(!a)throw new Error(`No submitButtonRenderer configured for form "${e.id}". Please configure a submitButtonRenderer using config.setSubmitButtonRenderer() or config.setFormRenderConfig().`);let m={isSubmitting:o.isSubmitting,isValid:o.isValid,isDirty:o.isDirty,onSubmit:s,className:i,children:r};return a(m)}var x=class i{constructor(r,o){this.rows=[];this.rowCounter=0;this.config=r,this.formId=o||`form-${Date.now()}`;}static create(r,o){return new i(r,o)}addField(r,o,s={},e){return this.addRowFields([{fieldId:r,componentType:o,props:s,validation:e?.validation,conditional:e?.conditional}])}addRowFields(r,o){if(r.length===0)throw new Error("At least one field is required");if(r.length>3)throw new Error("Maximum 3 fields per row");let s=`row-${++this.rowCounter}`,e=[];for(let m of r){let d=this.config.getComponent(m.componentType);if(!d)throw new Error(`No component found with type "${m.componentType}"`);let l={id:m.fieldId,componentId:d.id,props:{...d.defaultProps,...m.props},validation:m.validation,conditional:m.conditional};e.push(l);}let a={id:s,fields:e,maxColumns:r.length,spacing:o?.spacing||"normal",alignment:o?.alignment||"stretch"};return this.rows.push(a),this}addFields(r){for(let o of r)this.addField(o.fieldId,o.componentType,o.props,{validation:o.validation,conditional:o.conditional});return this}setId(r){return this.formId=r,this}updateField(r,o){let s=false;for(let e of this.rows){let a=e.fields.findIndex(m=>m.id===r);a!==-1&&(e.fields[a]={...e.fields[a],...o,props:{...e.fields[a].props,...o.props}},s=true);}if(!s)throw new Error(`Field with ID "${r}" not found`);return this}removeField(r){for(let o of this.rows){let s=o.fields.filter(e=>e.id!==r);Object.assign(o,{fields:s});}return this.rows=this.rows.filter(o=>o.fields.length>0),this}getField(r){for(let o of this.rows){let s=o.fields.find(e=>e.id===r);if(s)return s}}getFields(){return this.rows.flatMap(r=>r.fields)}getRows(){return [...this.rows]}clear(){return this.rows=[],this.rowCounter=0,this}clone(r){let o=new i(this.config,r);return o.rows=this.rows.map(s=>({...s,fields:s.fields.map(e=>({...e}))})),o.rowCounter=this.rowCounter,o}validate(){let r=[],o=this.getFields(),s=o.map(a=>a.id),e=s.filter((a,m)=>s.indexOf(a)!==m);e.length>0&&r.push(`Duplicate field IDs: ${e.join(", ")}`);for(let a of o)this.config.hasComponent(a.componentId)||r.push(`Component "${a.componentId}" not found for field "${a.id}"`);for(let a of this.rows)a.fields.length>3&&r.push(`Row "${a.id}" has ${a.fields.length} fields, maximum is 3`),a.fields.length===0&&r.push(`Row "${a.id}" is empty`);return r}build(){let r=this.validate();if(r.length>0)throw new Error(`Form validation failed: ${r.join(", ")}`);return {id:this.formId,rows:[...this.rows],allFields:this.getFields(),config:this.config,renderConfig:this.config.getFormRenderConfig()}}toJSON(){return {id:this.formId,rows:this.rows}}fromJSON(r){return r.id&&(this.formId=r.id),r.rows&&(this.rows=r.rows,this.rowCounter=this.rows.length),this}getStats(){let r=this.getFields(),o=this.rows.map(s=>s.fields.length);return {totalFields:r.length,totalRows:this.rows.length,averageFieldsPerRow:this.rows.length>0?r.length/this.rows.length:0,maxFieldsInRow:o.length>0?Math.max(...o):0,minFieldsInRow:o.length>0?Math.min(...o):0}}};Object.defineProperty(exports,"createZodValidator",{enumerable:true,get:function(){return core.createZodValidator}});Object.defineProperty(exports,"ril",{enumerable:true,get:function(){return core.ril}});exports.Form=rr;exports.FormBody=sr;exports.FormBuilder=x;exports.FormField=W;exports.FormProvider=_;exports.FormRow=H;exports.FormSubmitButton=dr;exports.form=x;exports.useFormContext=C;
|
|
1
|
+
'use strict';var er=require('react'),jsxRuntime=require('react/jsx-runtime'),core=require('@rilaykit/core');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var er__default=/*#__PURE__*/_interopDefault(er);function j(i,r){switch(r.type){case "SET_VALUE":{let o={...i.values,[r.fieldId]:r.value};return {...i,values:o,isDirty:true}}case "SET_ERROR":return {...i,errors:{...i.errors,[r.fieldId]:r.errors},isValid:false};case "SET_WARNING":return {...i,warnings:{...i.warnings,[r.fieldId]:r.warnings}};case "CLEAR_ERROR":{let o={...i.errors};return delete o[r.fieldId],{...i,errors:o}}case "CLEAR_WARNING":{let o={...i.warnings};return delete o[r.fieldId],{...i,warnings:o}}case "MARK_TOUCHED":return {...i,touched:new Set([...i.touched,r.fieldId])};case "SET_VALIDATING":{let o=new Set(i.isValidating);return r.isValidating?o.add(r.fieldId):o.delete(r.fieldId),{...i,isValidating:o}}case "SET_SUBMITTING":return {...i,isSubmitting:r.isSubmitting};case "RESET":return {values:r.values||{},errors:{},warnings:{},touched:new Set,isValidating:new Set,isDirty:false,isValid:true,isSubmitting:false};case "UPDATE_VALIDATION_STATE":{let o=Object.keys(i.errors).some(d=>i.errors[d].length>0);return {...i,isValid:!o}}default:return i}}var U=er.createContext(null);function D({children:i,formConfig:r,defaultValues:o={},onSubmit:d,onFieldChange:e,className:s}){let f={values:o,errors:{},warnings:{},touched:new Set,isValidating:new Set,isDirty:false,isValid:true,isSubmitting:false},[a,m]=er.useReducer(j,f),t=er.useRef(new Map),F=er.useRef(d),l=er.useRef(e);F.current=d,l.current=e;let y=er.useCallback((n,c)=>{m({type:"SET_ERROR",fieldId:n,errors:c}),m({type:"UPDATE_VALIDATION_STATE"});},[]),E=er.useCallback((n,c)=>{m({type:"SET_WARNING",fieldId:n,warnings:c});},[]),v=er.useCallback(n=>{m({type:"CLEAR_ERROR",fieldId:n}),m({type:"UPDATE_VALIDATION_STATE"});},[]),h=er.useCallback(n=>{m({type:"CLEAR_WARNING",fieldId:n});},[]),P=er.useCallback(n=>{m({type:"MARK_TOUCHED",fieldId:n});},[]),S=er.useCallback((n,c)=>{m({type:"SET_VALIDATING",fieldId:n,isValidating:c});},[]),T=er.useCallback((n,c)=>{if(m({type:"SET_VALUE",fieldId:n,value:c}),a.errors[n]&&a.errors[n].length>0&&(m({type:"CLEAR_ERROR",fieldId:n}),m({type:"UPDATE_VALIDATION_STATE"})),l.current){let u={...a.values,[n]:c};l.current(n,c,u);}},[a.errors,a.values]),R=er.useMemo(()=>r,[r]),b=er.useCallback(async(n,c)=>{let u=R.allFields.find(A=>A.id===n);if(!u?.validation?.validator)return {isValid:true,errors:[]};let z=c!==void 0?c:a.values[n],B=t.current.get(n);B&&clearTimeout(B);let Z={fieldId:n,formData:a.values,fieldProps:u.props,touched:a.touched.has(n),dirty:a.isDirty},O=u.validation.debounceMs||0;return new Promise(A=>{let L=async()=>{S(n,true);try{let g=await u.validation.validator(z,Z,u.props);g.errors.length>0?y(n,g.errors):v(n),g.warnings&&g.warnings.length>0?E(n,g.warnings):h(n),A(g);}catch(g){let M={isValid:false,errors:[{code:"validation_error",message:g instanceof Error?g.message:"Validation error"}]};y(n,M.errors),A(M);}finally{S(n,false);}};if(O>0){let g=setTimeout(L,O);t.current.set(n,g);}else L();})},[R,a.values,a.touched,a.isDirty,y,E,v,h,S]),I=er.useCallback(async()=>{let n=R.allFields.map(u=>b(u.id));return (await Promise.all(n)).every(u=>u.isValid)},[R,b]),w=er.useCallback(n=>{m({type:"RESET",values:n});},[]),x=er.useCallback(async n=>{if(n?.preventDefault(),!F.current)return true;m({type:"SET_SUBMITTING",isSubmitting:true});try{return await I()?(await F.current(a.values),!0):!1}catch(c){return console.error("Error during form submission:",c),false}finally{m({type:"SET_SUBMITTING",isSubmitting:false});}},[a.values,I]),K=er.useMemo(()=>({formState:a,formConfig:R,setValue:T,setError:y,setWarning:E,clearError:v,clearWarning:h,markFieldTouched:P,setFieldValidating:S,validateField:b,validateAllFields:I,reset:w,submit:x}),[a,R,T,y,E,v,h,P,S,b,I,w,x]);return jsxRuntime.jsx(U.Provider,{value:K,children:jsxRuntime.jsx("form",{onSubmit:x,className:s,noValidate:true,children:i})})}function C(){let i=er.useContext(U);if(!i)throw new Error("useFormContext must be used within a FormProvider");return i}function rr({formConfig:i,defaultValues:r,onSubmit:o,onFieldChange:d,children:e}){return jsxRuntime.jsx(D,{formConfig:i,defaultValues:r,onSubmit:o,onFieldChange:d,className:"streamline-form",children:e})}function W({fieldId:i,disabled:r=false,customProps:o={},className:d}){let{formState:e,formConfig:s,setValue:f,markFieldTouched:a,validateField:m}=C(),t=er.useMemo(()=>s.allFields.find(w=>w.id===i),[s.allFields,i]);if(!t)throw new Error(`Field with ID "${i}" not found`);let F=er.useMemo(()=>s.config.getComponent(t.componentId),[s.config,t.componentId]);if(!F)throw new Error(`Component with ID "${t.componentId}" not found`);let l=er.useMemo(()=>({value:e.values[t.id],errors:e.errors[t.id]||[],warnings:e.warnings[t.id]||[],touched:e.touched.has(t.id),validating:e.isValidating.has(t.id)}),[e.values,e.errors,e.warnings,e.touched,e.isValidating,t.id]),y=er.useCallback(w=>{let x=l.errors.length>0;f(t.id,w),(t.validation?.validateOnChange||x&&t.validation?.validator||l.touched&&t.validation?.validator)&&m(t.id,w);},[t.id,t.validation,f,m,l.errors.length,l.touched]),E=er.useCallback(()=>{a(t.id),(t.validation?.validateOnBlur||t.validation?.validator)&&m(t.id);},[t.id,t.validation,a,m]),v=er.useMemo(()=>{if(!t.conditional)return true;try{return t.conditional.condition(e.values)}catch(w){return console.warn(`Conditional evaluation failed for field "${t.id}":`,w),true}},[t.conditional,e.values,t.id]),h=er.useMemo(()=>{if(!t.conditional||!v)return {};switch(t.conditional.action){case "disable":return {disabled:true};case "require":return {required:true};default:return {}}},[t.conditional,v]);if(!v&&t.conditional?.action==="hide")return null;let P=er.useMemo(()=>({...F.defaultProps,...t.props,...o,...h}),[F.defaultProps,t.props,o,h]),S=er.useMemo(()=>({id:t.id,props:P,value:l.value,onChange:y,onBlur:E,error:l.errors,warnings:l.warnings,touched:l.touched,disabled:r||h.disabled,isValidating:l.validating}),[t.id,P,l.value,y,E,l.errors,l.warnings,l.touched,r,h.disabled,l.validating]),T=s.renderConfig?.fieldRenderer,R=F.renderer(S),b=F.useFieldRenderer!==false,I=T&&b?T({children:R,id:t.id,error:l.errors,warnings:l.warnings,touched:l.touched,disabled:r||h.disabled,isValidating:l.validating,...P}):R;return jsxRuntime.jsx("div",{className:d,"data-field-id":t.id,"data-field-type":F.type,children:I})}var q=er__default.default.memo(W);function H({row:i,className:r}){let{formConfig:o}=C(),d=o.renderConfig?.rowRenderer;if(!d)throw new Error(`No rowRenderer configured for form "${o.id}". Please configure a rowRenderer using config.setRowRenderer() or config.setFormRenderConfig().`);let e=i.fields.map(f=>jsxRuntime.jsx(q,{fieldId:f.id},f.id)),s={row:i,children:e,className:r,spacing:i.spacing,alignment:i.alignment};return d(s)}var J=H;function sr({className:i}){let{formConfig:r}=C(),o=r.renderConfig?.bodyRenderer;if(!o)throw new Error(`No bodyRenderer configured for form "${r.id}". Please configure a bodyRenderer using config.setBodyRenderer() or config.setFormRenderConfig().`);let d=er.useMemo(()=>r.rows.map(s=>jsxRuntime.jsx(J,{row:s},s.id)),[r.rows]);return o({formConfig:r,children:d,className:i})}function ar({className:i,children:r}){let{formState:o,submit:d,formConfig:e}=C(),s=e.renderConfig?.submitButtonRenderer;if(!s)throw new Error(`No submitButtonRenderer configured for form "${e.id}". Please configure a submitButtonRenderer using config.setSubmitButtonRenderer() or config.setFormRenderConfig().`);let f={isSubmitting:o.isSubmitting,isValid:o.isValid,isDirty:o.isDirty,onSubmit:d,className:i,children:r};return s(f)}var N=class i{constructor(r,o){this.rows=[];this.rowCounter=0;this.config=r,this.formId=o||`form-${Date.now()}`;}static create(r,o){return new i(r,o)}addField(r,o,d={},e){return this.addRowFields([{fieldId:r,componentType:o,props:d,validation:e?.validation,conditional:e?.conditional}])}addRowFields(r,o){if(r.length===0)throw new Error("At least one field is required");if(r.length>3)throw new Error("Maximum 3 fields per row");let d=`row-${++this.rowCounter}`,e=[];for(let f of r){let a=this.config.getComponent(f.componentType);if(!a)throw new Error(`No component found with type "${f.componentType}"`);let m={id:f.fieldId,componentId:a.id,props:{...a.defaultProps,...f.props},validation:f.validation,conditional:f.conditional};e.push(m);}let s={id:d,fields:e,maxColumns:r.length,spacing:o?.spacing||"normal",alignment:o?.alignment||"stretch"};return this.rows.push(s),this}addFields(r){for(let o of r)this.addField(o.fieldId,o.componentType,o.props,{validation:o.validation,conditional:o.conditional});return this}setId(r){return this.formId=r,this}updateField(r,o){let d=false;for(let e of this.rows){let s=e.fields.findIndex(f=>f.id===r);s!==-1&&(e.fields[s]={...e.fields[s],...o,props:{...e.fields[s].props,...o.props}},d=true);}if(!d)throw new Error(`Field with ID "${r}" not found`);return this}removeField(r){for(let o of this.rows){let d=o.fields.filter(e=>e.id!==r);Object.assign(o,{fields:d});}return this.rows=this.rows.filter(o=>o.fields.length>0),this}getField(r){for(let o of this.rows){let d=o.fields.find(e=>e.id===r);if(d)return d}}getFields(){return this.rows.flatMap(r=>r.fields)}getRows(){return [...this.rows]}clear(){return this.rows=[],this.rowCounter=0,this}clone(r){let o=new i(this.config,r);return o.rows=this.rows.map(d=>({...d,fields:d.fields.map(e=>({...e}))})),o.rowCounter=this.rowCounter,o}validate(){let r=[],o=this.getFields(),d=o.map(s=>s.id),e=d.filter((s,f)=>d.indexOf(s)!==f);e.length>0&&r.push(`Duplicate field IDs: ${e.join(", ")}`);for(let s of o)this.config.hasComponent(s.componentId)||r.push(`Component "${s.componentId}" not found for field "${s.id}"`);for(let s of this.rows)s.fields.length>3&&r.push(`Row "${s.id}" has ${s.fields.length} fields, maximum is 3`),s.fields.length===0&&r.push(`Row "${s.id}" is empty`);return r}build(){let r=this.validate();if(r.length>0)throw new Error(`Form validation failed: ${r.join(", ")}`);return {id:this.formId,rows:[...this.rows],allFields:this.getFields(),config:this.config,renderConfig:this.config.getFormRenderConfig()}}toJSON(){return {id:this.formId,rows:this.rows}}fromJSON(r){return r.id&&(this.formId=r.id),r.rows&&(this.rows=r.rows,this.rowCounter=this.rows.length),this}getStats(){let r=this.getFields(),o=this.rows.map(d=>d.fields.length);return {totalFields:r.length,totalRows:this.rows.length,averageFieldsPerRow:this.rows.length>0?r.length/this.rows.length:0,maxFieldsInRow:o.length>0?Math.max(...o):0,minFieldsInRow:o.length>0?Math.min(...o):0}}};Object.defineProperty(exports,"createZodValidator",{enumerable:true,get:function(){return core.createZodValidator}});Object.defineProperty(exports,"ril",{enumerable:true,get:function(){return core.ril}});exports.Form=rr;exports.FormBody=sr;exports.FormBuilder=N;exports.FormField=W;exports.FormProvider=D;exports.FormRow=H;exports.FormSubmitButton=ar;exports.form=N;exports.useFormContext=C;
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import er,{createContext,useMemo,useCallback,useContext,useReducer,useRef}from'react';import {jsx}from'react/jsx-runtime';export{createZodValidator,ril}from'@rilaykit/core';function j(i,r){switch(r.type){case "SET_VALUE":{let o={...i.values,[r.fieldId]:r.value};return {...i,values:o,isDirty:true}}case "SET_ERROR":return {...i,errors:{...i.errors,[r.fieldId]:r.errors},isValid:false};case "SET_WARNING":return {...i,warnings:{...i.warnings,[r.fieldId]:r.warnings}};case "CLEAR_ERROR":{let o={...i.errors};return delete o[r.fieldId],{...i,errors:o}}case "CLEAR_WARNING":{let o={...i.warnings};return delete o[r.fieldId],{...i,warnings:o}}case "MARK_TOUCHED":return {...i,touched:new Set([...i.touched,r.fieldId])};case "SET_VALIDATING":{let o=new Set(i.isValidating);return r.isValidating?o.add(r.fieldId):o.delete(r.fieldId),{...i,isValidating:o}}case "SET_SUBMITTING":return {...i,isSubmitting:r.isSubmitting};case "RESET":return {values:r.values||{},errors:{},warnings:{},touched:new Set,isValidating:new Set,isDirty:false,isValid:true,isSubmitting:false};case "UPDATE_VALIDATION_STATE":{let o=Object.keys(i.errors).some(s=>i.errors[s].length>0);return {...i,isValid:!o}}default:return i}}var U=createContext(null);function _({children:i,formConfig:r,defaultValues:o={},onSubmit:s,onFieldChange:e,className:a}){let m={values:o,errors:{},warnings:{},touched:new Set,isValidating:new Set,isDirty:false,isValid:true,isSubmitting:false},[d,l]=useReducer(j,m),t=useRef(new Map),h=useRef(s),f=useRef(e);h.current=s,f.current=e;let R=useCallback((n,c)=>{l({type:"SET_ERROR",fieldId:n,errors:c}),l({type:"UPDATE_VALIDATION_STATE"});},[]),E=useCallback((n,c)=>{l({type:"SET_WARNING",fieldId:n,warnings:c});},[]),y=useCallback(n=>{l({type:"CLEAR_ERROR",fieldId:n}),l({type:"UPDATE_VALIDATION_STATE"});},[]),w=useCallback(n=>{l({type:"CLEAR_WARNING",fieldId:n});},[]),P=useCallback(n=>{l({type:"MARK_TOUCHED",fieldId:n});},[]),S=useCallback((n,c)=>{l({type:"SET_VALIDATING",fieldId:n,isValidating:c});},[]),F=useCallback((n,c)=>{if(l({type:"SET_VALUE",fieldId:n,value:c}),d.errors[n]&&d.errors[n].length>0&&(l({type:"CLEAR_ERROR",fieldId:n}),l({type:"UPDATE_VALIDATION_STATE"})),f.current){let u={...d.values,[n]:c};f.current(n,c,u);}},[d.errors,d.values]),v=useMemo(()=>r,[r]),b=useCallback(async(n,c)=>{let u=v.allFields.find(T=>T.id===n);if(!u?.validation?.validator)return {isValid:true,errors:[]};let z=c!==void 0?c:d.values[n],B=t.current.get(n);B&&clearTimeout(B);let Z={fieldId:n,formData:d.values,fieldProps:u.props,touched:d.touched.has(n),dirty:d.isDirty},O=u.validation.debounceMs||0;return new Promise(T=>{let L=async()=>{S(n,true);try{let g=await u.validation.validator(z,Z,u.props);g.errors.length>0?R(n,g.errors):y(n),g.warnings&&g.warnings.length>0?E(n,g.warnings):w(n),T(g);}catch(g){let M={isValid:false,errors:[{code:"validation_error",message:g instanceof Error?g.message:"Validation error"}]};R(n,M.errors),T(M);}finally{S(n,false);}};if(O>0){let g=setTimeout(L,O);t.current.set(n,g);}else L();})},[v,d.values,d.touched,d.isDirty,R,E,y,w,S]),I=useCallback(async()=>{let n=v.allFields.map(u=>b(u.id));return (await Promise.all(n)).every(u=>u.isValid)},[v,b]),D=useCallback(n=>{l({type:"RESET",values:n});},[]),A=useCallback(async n=>{if(n?.preventDefault(),!h.current)return true;l({type:"SET_SUBMITTING",isSubmitting:true});try{return await I()?(await h.current(d.values),!0):!1}catch(c){return console.error("Error during form submission:",c),false}finally{l({type:"SET_SUBMITTING",isSubmitting:false});}},[d.values,I]),K=useMemo(()=>({formState:d,formConfig:v,setValue:F,setError:R,setWarning:E,clearError:y,clearWarning:w,markFieldTouched:P,setFieldValidating:S,validateField:b,validateAllFields:I,reset:D,submit:A}),[d,v,F,R,E,y,w,P,S,b,I,D,A]);return jsx(U.Provider,{value:K,children:jsx("form",{onSubmit:A,className:a,noValidate:true,children:i})})}function C(){let i=useContext(U);if(!i)throw new Error("useFormContext must be used within a FormProvider");return i}function rr({formConfig:i,defaultValues:r,onSubmit:o,onFieldChange:s,children:e}){return jsx(_,{formConfig:i,defaultValues:r,onSubmit:o,onFieldChange:s,className:"streamline-form",children:e})}function W({fieldId:i,disabled:r=false,customProps:o={},className:s}){let{formState:e,formConfig:a,setValue:m,markFieldTouched:d,validateField:l}=C(),t=useMemo(()=>a.allFields.find(F=>F.id===i),[a.allFields,i]);if(!t)throw new Error(`Field with ID "${i}" not found`);let h=useMemo(()=>a.config.getComponent(t.componentId),[a.config,t.componentId]);if(!h)throw new Error(`Component with ID "${t.componentId}" not found`);let f=useMemo(()=>({value:e.values[t.id],errors:e.errors[t.id]||[],warnings:e.warnings[t.id]||[],touched:e.touched.has(t.id),validating:e.isValidating.has(t.id)}),[e.values,e.errors,e.warnings,e.touched,e.isValidating,t.id]),R=useCallback(F=>{let v=f.errors.length>0;m(t.id,F),(t.validation?.validateOnChange||v&&t.validation?.validator||f.touched&&t.validation?.validator)&&l(t.id,F);},[t.id,t.validation,m,l,f.errors.length,f.touched]),E=useCallback(()=>{d(t.id),(t.validation?.validateOnBlur||t.validation?.validator)&&l(t.id);},[t.id,t.validation,d,l]),y=useMemo(()=>{if(!t.conditional)return true;try{return t.conditional.condition(e.values)}catch(F){return console.warn(`Conditional evaluation failed for field "${t.id}":`,F),true}},[t.conditional,e.values,t.id]),w=useMemo(()=>{if(!t.conditional||!y)return {};switch(t.conditional.action){case "disable":return {disabled:true};case "require":return {required:true};default:return {}}},[t.conditional,y]);if(!y&&t.conditional?.action==="hide")return null;let P=useMemo(()=>({...h.defaultProps,...t.props,...o,...w}),[h.defaultProps,t.props,o,w]),S=useMemo(()=>({id:t.id,props:P,value:f.value,onChange:R,onBlur:E,error:f.errors,warnings:f.warnings,touched:f.touched,disabled:r||w.disabled,isValidating:f.validating}),[t.id,P,f.value,R,E,f.errors,f.warnings,f.touched,r,w.disabled,f.validating]);return jsx("div",{className:s,"data-field-id":t.id,"data-field-type":h.type,children:h.renderer(S)})}var q=er.memo(W);function H({row:i,className:r}){let{formConfig:o}=C(),s=o.renderConfig?.rowRenderer;if(!s)throw new Error(`No rowRenderer configured for form "${o.id}". Please configure a rowRenderer using config.setRowRenderer() or config.setFormRenderConfig().`);let e=i.fields.map(m=>jsx(q,{fieldId:m.id},m.id)),a={row:i,children:e,className:r,spacing:i.spacing,alignment:i.alignment};return s(a)}var J=H;function sr({className:i}){let{formConfig:r}=C(),o=r.renderConfig?.bodyRenderer;if(!o)throw new Error(`No bodyRenderer configured for form "${r.id}". Please configure a bodyRenderer using config.setBodyRenderer() or config.setFormRenderConfig().`);let s=useMemo(()=>r.rows.map(a=>jsx(J,{row:a},a.id)),[r.rows]);return o({formConfig:r,children:s,className:i})}function dr({className:i,children:r}){let{formState:o,submit:s,formConfig:e}=C(),a=e.renderConfig?.submitButtonRenderer;if(!a)throw new Error(`No submitButtonRenderer configured for form "${e.id}". Please configure a submitButtonRenderer using config.setSubmitButtonRenderer() or config.setFormRenderConfig().`);let m={isSubmitting:o.isSubmitting,isValid:o.isValid,isDirty:o.isDirty,onSubmit:s,className:i,children:r};return a(m)}var x=class i{constructor(r,o){this.rows=[];this.rowCounter=0;this.config=r,this.formId=o||`form-${Date.now()}`;}static create(r,o){return new i(r,o)}addField(r,o,s={},e){return this.addRowFields([{fieldId:r,componentType:o,props:s,validation:e?.validation,conditional:e?.conditional}])}addRowFields(r,o){if(r.length===0)throw new Error("At least one field is required");if(r.length>3)throw new Error("Maximum 3 fields per row");let s=`row-${++this.rowCounter}`,e=[];for(let m of r){let d=this.config.getComponent(m.componentType);if(!d)throw new Error(`No component found with type "${m.componentType}"`);let l={id:m.fieldId,componentId:d.id,props:{...d.defaultProps,...m.props},validation:m.validation,conditional:m.conditional};e.push(l);}let a={id:s,fields:e,maxColumns:r.length,spacing:o?.spacing||"normal",alignment:o?.alignment||"stretch"};return this.rows.push(a),this}addFields(r){for(let o of r)this.addField(o.fieldId,o.componentType,o.props,{validation:o.validation,conditional:o.conditional});return this}setId(r){return this.formId=r,this}updateField(r,o){let s=false;for(let e of this.rows){let a=e.fields.findIndex(m=>m.id===r);a!==-1&&(e.fields[a]={...e.fields[a],...o,props:{...e.fields[a].props,...o.props}},s=true);}if(!s)throw new Error(`Field with ID "${r}" not found`);return this}removeField(r){for(let o of this.rows){let s=o.fields.filter(e=>e.id!==r);Object.assign(o,{fields:s});}return this.rows=this.rows.filter(o=>o.fields.length>0),this}getField(r){for(let o of this.rows){let s=o.fields.find(e=>e.id===r);if(s)return s}}getFields(){return this.rows.flatMap(r=>r.fields)}getRows(){return [...this.rows]}clear(){return this.rows=[],this.rowCounter=0,this}clone(r){let o=new i(this.config,r);return o.rows=this.rows.map(s=>({...s,fields:s.fields.map(e=>({...e}))})),o.rowCounter=this.rowCounter,o}validate(){let r=[],o=this.getFields(),s=o.map(a=>a.id),e=s.filter((a,m)=>s.indexOf(a)!==m);e.length>0&&r.push(`Duplicate field IDs: ${e.join(", ")}`);for(let a of o)this.config.hasComponent(a.componentId)||r.push(`Component "${a.componentId}" not found for field "${a.id}"`);for(let a of this.rows)a.fields.length>3&&r.push(`Row "${a.id}" has ${a.fields.length} fields, maximum is 3`),a.fields.length===0&&r.push(`Row "${a.id}" is empty`);return r}build(){let r=this.validate();if(r.length>0)throw new Error(`Form validation failed: ${r.join(", ")}`);return {id:this.formId,rows:[...this.rows],allFields:this.getFields(),config:this.config,renderConfig:this.config.getFormRenderConfig()}}toJSON(){return {id:this.formId,rows:this.rows}}fromJSON(r){return r.id&&(this.formId=r.id),r.rows&&(this.rows=r.rows,this.rowCounter=this.rows.length),this}getStats(){let r=this.getFields(),o=this.rows.map(s=>s.fields.length);return {totalFields:r.length,totalRows:this.rows.length,averageFieldsPerRow:this.rows.length>0?r.length/this.rows.length:0,maxFieldsInRow:o.length>0?Math.max(...o):0,minFieldsInRow:o.length>0?Math.min(...o):0}}};export{rr as Form,sr as FormBody,x as FormBuilder,W as FormField,_ as FormProvider,H as FormRow,dr as FormSubmitButton,x as form,C as useFormContext};
|
|
1
|
+
import er,{createContext,useMemo,useCallback,useContext,useReducer,useRef}from'react';import {jsx}from'react/jsx-runtime';export{createZodValidator,ril}from'@rilaykit/core';function j(i,r){switch(r.type){case "SET_VALUE":{let o={...i.values,[r.fieldId]:r.value};return {...i,values:o,isDirty:true}}case "SET_ERROR":return {...i,errors:{...i.errors,[r.fieldId]:r.errors},isValid:false};case "SET_WARNING":return {...i,warnings:{...i.warnings,[r.fieldId]:r.warnings}};case "CLEAR_ERROR":{let o={...i.errors};return delete o[r.fieldId],{...i,errors:o}}case "CLEAR_WARNING":{let o={...i.warnings};return delete o[r.fieldId],{...i,warnings:o}}case "MARK_TOUCHED":return {...i,touched:new Set([...i.touched,r.fieldId])};case "SET_VALIDATING":{let o=new Set(i.isValidating);return r.isValidating?o.add(r.fieldId):o.delete(r.fieldId),{...i,isValidating:o}}case "SET_SUBMITTING":return {...i,isSubmitting:r.isSubmitting};case "RESET":return {values:r.values||{},errors:{},warnings:{},touched:new Set,isValidating:new Set,isDirty:false,isValid:true,isSubmitting:false};case "UPDATE_VALIDATION_STATE":{let o=Object.keys(i.errors).some(d=>i.errors[d].length>0);return {...i,isValid:!o}}default:return i}}var U=createContext(null);function D({children:i,formConfig:r,defaultValues:o={},onSubmit:d,onFieldChange:e,className:s}){let f={values:o,errors:{},warnings:{},touched:new Set,isValidating:new Set,isDirty:false,isValid:true,isSubmitting:false},[a,m]=useReducer(j,f),t=useRef(new Map),F=useRef(d),l=useRef(e);F.current=d,l.current=e;let y=useCallback((n,c)=>{m({type:"SET_ERROR",fieldId:n,errors:c}),m({type:"UPDATE_VALIDATION_STATE"});},[]),E=useCallback((n,c)=>{m({type:"SET_WARNING",fieldId:n,warnings:c});},[]),v=useCallback(n=>{m({type:"CLEAR_ERROR",fieldId:n}),m({type:"UPDATE_VALIDATION_STATE"});},[]),h=useCallback(n=>{m({type:"CLEAR_WARNING",fieldId:n});},[]),P=useCallback(n=>{m({type:"MARK_TOUCHED",fieldId:n});},[]),S=useCallback((n,c)=>{m({type:"SET_VALIDATING",fieldId:n,isValidating:c});},[]),T=useCallback((n,c)=>{if(m({type:"SET_VALUE",fieldId:n,value:c}),a.errors[n]&&a.errors[n].length>0&&(m({type:"CLEAR_ERROR",fieldId:n}),m({type:"UPDATE_VALIDATION_STATE"})),l.current){let u={...a.values,[n]:c};l.current(n,c,u);}},[a.errors,a.values]),R=useMemo(()=>r,[r]),b=useCallback(async(n,c)=>{let u=R.allFields.find(A=>A.id===n);if(!u?.validation?.validator)return {isValid:true,errors:[]};let z=c!==void 0?c:a.values[n],B=t.current.get(n);B&&clearTimeout(B);let Z={fieldId:n,formData:a.values,fieldProps:u.props,touched:a.touched.has(n),dirty:a.isDirty},O=u.validation.debounceMs||0;return new Promise(A=>{let L=async()=>{S(n,true);try{let g=await u.validation.validator(z,Z,u.props);g.errors.length>0?y(n,g.errors):v(n),g.warnings&&g.warnings.length>0?E(n,g.warnings):h(n),A(g);}catch(g){let M={isValid:false,errors:[{code:"validation_error",message:g instanceof Error?g.message:"Validation error"}]};y(n,M.errors),A(M);}finally{S(n,false);}};if(O>0){let g=setTimeout(L,O);t.current.set(n,g);}else L();})},[R,a.values,a.touched,a.isDirty,y,E,v,h,S]),I=useCallback(async()=>{let n=R.allFields.map(u=>b(u.id));return (await Promise.all(n)).every(u=>u.isValid)},[R,b]),w=useCallback(n=>{m({type:"RESET",values:n});},[]),x=useCallback(async n=>{if(n?.preventDefault(),!F.current)return true;m({type:"SET_SUBMITTING",isSubmitting:true});try{return await I()?(await F.current(a.values),!0):!1}catch(c){return console.error("Error during form submission:",c),false}finally{m({type:"SET_SUBMITTING",isSubmitting:false});}},[a.values,I]),K=useMemo(()=>({formState:a,formConfig:R,setValue:T,setError:y,setWarning:E,clearError:v,clearWarning:h,markFieldTouched:P,setFieldValidating:S,validateField:b,validateAllFields:I,reset:w,submit:x}),[a,R,T,y,E,v,h,P,S,b,I,w,x]);return jsx(U.Provider,{value:K,children:jsx("form",{onSubmit:x,className:s,noValidate:true,children:i})})}function C(){let i=useContext(U);if(!i)throw new Error("useFormContext must be used within a FormProvider");return i}function rr({formConfig:i,defaultValues:r,onSubmit:o,onFieldChange:d,children:e}){return jsx(D,{formConfig:i,defaultValues:r,onSubmit:o,onFieldChange:d,className:"streamline-form",children:e})}function W({fieldId:i,disabled:r=false,customProps:o={},className:d}){let{formState:e,formConfig:s,setValue:f,markFieldTouched:a,validateField:m}=C(),t=useMemo(()=>s.allFields.find(w=>w.id===i),[s.allFields,i]);if(!t)throw new Error(`Field with ID "${i}" not found`);let F=useMemo(()=>s.config.getComponent(t.componentId),[s.config,t.componentId]);if(!F)throw new Error(`Component with ID "${t.componentId}" not found`);let l=useMemo(()=>({value:e.values[t.id],errors:e.errors[t.id]||[],warnings:e.warnings[t.id]||[],touched:e.touched.has(t.id),validating:e.isValidating.has(t.id)}),[e.values,e.errors,e.warnings,e.touched,e.isValidating,t.id]),y=useCallback(w=>{let x=l.errors.length>0;f(t.id,w),(t.validation?.validateOnChange||x&&t.validation?.validator||l.touched&&t.validation?.validator)&&m(t.id,w);},[t.id,t.validation,f,m,l.errors.length,l.touched]),E=useCallback(()=>{a(t.id),(t.validation?.validateOnBlur||t.validation?.validator)&&m(t.id);},[t.id,t.validation,a,m]),v=useMemo(()=>{if(!t.conditional)return true;try{return t.conditional.condition(e.values)}catch(w){return console.warn(`Conditional evaluation failed for field "${t.id}":`,w),true}},[t.conditional,e.values,t.id]),h=useMemo(()=>{if(!t.conditional||!v)return {};switch(t.conditional.action){case "disable":return {disabled:true};case "require":return {required:true};default:return {}}},[t.conditional,v]);if(!v&&t.conditional?.action==="hide")return null;let P=useMemo(()=>({...F.defaultProps,...t.props,...o,...h}),[F.defaultProps,t.props,o,h]),S=useMemo(()=>({id:t.id,props:P,value:l.value,onChange:y,onBlur:E,error:l.errors,warnings:l.warnings,touched:l.touched,disabled:r||h.disabled,isValidating:l.validating}),[t.id,P,l.value,y,E,l.errors,l.warnings,l.touched,r,h.disabled,l.validating]),T=s.renderConfig?.fieldRenderer,R=F.renderer(S),b=F.useFieldRenderer!==false,I=T&&b?T({children:R,id:t.id,error:l.errors,warnings:l.warnings,touched:l.touched,disabled:r||h.disabled,isValidating:l.validating,...P}):R;return jsx("div",{className:d,"data-field-id":t.id,"data-field-type":F.type,children:I})}var q=er.memo(W);function H({row:i,className:r}){let{formConfig:o}=C(),d=o.renderConfig?.rowRenderer;if(!d)throw new Error(`No rowRenderer configured for form "${o.id}". Please configure a rowRenderer using config.setRowRenderer() or config.setFormRenderConfig().`);let e=i.fields.map(f=>jsx(q,{fieldId:f.id},f.id)),s={row:i,children:e,className:r,spacing:i.spacing,alignment:i.alignment};return d(s)}var J=H;function sr({className:i}){let{formConfig:r}=C(),o=r.renderConfig?.bodyRenderer;if(!o)throw new Error(`No bodyRenderer configured for form "${r.id}". Please configure a bodyRenderer using config.setBodyRenderer() or config.setFormRenderConfig().`);let d=useMemo(()=>r.rows.map(s=>jsx(J,{row:s},s.id)),[r.rows]);return o({formConfig:r,children:d,className:i})}function ar({className:i,children:r}){let{formState:o,submit:d,formConfig:e}=C(),s=e.renderConfig?.submitButtonRenderer;if(!s)throw new Error(`No submitButtonRenderer configured for form "${e.id}". Please configure a submitButtonRenderer using config.setSubmitButtonRenderer() or config.setFormRenderConfig().`);let f={isSubmitting:o.isSubmitting,isValid:o.isValid,isDirty:o.isDirty,onSubmit:d,className:i,children:r};return s(f)}var N=class i{constructor(r,o){this.rows=[];this.rowCounter=0;this.config=r,this.formId=o||`form-${Date.now()}`;}static create(r,o){return new i(r,o)}addField(r,o,d={},e){return this.addRowFields([{fieldId:r,componentType:o,props:d,validation:e?.validation,conditional:e?.conditional}])}addRowFields(r,o){if(r.length===0)throw new Error("At least one field is required");if(r.length>3)throw new Error("Maximum 3 fields per row");let d=`row-${++this.rowCounter}`,e=[];for(let f of r){let a=this.config.getComponent(f.componentType);if(!a)throw new Error(`No component found with type "${f.componentType}"`);let m={id:f.fieldId,componentId:a.id,props:{...a.defaultProps,...f.props},validation:f.validation,conditional:f.conditional};e.push(m);}let s={id:d,fields:e,maxColumns:r.length,spacing:o?.spacing||"normal",alignment:o?.alignment||"stretch"};return this.rows.push(s),this}addFields(r){for(let o of r)this.addField(o.fieldId,o.componentType,o.props,{validation:o.validation,conditional:o.conditional});return this}setId(r){return this.formId=r,this}updateField(r,o){let d=false;for(let e of this.rows){let s=e.fields.findIndex(f=>f.id===r);s!==-1&&(e.fields[s]={...e.fields[s],...o,props:{...e.fields[s].props,...o.props}},d=true);}if(!d)throw new Error(`Field with ID "${r}" not found`);return this}removeField(r){for(let o of this.rows){let d=o.fields.filter(e=>e.id!==r);Object.assign(o,{fields:d});}return this.rows=this.rows.filter(o=>o.fields.length>0),this}getField(r){for(let o of this.rows){let d=o.fields.find(e=>e.id===r);if(d)return d}}getFields(){return this.rows.flatMap(r=>r.fields)}getRows(){return [...this.rows]}clear(){return this.rows=[],this.rowCounter=0,this}clone(r){let o=new i(this.config,r);return o.rows=this.rows.map(d=>({...d,fields:d.fields.map(e=>({...e}))})),o.rowCounter=this.rowCounter,o}validate(){let r=[],o=this.getFields(),d=o.map(s=>s.id),e=d.filter((s,f)=>d.indexOf(s)!==f);e.length>0&&r.push(`Duplicate field IDs: ${e.join(", ")}`);for(let s of o)this.config.hasComponent(s.componentId)||r.push(`Component "${s.componentId}" not found for field "${s.id}"`);for(let s of this.rows)s.fields.length>3&&r.push(`Row "${s.id}" has ${s.fields.length} fields, maximum is 3`),s.fields.length===0&&r.push(`Row "${s.id}" is empty`);return r}build(){let r=this.validate();if(r.length>0)throw new Error(`Form validation failed: ${r.join(", ")}`);return {id:this.formId,rows:[...this.rows],allFields:this.getFields(),config:this.config,renderConfig:this.config.getFormRenderConfig()}}toJSON(){return {id:this.formId,rows:this.rows}}fromJSON(r){return r.id&&(this.formId=r.id),r.rows&&(this.rows=r.rows,this.rowCounter=this.rows.length),this}getStats(){let r=this.getFields(),o=this.rows.map(d=>d.fields.length);return {totalFields:r.length,totalRows:this.rows.length,averageFieldsPerRow:this.rows.length>0?r.length/this.rows.length:0,maxFieldsInRow:o.length>0?Math.max(...o):0,minFieldsInRow:o.length>0?Math.min(...o):0}}};export{rr as Form,sr as FormBody,N as FormBuilder,W as FormField,D as FormProvider,H as FormRow,ar as FormSubmitButton,N as form,C as useFormContext};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rilaykit/forms",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Form building utilities and components for RilayKit",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"url": "https://github.com/andyoucreate/rilay/issues"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@rilaykit/core": "1.
|
|
27
|
+
"@rilaykit/core": "1.1.0"
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
30
30
|
"react": ">=18.0.0",
|