@kbgarcia8/react-dynamic-form
Version:
A form that can be nested with editable, expandable and flexible input-forms
178 lines (172 loc) • 14.3 kB
JavaScript
;Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),F=require("react"),r=require("styled-components"),t={fonts:{secondary:"Raleway",tertiary:"Lato",fallback:"system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif"},fontWeight:{light:300,medium:500,bold:700,bolder:900},fontSize:{xsmall:"0.75rem"},spacing:{xxxsmall:"0.25rem",xxsmall:"0.375rem",xsmall:"0.5rem",small:"0.75rem",medium:"1.25rem"},borderRadius:{xsmall:"0.125rem",small:"0.25rem",xlarge:"2rem"},borderThickness:{thin:"0.0625rem",light:"0.125rem"}},J=r.button`
display: flex;
align-items: center;
justify-content: center;
background-color: ${({theme:n})=>n.colors.blue||"blue"};
color: ${({theme:n})=>n.colors.bg||"white"};
border: ${t.borderThickness.light} solid ${({theme:n})=>n.colors.text||"black"};
border-radius: ${t.borderRadius.xlarge};
padding: ${t.spacing.xxxsmall} ${t.spacing.small};
margin: 0.125rem;
width: auto;
cursor: pointer;
transition: background-color 0.2s ease, border-color 0.2s ease;
&:hover {
background-color: lightblue;
border: ${t.borderThickness.light} solid gray;
}
& .button-icon-text-space {
max-width: 100%;
}
& .button-icon-text-space svg {
max-width: 100%;
}
`,K=r.div`
width: 100%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
`,Q=r.img`
maxwidth: 100%;
`,V=r.span`
font-size: ${t.fontSize.xsmall};
font-weight: ${t.fontWeight.medium};
font-family: ${t.fonts.tertiary}, ${t.fonts.fallback};
display: flex;
align-items: center;
justify-content: center;
`,f=({onClick:n,id:s,buttonType:l,source:o,svg:x,alt:d="alt-button-icon",text:m="",className:c="",dataAttributes:h={}})=>e.jsx(J,{onClick:n,id:s,type:l,className:c,...h,children:e.jsxs(K,{className:"button-icon-text-space",children:[o?e.jsx(Q,{src:o,alt:d}):x||"",m&&e.jsx(V,{id:s,children:m})]})}),X=r.div`
display: flex;
flex-direction: column;
align-items: left;
width: 100%;
margin-bottom: ${t.spacing.small};
`,Y=r.div`
display: flex;
gap: ${t.spacing.xsmall};
width: auto;
height: auto;
`,Z=r.label`
display: flex;
align-items: center;
justify-content:center;
height: auto;
flex-direction: ${n=>n.$labelFlexDirection||"column"};
font-family: ${t.fonts.secondary}, ${t.fonts.fallback};
font-size: ${t.fontSize.xsmall};
font-weight: ${t.fontWeight.bold};
gap: ${t.spacing.xxsmall};
& .label-icon-container img,
& .label-icon-container svg {
max-width: 100%;
height: auto;
object-fit: contain;
}
`,_=r.div`
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: ${t.spacing.xxxsmall};
`,ee=r.span`
font-weight: ${t.fontWeight.bolder};
`,te=r.div`
max-width: 100%;
display: flex;
align-items: center;
`,ne=r.span`
font-weight: ${t.fontWeight.light};
`,R=({htmlFor:n,textLabel:s,additionalInfo:l,$labelFlexDirection:o,source:x,svg:d,className:m,children:c})=>e.jsxs(Z,{htmlFor:n,className:m,$labelFlexDirection:o,children:[(x||d)&&e.jsx(te,{className:"label-icon-container",children:x?e.jsx("img",{src:x,alt:`${n}-label-icon`}):d||""}),e.jsxs(_,{className:"label-text-container",children:[e.jsx(ee,{className:"main-label",children:s}),l&&e.jsx(ne,{className:"additional-info",children:l})]}),c]}),B=r.input`
display: flex;
place-content: center;
font-family: ${t.fonts.secondary}, ${t.fonts.fallback};
font-size: ${t.fontSize.xsmall};
line-height: 1.75;
padding: ${t.spacing.xxxsmall} ${t.spacing.xsmall};
max-width: 100%;
height: auto;
background-color: #FFFFFF;
outline: none;
border: ${t.borderThickness.thin} solid #000000;
border-radius: ${t.borderRadius.xsmall};
&:focus{
border: ${t.borderThickness.thin} solid ${({theme:n})=>n.colors.teal};
}
`,ae=r.textarea`
display: flex;
place-content: center;
border: ${t.borderThickness.light} solid ${({theme:n})=>n.colors.text};
border-radius: ${t.borderRadius.small};
outline: none;
line-height: ${t.spacing.small};
padding: ${t.spacing.xxxsmall};
font-family: ${t.fonts.secondary}, ${t.fonts.fallback};
font-size: ${t.fontSize.xsmall};
max-width: 100%;
resize: none;
overflow-y: auto;
`,A=F.forwardRef((n,s)=>{const{type:l,id:o,onChange:x,isRequired:d,dataAttributes:m,disabled:c,className:h}=n;if(l==="textarea"){const{rows:y=5,cols:N=30,value:E,...v}=n;return e.jsx(ae,{id:o,onChange:x,value:E,rows:y,cols:N,...m,className:h,ref:s,disabled:c,required:d})}if(l==="radio"||l==="checkbox"){const{checked:y,...N}=n;return e.jsx(B,{ref:s,type:"checkbox",id:o,checked:y,onChange:x,disabled:c,className:h,...m})}const g=n,{value:j,pattern:$,placeholderText:k,...C}=g;return e.jsx(B,{id:o,name:o,placeholder:k,onChange:x,value:j,type:l,required:d,...m,className:h,ref:s,disabled:c,pattern:$})}),w=n=>{const{className:s,type:l,id:o,textLabel:x,additionalInfo:d,$labelFlexDirection:m,svg:c,labelClass:h,onChange:g,isRequired:j,dataAttributes:$,inputClass:k,ref:C,disabled:y,isEditable:N,editIcon:E,onClickEdit:v,deleteIcon:D,onClickDelete:S,idx:T,children:q}=n;return e.jsxs(X,{className:`${s} ${o.replace("#","")}-label-input-container`,children:[l!=="radio"&&l!=="checkbox"&&e.jsx(R,{htmlFor:o,textLabel:x,additionalInfo:d,$labelFlexDirection:m,svg:c,className:h}),l!=="radio"&&l!=="checkbox"&&l==="textarea"&&(()=>{const{rows:a=5,cols:u=30,value:i,...p}=n;return e.jsx(A,{id:o,name:o,type:"textarea",isRequired:j,onChange:g,value:i,rows:a,cols:u,dataAttributes:$,className:k,ref:C,disabled:y})})(),l!=="radio"&&l!=="checkbox"&&l!=="textarea"&&(()=>{const a=n,{value:u,pattern:i,placeholderText:p,...z}=a;return e.jsx(A,{id:o,name:o,placeholderText:p,onChange:g,value:u,type:l,isRequired:j,dataAttributes:$,className:k,ref:C,disabled:y,pattern:i})})(),(l==="radio"||l==="checkbox")&&(()=>{const{checked:a,...u}=n;return e.jsxs(e.Fragment,{children:[e.jsx(A,{ref:C,type:"checkbox",name:o,id:o,isRequired:j,checked:a,onChange:g,disabled:y,className:k,dataAttributes:$}),e.jsx(R,{htmlFor:o,textLabel:x,additionalInfo:d,$labelFlexDirection:m,svg:c,className:h})]})})(),N&&e.jsxs(Y,{className:"input-edit-buttons",children:[e.jsx(f,{id:`editable-${o}-edit-btn`,svg:E,buttonType:"button",onClick:v,className:`edit-radio-${T}`,dataAttributes:$}),e.jsx(f,{id:`editable-${o}-delete-btn`,svg:D,buttonType:"button",onClick:S,className:`delete-radio-${T}`,dataAttributes:$})]}),q]})},se=r.fieldset`
padding: 0;
height: auto;
width: 100%;
`,oe=r.legend`
font-size: ${t.spacing.medium};
font-weight: 500;
margin: 0 auto ${t.spacing.small} auto;
text-align: center;
font-family: ${t.fonts.secondary}, ${t.fonts.fallback};
`,le=r.div`
display: flex;
flex-direction: column;
align-items: flex-start;
width: 100%;
margin-bottom: ${t.spacing.small};
`,ie=r.div`
display: flex;
justify-content: space-between;
width: 100%;
`,P=({legend:n,idx:s,editableInformation:l,onChangeOfEditableOption:o,onClickSaveEdit:x,onClickCancelEdit:d,onClickDeleteEntry:m})=>e.jsxs(se,{className:"editable-option-fieldset",children:[e.jsx(oe,{children:`${n} ${s+1}`}),l?.map((c,h)=>e.jsx(le,{className:"editable-option-container",children:e.jsx(A,{id:`editable-option-${h}`,name:`editable-option-${h}`,placeholderText:c.name.charAt(0).toUpperCase()+c.name.slice(1),onChange:o,value:c.info,type:c.type,isRequired:!0,className:"editable-option",dataAttributes:{"data-index":h,"data-key":c.info}})},`${c.name}-${h}`)),e.jsxs(ie,{className:"editable-option-button-space",children:[e.jsx(f,{id:`editable-option-${s}-submit`,buttonType:"button",text:"Save",onClick:x,className:"editable-option-btn",dataAttributes:{"data-index":s}}),e.jsx(f,{id:`editable-option-${s}-cancel`,buttonType:"button",text:"Cancel",onClick:d,className:"editable-option-btn",dataAttributes:{"data-index":s}}),e.jsx(f,{id:`editable-option-${s}-delete`,buttonType:"button",text:"Delete",onClick:m,className:"editable-option-btn",dataAttributes:{"data-index":s}})]})]}),ce=r.div`
display: flex;
justify-content: space-between;
max-width: 100%;
`,re=({id:n,hasSubmit:s,submitText:l,handleSubmit:o,hasReset:x,resetText:d,handleReset:m,hasCancel:c,cancelText:h,handleCancel:g})=>e.jsxs(ce,{className:"form-main-button-container",children:[s&&e.jsx(f,{id:`form-${n}-submit`,buttonType:"submit",text:l??"Submit",onClick:o,className:"submit-form-btn"}),x&&e.jsx(f,{id:`form-${n}-edit`,buttonType:"button",text:d??"Reset",onClick:m,className:"reset-form-btn"}),c&&e.jsx(f,{id:`form-${n}-cancel`,buttonType:"button",text:h??"Cancel",onClick:g,className:"cancel-form-btn"})]}),W=r.legend`
font-size: ${t.spacing.medium};
font-weight: 500;
margin-bottom: ${t.spacing.small};
width: auto;
text-align: center;
font-family: ${t.fonts.secondary}, ${t.fonts.fallback};
`,M=r.fieldset`
padding: 0;
height: auto;
width: 100%;
`,U=r.div`
padding: ${t.spacing.small};
height: auto;
width: 100%;
`,O=r.div`
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: auto;
font-family: ${t.fonts.tertiary}, ${t.fonts.fallback};
font-size: ${t.fontSize.xsmall};
font-weight: ${t.fontWeight.bold};
`,de=r.form`
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
`,H=r.div`
display: flex;
justify-content: space-between;
width: 100%;
`,me=r.div`
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
`,xe=({fieldsets:n=null,legendText:s,isExpandable:l,id:o,formInputs:x,labelAndInputContainerClass:d,labelClass:m,inputClass:c,onChangeOfEditableOption:h,handleAddingInputEntry:g,hasSubmit:j=!1,submitText:$,handleSubmit:k,hasReset:C=!1,resetText:y,handleReset:N,hasCancel:E=!1,cancelText:v,handleCancel:D,handleSubmitForm:S,className:T,children:q})=>e.jsxs(de,{id:`${o}-form`,className:T,onSubmit:S,children:[n?n.map((a,u)=>e.jsxs(U,{className:`${o}-fieldset-wrapper`,children:[e.jsxs(M,{id:`${o}-form-fieldset-${u}`,className:`${a.legend}-fieldset`,children:[a.legend&&e.jsx(W,{className:`${a.legend}-legend`,children:a.legend}),a.inputs.length!==0?a.inputs.map((i,p)=>e.jsxs(F.Fragment,{children:[i.type==="textarea"&&e.jsx(w,{...i,id:i.id??`${a.legend}-input`,labelClass:m,inputClass:c,idx:p,className:`${d} ${i?.uniqueClass}`}),i.type!=="textarea"&&i.type!=="radio"&&i.type!=="checkbox"&&e.jsx(w,{...i,id:i.id??`${a.legend}-input`,labelClass:m,inputClass:c,idx:p,className:`${d} ${i?.uniqueClass}`}),(i.type==="radio"||i.type==="checkbox")&&e.jsxs(e.Fragment,{children:[e.jsx(w,{...i,id:i.id??`${a.legend}-input`,labelClass:m,inputClass:c,idx:p,className:`${d} ${i?.uniqueClass}`}),i.editing&&i.isEditable&&e.jsx(P,{legend:`${a.legend}`,idx:p,editableInformation:i?.editableInformation||[],onChangeOfEditableOption:h,onClickSaveEdit:i?.onClickSave||(z=>{}),onClickCancelEdit:i?.onClickCancel||(z=>{}),onClickDeleteEntry:i?.onClickDelete||(z=>{})})]})]},`form-${o}-${p}`)):a.isExpandable?e.jsx(O,{children:`No entry yet on ${a.legend}. Click "+" button to add entry.`}):""]}),a.isExpandable&&e.jsx(H,{className:"add-input-button-space",children:e.jsx(f,{id:`expand-${a.legend}-inputs`,buttonType:"button",text:"+",onClick:g,className:"add-input-entry"})})]},`${a.legend}-${u}`)):e.jsxs(U,{className:`${o}-fieldset-wrapper`,children:[e.jsxs(M,{id:`${o}-form-fieldset`,className:`${s}-fieldset`,children:[s&&e.jsx(W,{className:`${s}-legend`,children:s}),!n&&x&&x.length!==0?x.map((a,u)=>e.jsxs(F.Fragment,{children:[a.type==="textarea"&&e.jsx(w,{...a,id:a.id??`${s}-input`,labelClass:m,inputClass:c,idx:u,className:`${d} ${a?.uniqueClass}`}),a.type!=="textarea"&&a.type!=="radio"&&a.type!=="checkbox"&&e.jsx(w,{...a,id:a.id??`${s}-input`,labelClass:m,inputClass:c,idx:u,className:`${d} ${a?.uniqueClass}`}),(a.type==="radio"||a.type==="checkbox")&&e.jsxs(e.Fragment,{children:[e.jsx(w,{...a,id:a.id??`${s}-input`,labelClass:m,inputClass:c,idx:u,className:`${d} ${a?.uniqueClass}`}),a.editing&&a.isEditable&&e.jsx(P,{legend:`${s}`,idx:u,editableInformation:a?.editableInformation,onChangeOfEditableOption:h,onClickSaveEdit:a?.onClickSave||(i=>{}),onClickCancelEdit:a?.onClickCancel||(i=>{}),onClickDeleteEntry:a?.onClickDelete||(i=>{})})]})]},`form-${o}-${u}`)):l?e.jsx(O,{children:`No entry yet on ${s}. Please click "+" button to add`}):""]}),l&&e.jsx(H,{className:"add-input-button-space",children:e.jsx(f,{id:`expand-${s}-inputs`,buttonType:"button",text:"+",onClick:g,className:"add-input-entry"})})]}),e.jsx(re,{id:o,hasSubmit:j,submitText:$,handleSubmit:k,hasReset:C,resetText:y,handleReset:N,hasCancel:E,cancelText:v,handleCancel:D}),e.jsx(me,{className:"children-container",children:q})]}),be=n=>{const s=/^#([0-9A-Fa-f]{3}){1,2}$/,l=/^rgb(a)?\(\s*\d{1,3}\s*,\s*\d{1,3}\s*,\s*\d{1,3}(?:\s*,\s*(0|1|0?\.\d+))?\s*\)$/;return s.test(n)||l.test(n)||CSS.supports("color",n)},b=n=>{if(!be(n))throw new Error(`Invalid color: ${n}`);return n},he={mobile:"320px",tablet:"768px",desktop:"992px",largeDesktop:"1200px",largerDesktop:"1400px"},I={name:"light",colors:{text:b("#333446"),bg:b("#EEEEEE"),blue:b("#7F8CAA"),blue2:b("#80A6FF"),teal:b("#5b8280ff"),teal2:b("#AEEAE7"),gray:b("#AEAEAE"),information:b("#202234"),success:b("#123524"),warning:b("#F2C265"),error:b("#990000")}},G={name:"dark",colors:{bg:b("#333446"),text:b("#EEEEEE"),blue:b("#80A6FF"),blue2:b("#7F8CAA"),teal:b("#AEEAE7"),teal2:b("#5b8280ff"),gray:b("#D0D0DD"),information:b("#C9E6F0"),success:b("#9EDF9C"),warning:b("#FCFFC1"),error:b("#FAD4D4")}},L=F.createContext({}),ue=({children:n,initialTheme:s=I,secondTheme:l=G})=>{const[o,x]=F.useState(s),d=()=>{x(m=>m===s?l:s)};return e.jsx(L.Provider,{value:{currentTheme:o,toggleTheme:d},children:e.jsx(r.ThemeProvider,{theme:o,children:n})})},ge=()=>F.useContext(L);exports.DynamicForm=xe;exports.ThemeContext=L;exports.ThemeContextProvider=ue;exports.breakpoints=he;exports.darkTheme=G;exports.lightTheme=I;exports.useTheme=ge;