formulaire-dynamique
Version:
Package React pour formulaires dynamiques avec validation et tous types de champs
3 lines (2 loc) • 10.5 kB
JavaScript
import e,{useState as n,useEffect as r,useCallback as t}from"react";import i from"prop-types";import{jsxs as a,jsx as l,Fragment as c}from"react/jsx-runtime";function o(e,n){(null==n||n>e.length)&&(n=e.length);for(var r=0,t=Array(n);r<n;r++)t[r]=e[r];return t}function u(e,n,r){return(n=function(e){var n=function(e,n){if("object"!=typeof e||!e)return e;var r=e[Symbol.toPrimitive];if(void 0!==r){var t=r.call(e,n);if("object"!=typeof t)return t;throw new TypeError("@@toPrimitive must return a primitive value.")}return("string"===n?String:Number)(e)}(e,"string");return"symbol"==typeof n?n:n+""}(n))in e?Object.defineProperty(e,n,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[n]=r,e}function s(e,n){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var t=Object.getOwnPropertySymbols(e);n&&(t=t.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),r.push.apply(r,t)}return r}function m(e){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{};n%2?s(Object(r),!0).forEach((function(n){u(e,n,r[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):s(Object(r)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(r,n))}))}return e}function f(e,n){return function(e){if(Array.isArray(e))return e}(e)||function(e,n){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var t,i,a,l,c=[],o=!0,u=!1;try{if(a=(r=r.call(e)).next,0===n);else for(;!(o=(t=a.call(r)).done)&&(c.push(t.value),c.length!==n);o=!0);}catch(e){u=!0,i=e}finally{try{if(!o&&null!=r.return&&(l=r.return(),Object(l)!==l))return}finally{if(u)throw i}}return c}}(e,n)||function(e,n){if(e){if("string"==typeof e)return o(e,n);var r={}.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?o(e,n):void 0}}(e,n)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}var d=function(t){var i=t.field,o=t.value,u=t.error,s=t.touched,d=t.onChange,p=t.onBlur,h=f(n(null),2),v=h[0],b=h[1];r((function(){if("file"===i.type&&o&&o instanceof File)if(o.type.startsWith("image/")){var e=new FileReader;e.onload=function(e){b(e.target.result)},e.readAsDataURL(o)}else b(null);else b(null)}),[o,i.type]);var g=function(e){d(i.name,e.target.files[0]||null)},y=function(){return i.icon?"function"==typeof i.icon||e.isValidElement(i.icon)?l("span",{className:"field-icon",children:i.icon}):"string"==typeof i.icon?l("i",{className:"field-icon ".concat(i.icon)}):i.icon.src?l("img",{src:i.icon.src,alt:i.icon.alt||"Icon",className:"field-icon icon-image",style:{width:i.icon.width||"16px",height:i.icon.height||"16px"}}):null:null},x=function(){var e={id:i.name,name:i.name,value:"file"!==i.type?o||"":void 0,onChange:"file"!==i.type?function(e){return d(i.name,e.target.value)}:g,onBlur:function(){return p(i.name)},className:"form-field ".concat(i.type," ").concat(u&&s?"error":""),disabled:i.disabled,required:i.required};switch(i.type){case"text":case"email":case"password":case"number":case"tel":case"url":case"date":case"time":case"datetime-local":case"color":return a("div",{className:"input-with-icon",children:[y(),l("input",m(m({type:i.type},e),{},{placeholder:i.placeholder}))]});case"range":return a("div",{className:"range-container",children:[y(),l("input",m(m({type:"range"},e),{},{min:i.min,max:i.max,step:i.step})),l("span",{className:"range-value",children:o})]});case"textarea":return a("div",{className:"textarea-with-icon",children:[y(),l("textarea",m(m({},e),{},{rows:i.rows,placeholder:i.placeholder}))]});case"select":return a("div",{className:"select-with-icon",children:[y(),a("select",m(m({},e),{},{children:[i.placeholder&&l("option",{value:"",children:i.placeholder}),i.options.map((function(e){return l("option",{value:e.value,children:e.label},e.value)}))]}))]});case"checkbox":return a("div",{className:"checkbox-with-icon",children:[l("input",{type:"checkbox",id:i.name,name:i.name,checked:!!o,onChange:function(e){return d(i.name,e.target.checked)},onBlur:function(){return p(i.name)},className:"form-field checkbox ".concat(u&&s?"error":""),disabled:i.disabled}),y()]});case"radio":return l("div",{className:"radio-group",children:i.options.map((function(e){return a("label",{className:"radio-option",children:[l("input",{type:"radio",name:i.name,value:e.value,checked:o===e.value,onChange:function(e){return d(i.name,e.target.value)},onBlur:function(){return p(i.name)}}),e.icon&&l("span",{className:"option-icon",children:"string"==typeof e.icon?l("i",{className:e.icon}):e.icon}),e.label]},e.value)}))});case"file":return a("div",{className:"file-input-container",children:[a("div",{className:"file-input-wrapper",children:[y(),l("input",{type:"file",id:i.name,name:i.name,onChange:g,onBlur:function(){return p(i.name)},accept:i.accept,className:"form-field file ".concat(u&&s?"error":""),disabled:i.disabled})]}),v&&a("div",{className:"image-preview",children:[l("img",{src:v,alt:"Aperçu",className:"preview-image",style:{maxWidth:i.previewWidth||"200px",maxHeight:i.previewHeight||"200px"}}),l("button",{type:"button",className:"remove-preview",onClick:function(){d(i.name,null),b(null)},title:"Supprimer l'image",children:"×"})]}),o&&!v&&a("div",{className:"file-info",children:[l("span",{className:"file-name",children:o.name}),a("span",{className:"file-size",children:["(",Math.round(o.size/1024)," Ko)"]}),l("button",{type:"button",className:"remove-file",onClick:function(){return d(i.name,null)},title:"Supprimer le fichier",children:"×"})]})]});default:return null}};return a("div",{className:"form-field-container ".concat(i.type,"-container"),children:["checkbox"===i.type?a("label",{htmlFor:i.name,className:"checkbox-label",children:[x(),a("span",{className:"checkbox-text",children:[i.label,i.required&&l("span",{className:"required-asterisk",children:"*"})]})]}):a(c,{children:[a("label",{htmlFor:i.name,className:"field-label",children:[i.label,i.required&&l("span",{className:"required-asterisk",children:"*"})]}),x()]}),u&&s&&l("div",{className:"error-message",children:u}),i.helpText&&l("div",{className:"help-text",children:i.helpText})]})};d.propTypes={field:i.object.isRequired,value:i.any,error:i.string,touched:i.bool,onChange:i.func.isRequired,onBlur:i.func.isRequired};var p=function(e,n){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},t=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};if(t[e]){var i=t[e](n);if(i)return i}if(r.required){if(null==n||""===n)return r.requiredMessage||"Ce champ est requis.";if(Array.isArray(n)&&0===n.length)return r.requiredMessage||"Veuillez ajouter au moins un élément.";if(n instanceof File&&(0===n.size||!n.name.trim()))return r.requiredMessage||"Un fichier est requis."}if(null==n||""===n)return null;if("string"==typeof n){if(r.minLength&&n.length<r.minLength)return r.minLengthMessage||"Minimum ".concat(r.minLength," caractères requis.");if(r.maxLength&&n.length>r.maxLength)return r.maxLengthMessage||"Maximum ".concat(r.maxLength," caractères autorisés.");if(r.pattern&&!new RegExp(r.pattern).test(n))return r.patternMessage||"Format invalide."}if("number"==typeof n||!isNaN(Number(n))){if(void 0!==r.min&&Number(n)<r.min)return r.minMessage||"Valeur minimale : ".concat(r.min);if(void 0!==r.max&&Number(n)>r.max)return r.maxMessage||"Valeur maximale : ".concat(r.max)}if(n instanceof File){if(r.accept)if(!r.accept.split(",").map((function(e){return e.trim()})).some((function(e){if(e.includes("*")){var r=e.split("/")[0];return n.type.startsWith(r+"/")}return e.startsWith(".")?n.name.toLowerCase().endsWith(e.toLowerCase()):n.type===e})))return r.acceptMessage||"Type de fichier non autorisé. Types acceptés : ".concat(r.accept);if(r.maxSize&&n.size>r.maxSize)return r.maxSizeMessage||"Fichier trop volumineux (max. ".concat(Math.round(r.maxSize/1024)," Ko)")}return null},h=function(e,n){var r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},t={};return n.forEach((function(n){var i=p(n.name,e[n.name],n.validation,r);i&&(t[n.name]=i)})),t},v=Object.freeze({__proto__:null,validateField:p,validateForm:h}),b=function(e){var r,i=e.config,c=e.onSubmit,o=e.customValidation,s=void 0===o?{}:o,v=e.className,b={};i.fields&&Array.isArray(i.fields)&&i.fields.forEach((function(e){b[e.name]=function(e){if(void 0!==e.defaultValue)return e.defaultValue;switch(e.type){case"checkbox":return!1;case"file":return null;case"number":default:return"";case"range":return e.min||0}}(e)}));var g=f(n(b),2),y=g[0],x=g[1],N=f(n({}),2),w=N[0],O=N[1],j=f(n({}),2),S=j[0],q=j[1],k=t((function(e,n){if(x((function(r){return m(m({},r),{},u({},e,n))})),q((function(n){return m(m({},n),{},u({},e,!0))})),i.validateOnChange){var r=i.fields.find((function(n){return n.name===e}));if(r){var t=p(e,n,r.validation,s);O((function(n){return m(m({},n),{},u({},e,t))}))}}}),[i.validateOnChange,i.fields,s]),C=t((function(e){if(q((function(n){return m(m({},n),{},u({},e,!0))})),i.validateOnBlur){var n=i.fields.find((function(n){return n.name===e}));if(n){var r=p(e,y[e],n.validation,s);O((function(n){return m(m({},n),{},u({},e,r))}))}}}),[i.validateOnBlur,i.fields,y,s]);return i.fields&&Array.isArray(i.fields)?a("form",{onSubmit:function(e){e.preventDefault();var n={};i.fields.forEach((function(e){n[e.name]=!0})),q(n);var r=h(y,i.fields,s);O(r),0===Object.keys(r).length&&c(y)},className:"dynamic-form ".concat(v||""),noValidate:!0,children:[i.fields.map((function(e){return l(d,{field:e,value:y[e.name],error:w[e.name],touched:S[e.name],onChange:k,onBlur:C},e.name)})),l("button",{type:"submit",className:"form-submit-button",disabled:i.disableSubmitOnError&&Object.keys(w).some((function(e){return w[e]})),children:(null===(r=i.submitButton)||void 0===r?void 0:r.text)||"Envoyer"})]}):l("div",{className:"form-error",children:"La configuration du formulaire est invalide."})};b.propTypes={config:i.shape({fields:i.arrayOf(i.object).isRequired,validateOnChange:i.bool,validateOnBlur:i.bool,disableSubmitOnError:i.bool,submitButton:i.shape({text:i.string})}).isRequired,onSubmit:i.func.isRequired,customValidation:i.object,className:i.string};var g={DynamicForm:b,FormField:d,validators:v};export{b as DynamicForm,d as FormField,g as FormulaireDynamique,b as default,v as validators};
//# sourceMappingURL=index.js.map