mui-schema-form-builder 1.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/LICENSE +21 -0
- package/README.md +1 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +119 -0
- package/dist/index.d.ts +119 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/package.json +78 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 AI Studio Builder
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# mui-schema-form-builder
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use strict';var reactHookForm=require('react-hook-form'),material=require('@mui/material'),re=require('react-window'),D=require('react'),jsxRuntime=require('react/jsx-runtime'),zod=require('@hookform/resolvers/zod');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var re__namespace=/*#__PURE__*/_interopNamespace(re);var D__default=/*#__PURE__*/_interopDefault(D);var te=(t=>(t.TEXT="text",t.NUMBER="number",t.SELECT="select",t.AUTOCOMPLETE="autocomplete",t.RADIO="radio",t.CHECKBOX="checkbox",t.TEXTAREA="textarea",t.DATE="date",t))(te||{});var d=D__default.default.memo(({label:e,required:n,disabled:o,error:r})=>jsxRuntime.jsx(material.Box,{sx:{mb:1,display:"flex",alignItems:"center"},children:jsxRuntime.jsxs(material.Typography,{variant:"subtitle2",sx:{fontWeight:600,color:r?"error.main":o?"text.disabled":"text.primary",fontSize:"0.875rem"},children:[e,n&&jsxRuntime.jsx(material.Box,{component:"span",sx:{color:"error.main",ml:.5},children:"*"})]})}));d.displayName="FieldLabel";var y=D__default.default.memo(({fieldConfig:e,control:n})=>{let{field:o,fieldState:{error:r}}=reactHookForm.useController({name:e.name,control:n,defaultValue:e.defaultValue??""}),{ref:l,...u}=o;return jsxRuntime.jsxs(material.Box,{children:[jsxRuntime.jsx(d,{label:e.label,required:e.required,disabled:e.disabled,error:!!r}),jsxRuntime.jsx(material.TextField,{...u,slotProps:{htmlInput:{ref:l}},type:e.type==="date"?"date":"text",placeholder:e.placeholder,disabled:e.disabled,fullWidth:e.fullWidth??true,size:e.size??"medium",error:!!r,helperText:r?.message,multiline:e.type==="textarea",rows:e.type==="textarea"?4:1,...e.muiProps})]})});y.displayName="TextInput";var L=D__default.default.memo(({fieldConfig:e,control:n})=>{let{field:o,fieldState:{error:r}}=reactHookForm.useController({name:e.name,control:n,defaultValue:e.defaultValue??""}),{ref:l,...u}=o;return jsxRuntime.jsxs(material.Box,{children:[jsxRuntime.jsx(d,{label:e.label,required:e.required,disabled:e.disabled,error:!!r}),jsxRuntime.jsx(material.TextField,{...u,slotProps:{htmlInput:{ref:l}},type:"number",placeholder:e.placeholder,disabled:e.disabled,fullWidth:e.fullWidth??true,size:e.size??"medium",error:!!r,helperText:r?.message,onChange:a=>{let s=a.target.value===""?"":Number(a.target.value);o.onChange(s);},...e.muiProps})]})});L.displayName="NumberInput";var A=D__default.default.memo(({fieldConfig:e,control:n})=>{let{field:o,fieldState:{error:r}}=reactHookForm.useController({name:e.name,control:n,defaultValue:e.multiple?e.defaultValue??[]:e.defaultValue??""}),{ref:l,...u}=o;return jsxRuntime.jsxs(material.Box,{children:[jsxRuntime.jsx(d,{label:e.label,required:e.required,disabled:e.disabled,error:!!r}),jsxRuntime.jsxs(material.FormControl,{fullWidth:e.fullWidth??true,size:e.size??"medium",error:!!r,disabled:e.disabled,children:[jsxRuntime.jsx(material.Select,{...u,slotProps:{input:{ref:l}},multiple:e.multiple,displayEmpty:true,renderValue:e.multiple?a=>{let s=a;return !s||s.length===0?e.placeholder||"Select options":s.map(t=>e.options?.find(m=>m.value===t)?.label||t).join(", ")}:a=>a?e.options?.find(s=>s.value===a)?.label||a:e.placeholder||"Select an option",...e.muiProps,children:e.options?.map(a=>jsxRuntime.jsxs(material.MenuItem,{value:a.value,children:[e.multiple&&jsxRuntime.jsx(material.Checkbox,{checked:(o.value||[]).indexOf(a.value)>-1}),jsxRuntime.jsx(material.ListItemText,{primary:a.label})]},a.value))}),r&&jsxRuntime.jsx(material.FormHelperText,{children:r.message})]})]})});A.displayName="SelectInput";function g(e,n){let o=null;return (...r)=>{o&&clearTimeout(o),o=setTimeout(()=>e(...r),n);}}var W=D__default.default.memo(({fieldConfig:e,control:n})=>{let{field:o,fieldState:{error:r}}=reactHookForm.useController({name:e.name,control:n,defaultValue:e.multiple?e.defaultValue??[]:e.defaultValue??null}),[l,u]=D.useState(false),[a,s]=D.useState(e.options||[]),[t,m]=D.useState(false),[x,f]=D.useState(""),v=D.useMemo(()=>g(async p=>{if(e.fetchOptions){m(true);try{let i=await e.fetchOptions(p);s(i);}catch(i){console.error("Failed to fetch options",i);}finally{m(false);}}},300),[e]);D.useEffect(()=>{!l&&e.fetchOptions&&s([]);},[l,e.fetchOptions]),D.useEffect(()=>{l&&e.fetchOptions&&v(x);},[l,x,v,e.fetchOptions]);let B=(p,i)=>{o.onChange(i);},{ref:F,...S}=o;return jsxRuntime.jsxs(material.Box,{children:[jsxRuntime.jsx(d,{label:e.label,required:e.required,disabled:e.disabled,error:!!r}),jsxRuntime.jsx(material.Autocomplete,{...S,multiple:e.multiple,open:l,onOpen:()=>u(true),onClose:()=>u(false),options:a,loading:t,disabled:e.disabled,getOptionLabel:p=>typeof p=="string"?p:p.label||"",isOptionEqualToValue:(p,i)=>p.value===i.value,onChange:B,onInputChange:(p,i)=>{f(i);},renderOption:(p,i,{selected:c})=>{let{key:z,...T}=p;return jsxRuntime.jsxs("li",{...T,children:[e.multiple&&jsxRuntime.jsx(material.Checkbox,{size:"small",style:{marginRight:8},checked:c}),i.label]},z)},renderInput:p=>{let{InputProps:i,inputProps:c,...z}=p;return jsxRuntime.jsx(material.TextField,{...z,placeholder:e.placeholder,size:e.size??"medium",error:!!r,helperText:r?.message,slotProps:{input:{...i,endAdornment:jsxRuntime.jsxs(D__default.default.Fragment,{children:[t?jsxRuntime.jsx(material.CircularProgress,{color:"inherit",size:20}):null,i?.endAdornment]})},htmlInput:{...c,ref:T=>{F(T),c?.ref&&(typeof c.ref=="function"?c.ref(T):c.ref.current=T);}}}})},...e.muiProps})]})});W.displayName="AutocompleteInput";var N=D__default.default.memo(({fieldConfig:e,control:n})=>{let{field:o,fieldState:{error:r}}=reactHookForm.useController({name:e.name,control:n,defaultValue:e.defaultValue??""}),{ref:l,...u}=o;return jsxRuntime.jsxs(material.Box,{children:[jsxRuntime.jsx(d,{label:e.label,required:e.required,disabled:e.disabled,error:!!r}),jsxRuntime.jsxs(material.FormControl,{error:!!r,disabled:e.disabled,component:"fieldset",children:[jsxRuntime.jsx(material.RadioGroup,{...u,row:true,children:e.options?.map((a,s)=>jsxRuntime.jsx(material.FormControlLabel,{value:a.value,control:jsxRuntime.jsx(material.Radio,{size:e.size??"medium",slotProps:{input:{ref:s===0?l:void 0}}}),label:a.label},a.value))}),r&&jsxRuntime.jsx(material.FormHelperText,{children:r.message})]})]})});N.displayName="RadioInput";var G=D__default.default.memo(({fieldConfig:e,control:n})=>{let o=!!e.options,{field:r,fieldState:{error:l}}=reactHookForm.useController({name:e.name,control:n,defaultValue:o?e.defaultValue??[]:e.defaultValue??false});if(o){let s=t=>{let m=r.value||[],x=m.includes(t)?m.filter(f=>f!==t):[...m,t];r.onChange(x);};return jsxRuntime.jsxs(material.Box,{children:[jsxRuntime.jsx(d,{label:e.label,required:e.required,disabled:e.disabled,error:!!l}),jsxRuntime.jsxs(material.FormControl,{error:!!l,component:"fieldset",disabled:e.disabled,children:[jsxRuntime.jsx(material.FormGroup,{row:true,children:e.options?.map((t,m)=>{let x=(r.value||[]).includes(t.value);return jsxRuntime.jsx(material.FormControlLabel,{control:jsxRuntime.jsx(material.Checkbox,{size:e.size??"medium",checked:x,onChange:()=>s(t.value),slotProps:{input:{ref:m===0?r.ref:void 0}}}),label:t.label},t.value)})}),l&&jsxRuntime.jsx(material.FormHelperText,{children:l.message})]})]})}let{ref:u,...a}=r;return jsxRuntime.jsxs(material.Box,{children:[jsxRuntime.jsx(d,{label:e.label,required:e.required,disabled:e.disabled,error:!!l}),jsxRuntime.jsxs(material.FormControl,{error:!!l,disabled:e.disabled,children:[jsxRuntime.jsx(material.FormControlLabel,{control:jsxRuntime.jsx(material.Checkbox,{...a,slotProps:{input:{ref:u}},size:e.size??"medium",checked:!!r.value,onChange:s=>r.onChange(s.target.checked)}),label:e.label}),l&&jsxRuntime.jsx(material.FormHelperText,{children:l.message})]})]})});G.displayName="CheckboxInput";var Ue={text:y,number:L,select:A,autocomplete:W,radio:N,checkbox:G,textarea:y,date:y},O=D__default.default.memo(({fieldConfig:e,control:n})=>{let o=reactHookForm.useWatch({control:n});if(e.visibleIf&&!e.visibleIf(o))return null;let r=Ue[e.type]||y;return jsxRuntime.jsx(material.Grid,{size:e.grid||{xs:12},children:jsxRuntime.jsx(r,{fieldConfig:e,control:n})})});O.displayName="FormField";var j=({fields:e,schema:n,onReset:o})=>{let r=D.useMemo(()=>e.reduce((s,t)=>{let m=t.defaultValue;return m===void 0&&(t.multiple||t.type==="checkbox"&&t.options?m=[]:t.type==="checkbox"?m=false:m=""),s[t.name]=m,s},{}),[e]),l=reactHookForm.useForm({resolver:zod.zodResolver(n),defaultValues:r,mode:"onTouched",shouldFocusError:true}),{reset:u}=l;return {methods:l,defaultValues:r,handleFormReset:()=>{u(r),o&&o();}}};var er=re__namespace.FixedSizeList,yt=({fields:e,schema:n,onSubmit:o,onCancel:r,onReset:l,submitText:u="Submit",cancelText:a="Cancel",resetText:s="Reset",spacing:t=2,virtualize:m=false})=>{let{methods:x,handleFormReset:f}=j({fields:e,schema:n,onReset:l}),{handleSubmit:v,control:B,formState:{isSubmitting:F}}=x,S=({index:p,style:i})=>{let c=e[p];return jsxRuntime.jsx("div",{style:i,children:jsxRuntime.jsx(O,{fieldConfig:c,control:B},c.name)})};return jsxRuntime.jsx(reactHookForm.FormProvider,{...x,children:jsxRuntime.jsx("form",{onSubmit:v(o),noValidate:true,children:jsxRuntime.jsxs(material.Paper,{elevation:0,sx:{p:0,bgcolor:"transparent"},children:[m?jsxRuntime.jsx(er,{height:500,itemCount:e.length,itemSize:100,width:"100%",children:S}):jsxRuntime.jsx(material.Grid,{container:true,spacing:t,children:e.map(p=>jsxRuntime.jsx(O,{fieldConfig:p,control:B},p.name))}),jsxRuntime.jsxs(material.Box,{sx:{mt:4,display:"flex",gap:2,justifyContent:"flex-end",flexWrap:"wrap"},children:[r&&jsxRuntime.jsx(material.Button,{variant:"outlined",color:"inherit",onClick:r,disabled:F,sx:{textTransform:"none",fontWeight:500},children:a}),(l||s)&&jsxRuntime.jsx(material.Button,{variant:"text",color:"secondary",onClick:f,disabled:F,sx:{textTransform:"none",fontWeight:500},children:s}),jsxRuntime.jsx(material.Button,{type:"submit",variant:"contained",color:"primary",loading:F,sx:{px:4,py:1,borderRadius:2,textTransform:"none",fontWeight:600},children:u})]})]})})})};exports.AutocompleteInput=W;exports.CheckboxInput=G;exports.FieldType=te;exports.FormBuilder=yt;exports.FormField=O;exports.NumberInput=L;exports.RadioInput=N;exports.SelectInput=A;exports.TextInput=y;exports.debounce=g;exports.useFormBuilder=j;//# sourceMappingURL=index.cjs.map
|
|
2
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/form-builder/types/field.types.ts","../src/components/form-builder/inputs/FieldLabel.tsx","../src/components/form-builder/inputs/TextInput.tsx","../src/components/form-builder/inputs/NumberInput.tsx","../src/components/form-builder/inputs/SelectInput.tsx","../src/components/form-builder/utils/debounce.ts","../src/components/form-builder/inputs/AutocompleteInput.tsx","../src/components/form-builder/inputs/RadioInput.tsx","../src/components/form-builder/inputs/CheckboxInput.tsx","../src/components/form-builder/FormField.tsx","../src/hooks/useFormBuilder.ts","../src/components/form-builder/FormBuilder.tsx"],"names":["FieldType","FieldLabel","React","label","required","disabled","error","jsx","Box","jsxs","Typography","TextInput","fieldConfig","control","field","useController","fieldRef","fieldProps","TextField","NumberInput","e","val","SelectInput","FormControl","Select","selected","values","o","option","MenuItem","Checkbox","ListItemText","FormHelperText","debounce","func","wait","timeout","args","AutocompleteInput","open","setOpen","useState","options","setOptions","loading","setLoading","inputValue","setInputValue","debouncedFetch","useMemo","searchValue","results","err","useEffect","handleChange","_event","newValue","Autocomplete","value","newInputValue","props","key","otherProps","params","InputProps","inputProps","restParams","CircularProgress","node","RadioInput","RadioGroup","index","FormControlLabel","Radio","CheckboxInput","isGroup","handleGroupChange","currentValues","newValues","v","FormGroup","checked","fieldRegistry","FormField","useWatch","InputComponent","Grid","useFormBuilder","fields","schema","onReset","defaultValues","acc","defaultValue","methods","useForm","zodResolver","reset","VirtualList","re","FormBuilder","onSubmit","onCancel","submitText","cancelText","resetText","spacing","virtualize","handleFormReset","handleSubmit","isSubmitting","VirtualizedFieldList","style","FormProvider","Paper","Button"],"mappings":"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","file":"index.cjs","sourcesContent":["import { z } from 'zod';\r\n\r\nexport enum FieldType {\r\n TEXT = 'text',\r\n NUMBER = 'number',\r\n SELECT = 'select',\r\n AUTOCOMPLETE = 'autocomplete',\r\n RADIO = 'radio',\r\n CHECKBOX = 'checkbox',\r\n TEXTAREA = 'textarea',\r\n DATE = 'date'\r\n}\r\n\r\nexport interface Option {\r\n label: string;\r\n value: string | number;\r\n}\r\n\r\nexport interface GridConfig {\r\n xs?: number;\r\n sm?: number;\r\n md?: number;\r\n lg?: number;\r\n xl?: number;\r\n}\r\n\r\nexport interface FieldConfig {\r\n name: string;\r\n label: string;\r\n type: FieldType;\r\n defaultValue?: any;\r\n placeholder?: string;\r\n options?: Option[];\r\n multiple?: boolean;\r\n disabled?: boolean;\r\n fullWidth?: boolean;\r\n size?: 'small' | 'medium';\r\n required?: boolean;\r\n grid?: GridConfig;\r\n /**\r\n * For Autocomplete async fetching\r\n */\r\n fetchOptions?: (input: string) => Promise<Option[]>;\r\n /**\r\n * For dynamic visibility\r\n */\r\n visibleIf?: (values: any) => boolean;\r\n /**\r\n * Custom props for MUI components\r\n */\r\n muiProps?: any;\r\n}\r\n\r\nexport interface FormBuilderProps {\r\n fields: FieldConfig[];\r\n schema: z.ZodType<any>;\r\n onSubmit: (data: any) => void;\r\n onCancel?: () => void;\r\n onReset?: () => void;\r\n submitText?: string;\r\n cancelText?: string;\r\n resetText?: string;\r\n spacing?: number;\r\n virtualize?: boolean; // Enable if fields > 50\r\n}\r\n","import React from 'react';\r\nimport { Typography, Box } from '@mui/material';\r\n\r\ninterface FieldLabelProps {\r\n label: string;\r\n required?: boolean;\r\n disabled?: boolean;\r\n error?: boolean;\r\n}\r\n\r\nexport const FieldLabel = React.memo(({ label, required, disabled, error }: FieldLabelProps) => {\r\n return (\r\n <Box sx={{ mb: 1, display: 'flex', alignItems: 'center' }}>\r\n <Typography\r\n variant=\"subtitle2\"\r\n sx={{\r\n fontWeight: 600,\r\n color: error ? 'error.main' : disabled ? 'text.disabled' : 'text.primary',\r\n fontSize: '0.875rem',\r\n }}\r\n >\r\n {label}\r\n {required && (\r\n <Box component=\"span\" sx={{ color: 'error.main', ml: 0.5 }}>\r\n *\r\n </Box>\r\n )}\r\n </Typography>\r\n </Box>\r\n );\r\n});\r\n\r\nFieldLabel.displayName = 'FieldLabel';\r\n","import React from 'react';\r\nimport { TextField, Box } from '@mui/material';\r\nimport { useController, Control } from 'react-hook-form';\r\nimport { FieldConfig, FieldType } from '../types/field.types';\r\nimport { FieldLabel } from './FieldLabel';\r\n\r\ninterface InputProps {\r\n fieldConfig: FieldConfig;\r\n control: Control<any>;\r\n}\r\n\r\nexport const TextInput = React.memo(({ fieldConfig, control }: InputProps) => {\r\n const {\r\n field,\r\n fieldState: { error },\r\n } = useController({\r\n name: fieldConfig.name,\r\n control,\r\n defaultValue: fieldConfig.defaultValue ?? '',\r\n });\r\n\r\n const { ref: fieldRef, ...fieldProps } = field;\r\n\r\n return (\r\n <Box>\r\n <FieldLabel\r\n label={fieldConfig.label}\r\n required={fieldConfig.required}\r\n disabled={fieldConfig.disabled}\r\n error={!!error}\r\n />\r\n <TextField\r\n {...fieldProps}\r\n slotProps={{\r\n htmlInput: {\r\n ref: fieldRef\r\n }\r\n }}\r\n type={fieldConfig.type === FieldType.DATE ? 'date' : 'text'}\r\n placeholder={fieldConfig.placeholder}\r\n disabled={fieldConfig.disabled}\r\n fullWidth={fieldConfig.fullWidth ?? true}\r\n size={fieldConfig.size ?? 'medium'}\r\n error={!!error}\r\n helperText={error?.message}\r\n multiline={fieldConfig.type === FieldType.TEXTAREA}\r\n rows={fieldConfig.type === FieldType.TEXTAREA ? 4 : 1}\r\n {...fieldConfig.muiProps}\r\n />\r\n </Box>\r\n );\r\n});\r\n\r\nTextInput.displayName = 'TextInput';\r\n","import React from 'react';\r\nimport { TextField, Box } from '@mui/material';\r\nimport { useController, Control } from 'react-hook-form';\r\nimport { FieldConfig } from '../types/field.types';\r\nimport { FieldLabel } from './FieldLabel';\r\n\r\ninterface InputProps {\r\n fieldConfig: FieldConfig;\r\n control: Control<any>;\r\n}\r\n\r\nexport const NumberInput = React.memo(({ fieldConfig, control }: InputProps) => {\r\n const {\r\n field,\r\n fieldState: { error },\r\n } = useController({\r\n name: fieldConfig.name,\r\n control,\r\n defaultValue: fieldConfig.defaultValue ?? '',\r\n });\r\n\r\n const { ref: fieldRef, ...fieldProps } = field;\r\n\r\n return (\r\n <Box>\r\n <FieldLabel\r\n label={fieldConfig.label}\r\n required={fieldConfig.required}\r\n disabled={fieldConfig.disabled}\r\n error={!!error}\r\n />\r\n <TextField\r\n {...fieldProps}\r\n slotProps={{\r\n htmlInput: {\r\n ref: fieldRef\r\n }\r\n }}\r\n type=\"number\"\r\n placeholder={fieldConfig.placeholder}\r\n disabled={fieldConfig.disabled}\r\n fullWidth={fieldConfig.fullWidth ?? true}\r\n size={fieldConfig.size ?? 'medium'}\r\n error={!!error}\r\n helperText={error?.message}\r\n onChange={(e) => {\r\n const val = e.target.value === '' ? '' : Number(e.target.value);\r\n field.onChange(val);\r\n }}\r\n {...fieldConfig.muiProps}\r\n />\r\n </Box>\r\n );\r\n});\r\n\r\nNumberInput.displayName = 'NumberInput';\r\n","import React from 'react';\r\nimport {\r\n FormControl,\r\n Select,\r\n MenuItem,\r\n FormHelperText,\r\n Checkbox,\r\n ListItemText,\r\n Box,\r\n} from '@mui/material';\r\nimport { useController, Control } from 'react-hook-form';\r\nimport { FieldConfig } from '../types/field.types';\r\nimport { FieldLabel } from './FieldLabel';\r\n\r\ninterface InputProps {\r\n fieldConfig: FieldConfig;\r\n control: Control<any>;\r\n}\r\n\r\nexport const SelectInput = React.memo(({ fieldConfig, control }: InputProps) => {\r\n const {\r\n field,\r\n fieldState: { error },\r\n } = useController({\r\n name: fieldConfig.name,\r\n control,\r\n defaultValue: fieldConfig.multiple ? (fieldConfig.defaultValue ?? []) : (fieldConfig.defaultValue ?? ''),\r\n });\r\n\r\n const { ref: fieldRef, ...fieldProps } = field;\r\n\r\n return (\r\n <Box>\r\n <FieldLabel\r\n label={fieldConfig.label}\r\n required={fieldConfig.required}\r\n disabled={fieldConfig.disabled}\r\n error={!!error}\r\n />\r\n <FormControl\r\n fullWidth={fieldConfig.fullWidth ?? true}\r\n size={fieldConfig.size ?? 'medium'}\r\n error={!!error}\r\n disabled={fieldConfig.disabled}\r\n >\r\n <Select\r\n {...fieldProps}\r\n slotProps={{\r\n input: {\r\n ref: fieldRef\r\n }\r\n }}\r\n multiple={fieldConfig.multiple}\r\n displayEmpty\r\n renderValue={\r\n fieldConfig.multiple\r\n ? (selected) => {\r\n const values = selected as (string | number)[];\r\n if (!values || values.length === 0) return fieldConfig.placeholder || 'Select options';\r\n return values\r\n .map((val) => fieldConfig.options?.find((o) => o.value === val)?.label || val)\r\n .join(', ');\r\n }\r\n : (selected) => {\r\n if (!selected) return fieldConfig.placeholder || 'Select an option';\r\n return fieldConfig.options?.find((o) => o.value === selected)?.label || selected;\r\n }\r\n }\r\n {...fieldConfig.muiProps}\r\n >\r\n {fieldConfig.options?.map((option) => (\r\n <MenuItem key={option.value} value={option.value}>\r\n {fieldConfig.multiple && (\r\n <Checkbox checked={(field.value || []).indexOf(option.value) > -1} />\r\n )}\r\n <ListItemText primary={option.label} />\r\n </MenuItem>\r\n ))}\r\n </Select>\r\n {error && <FormHelperText>{error.message}</FormHelperText>}\r\n </FormControl>\r\n </Box>\r\n );\r\n});\r\n\r\nSelectInput.displayName = 'SelectInput';\r\n","export function debounce<T extends (...args: any[]) => any>(\r\n func: T,\r\n wait: number\r\n): (...args: Parameters<T>) => void {\r\n let timeout: ReturnType<typeof setTimeout> | null = null;\r\n return (...args: Parameters<T>) => {\r\n if (timeout) clearTimeout(timeout);\r\n timeout = setTimeout(() => func(...args), wait);\r\n };\r\n}\r\n","import React, { useState, useEffect, useMemo } from 'react';\r\nimport {\r\n Autocomplete,\r\n TextField,\r\n CircularProgress,\r\n Checkbox,\r\n Box,\r\n} from '@mui/material';\r\nimport { useController, Control } from 'react-hook-form';\r\nimport { FieldConfig, Option } from '../types/field.types';\r\nimport { debounce } from '../utils/debounce';\r\nimport { FieldLabel } from './FieldLabel';\r\n\r\ninterface InputProps {\r\n fieldConfig: FieldConfig;\r\n control: Control<any>;\r\n}\r\n\r\nexport const AutocompleteInput = React.memo(({ fieldConfig, control }: InputProps) => {\r\n const {\r\n field,\r\n fieldState: { error },\r\n } = useController({\r\n name: fieldConfig.name,\r\n control,\r\n defaultValue: fieldConfig.multiple ? (fieldConfig.defaultValue ?? []) : (fieldConfig.defaultValue ?? null),\r\n });\r\n\r\n const [open, setOpen] = useState(false);\r\n const [options, setOptions] = useState<Option[]>(fieldConfig.options || []);\r\n const [loading, setLoading] = useState(false);\r\n const [inputValue, setInputValue] = useState('');\r\n\r\n const debouncedFetch = useMemo(\r\n () =>\r\n debounce(async (searchValue: string) => {\r\n if (!fieldConfig.fetchOptions) return;\r\n setLoading(true);\r\n try {\r\n const results = await fieldConfig.fetchOptions(searchValue);\r\n setOptions(results);\r\n } catch (err) {\r\n console.error('Failed to fetch options', err);\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, 300),\r\n [fieldConfig]\r\n );\r\n\r\n useEffect(() => {\r\n if (!open && fieldConfig.fetchOptions) {\r\n setOptions([]);\r\n }\r\n }, [open, fieldConfig.fetchOptions]);\r\n\r\n useEffect(() => {\r\n if (open && fieldConfig.fetchOptions) {\r\n debouncedFetch(inputValue);\r\n }\r\n }, [open, inputValue, debouncedFetch, fieldConfig.fetchOptions]);\r\n\r\n const handleChange = (_event: any, newValue: any) => {\r\n field.onChange(newValue);\r\n };\r\n\r\n const { ref: fieldRef, ...fieldProps } = field;\r\n\r\n return (\r\n <Box>\r\n <FieldLabel\r\n label={fieldConfig.label}\r\n required={fieldConfig.required}\r\n disabled={fieldConfig.disabled}\r\n error={!!error}\r\n />\r\n <Autocomplete\r\n {...fieldProps}\r\n multiple={fieldConfig.multiple}\r\n open={open}\r\n onOpen={() => setOpen(true)}\r\n onClose={() => setOpen(false)}\r\n options={options}\r\n loading={loading}\r\n disabled={fieldConfig.disabled}\r\n getOptionLabel={(option: any) => (typeof option === 'string' ? option : (option.label || ''))}\r\n isOptionEqualToValue={(option: any, value: any) => option.value === value.value}\r\n onChange={handleChange}\r\n onInputChange={(_event, newInputValue) => {\r\n setInputValue(newInputValue);\r\n }}\r\n renderOption={(props, option: any, { selected }) => {\r\n const { key, ...otherProps } = props;\r\n return (\r\n <li key={key} {...otherProps}>\r\n {fieldConfig.multiple && (\r\n <Checkbox\r\n size=\"small\"\r\n style={{ marginRight: 8 }}\r\n checked={selected}\r\n />\r\n )}\r\n {option.label}\r\n </li>\r\n );\r\n }}\r\n renderInput={(params) => {\r\n const { InputProps, inputProps, ...restParams } = params as any;\r\n return (\r\n <TextField\r\n {...restParams}\r\n placeholder={fieldConfig.placeholder}\r\n size={fieldConfig.size ?? 'medium'}\r\n error={!!error}\r\n helperText={error?.message}\r\n slotProps={{\r\n input: {\r\n ...InputProps,\r\n endAdornment: (\r\n <React.Fragment>\r\n {loading ? <CircularProgress color=\"inherit\" size={20} /> : null}\r\n {InputProps?.endAdornment}\r\n </React.Fragment>\r\n ),\r\n },\r\n htmlInput: {\r\n ...inputProps,\r\n ref: (node: HTMLInputElement | null) => {\r\n fieldRef(node);\r\n if (inputProps?.ref) {\r\n if (typeof inputProps.ref === 'function') {\r\n inputProps.ref(node);\r\n } else {\r\n inputProps.ref.current = node;\r\n }\r\n }\r\n },\r\n },\r\n }}\r\n />\r\n );\r\n }}\r\n {...fieldConfig.muiProps}\r\n />\r\n </Box>\r\n );\r\n});\r\n\r\nAutocompleteInput.displayName = 'AutocompleteInput';\r\n","import React from 'react';\r\nimport {\r\n FormControl,\r\n RadioGroup,\r\n FormControlLabel,\r\n Radio,\r\n FormHelperText,\r\n Box,\r\n} from '@mui/material';\r\nimport { useController, Control } from 'react-hook-form';\r\nimport { FieldConfig } from '../types/field.types';\r\nimport { FieldLabel } from './FieldLabel';\r\n\r\ninterface InputProps {\r\n fieldConfig: FieldConfig;\r\n control: Control<any>;\r\n}\r\n\r\nexport const RadioInput = React.memo(({ fieldConfig, control }: InputProps) => {\r\n const {\r\n field,\r\n fieldState: { error },\r\n } = useController({\r\n name: fieldConfig.name,\r\n control,\r\n defaultValue: fieldConfig.defaultValue ?? '',\r\n });\r\n\r\n const { ref: fieldRef, ...fieldProps } = field;\r\n\r\n return (\r\n <Box>\r\n <FieldLabel\r\n label={fieldConfig.label}\r\n required={fieldConfig.required}\r\n disabled={fieldConfig.disabled}\r\n error={!!error}\r\n />\r\n <FormControl error={!!error} disabled={fieldConfig.disabled} component=\"fieldset\">\r\n <RadioGroup {...fieldProps} row>\r\n {fieldConfig.options?.map((option, index) => (\r\n <FormControlLabel\r\n key={option.value}\r\n value={option.value}\r\n control={\r\n <Radio \r\n size={fieldConfig.size ?? 'medium'} \r\n slotProps={{ input: { ref: index === 0 ? fieldRef : undefined } } as any} \r\n />\r\n }\r\n label={option.label}\r\n />\r\n ))}\r\n </RadioGroup>\r\n {error && <FormHelperText>{error.message}</FormHelperText>}\r\n </FormControl>\r\n </Box>\r\n );\r\n});\r\n\r\nRadioInput.displayName = 'RadioInput';\r\n","import React from 'react';\r\nimport {\r\n FormControl,\r\n FormControlLabel,\r\n Checkbox,\r\n FormHelperText,\r\n FormGroup,\r\n Box,\r\n} from '@mui/material';\r\nimport { useController, Control } from 'react-hook-form';\r\nimport { FieldConfig } from '../types/field.types';\r\nimport { FieldLabel } from './FieldLabel';\r\n\r\ninterface InputProps {\r\n fieldConfig: FieldConfig;\r\n control: Control<any>;\r\n}\r\n\r\nexport const CheckboxInput = React.memo(({ fieldConfig, control }: InputProps) => {\r\n // Checkbox can be single boolean or group of strings\r\n const isGroup = !!fieldConfig.options;\r\n\r\n const {\r\n field,\r\n fieldState: { error },\r\n } = useController({\r\n name: fieldConfig.name,\r\n control,\r\n defaultValue: isGroup ? (fieldConfig.defaultValue ?? []) : (fieldConfig.defaultValue ?? false),\r\n });\r\n\r\n if (isGroup) {\r\n const handleGroupChange = (value: any) => {\r\n const currentValues = (field.value as any[]) || [];\r\n const newValues = currentValues.includes(value)\r\n ? currentValues.filter((v) => v !== value)\r\n : [...currentValues, value];\r\n field.onChange(newValues);\r\n };\r\n\r\n return (\r\n <Box>\r\n <FieldLabel\r\n label={fieldConfig.label}\r\n required={fieldConfig.required}\r\n disabled={fieldConfig.disabled}\r\n error={!!error}\r\n />\r\n <FormControl error={!!error} component=\"fieldset\" disabled={fieldConfig.disabled}>\r\n <FormGroup row>\r\n {fieldConfig.options?.map((option, index) => {\r\n const checked = (field.value || []).includes(option.value);\r\n return (\r\n <FormControlLabel\r\n key={option.value}\r\n control={\r\n <Checkbox\r\n size={fieldConfig.size ?? 'medium'}\r\n checked={checked}\r\n onChange={() => handleGroupChange(option.value)}\r\n slotProps={{ input: { ref: index === 0 ? field.ref : undefined } } as any}\r\n />\r\n }\r\n label={option.label}\r\n />\r\n );\r\n })}\r\n </FormGroup>\r\n {error && <FormHelperText>{error.message}</FormHelperText>}\r\n </FormControl>\r\n </Box>\r\n );\r\n }\r\n\r\n const { ref: fieldRef, ...fieldProps } = field;\r\n\r\n return (\r\n <Box>\r\n <FieldLabel\r\n label={fieldConfig.label}\r\n required={fieldConfig.required}\r\n disabled={fieldConfig.disabled}\r\n error={!!error}\r\n />\r\n <FormControl error={!!error} disabled={fieldConfig.disabled}>\r\n <FormControlLabel\r\n control={\r\n <Checkbox\r\n {...fieldProps}\r\n slotProps={{ input: { ref: fieldRef } } as any}\r\n size={fieldConfig.size ?? 'medium'}\r\n checked={!!field.value}\r\n onChange={(e) => field.onChange(e.target.checked)}\r\n />\r\n }\r\n label={fieldConfig.label}\r\n />\r\n {error && <FormHelperText>{error.message}</FormHelperText>}\r\n </FormControl>\r\n </Box>\r\n );\r\n});\r\n\r\nCheckboxInput.displayName = 'CheckboxInput';\r\n","import React from 'react';\r\nimport { Control, useWatch } from 'react-hook-form';\r\nimport { Grid } from '@mui/material';\r\nimport { FieldConfig, FieldType } from './types/field.types';\r\nimport { TextInput } from './inputs/TextInput';\r\nimport { NumberInput } from './inputs/NumberInput';\r\nimport { SelectInput } from './inputs/SelectInput';\r\nimport { AutocompleteInput } from './inputs/AutocompleteInput';\r\nimport { RadioInput } from './inputs/RadioInput';\r\nimport { CheckboxInput } from './inputs/CheckboxInput';\r\n\r\ninterface FormFieldProps {\r\n fieldConfig: FieldConfig;\r\n control: Control<any>;\r\n}\r\n\r\nconst fieldRegistry: Record<FieldType, React.ComponentType<any>> = {\r\n [FieldType.TEXT]: TextInput,\r\n [FieldType.NUMBER]: NumberInput,\r\n [FieldType.SELECT]: SelectInput,\r\n [FieldType.AUTOCOMPLETE]: AutocompleteInput,\r\n [FieldType.RADIO]: RadioInput,\r\n [FieldType.CHECKBOX]: CheckboxInput,\r\n [FieldType.TEXTAREA]: TextInput, // Uses same text component with multiline prop\r\n [FieldType.DATE]: TextInput, // Fallback for simple date or placeholder\r\n};\r\n\r\nexport const FormField = React.memo(({ fieldConfig, control }: FormFieldProps) => {\r\n // Watch all values for dynamic visibility check\r\n const values = useWatch({ control });\r\n \r\n if (fieldConfig.visibleIf && !fieldConfig.visibleIf(values)) {\r\n return null;\r\n }\r\n\r\n const InputComponent = fieldRegistry[fieldConfig.type] || TextInput;\r\n\r\n return (\r\n <Grid size={fieldConfig.grid || { xs: 12 }}>\r\n <InputComponent fieldConfig={fieldConfig} control={control} />\r\n </Grid>\r\n );\r\n});\r\n\r\nFormField.displayName = 'FormField';\r\n","import { useMemo } from 'react';\r\nimport { useForm, FieldValues } from 'react-hook-form';\r\nimport { zodResolver } from '@hookform/resolvers/zod';\r\nimport { FieldType, FormBuilderProps } from '../components/form-builder/types/field.types';\r\n\r\nexport const useFormBuilder = <T extends FieldValues = any>({\r\n fields,\r\n schema,\r\n onReset,\r\n}: Pick<FormBuilderProps, 'fields' | 'schema' | 'onReset'>) => {\r\n const defaultValues = useMemo(() => {\r\n return fields.reduce((acc, field) => {\r\n let defaultValue = field.defaultValue;\r\n\r\n if (defaultValue === undefined) {\r\n if (field.multiple || (field.type === FieldType.CHECKBOX && field.options)) {\r\n defaultValue = [];\r\n } else if (field.type === FieldType.CHECKBOX) {\r\n defaultValue = false;\r\n } else {\r\n defaultValue = '';\r\n }\r\n }\r\n\r\n acc[field.name] = defaultValue;\r\n return acc;\r\n }, {} as any);\r\n }, [fields]);\r\n\r\n const methods = useForm<T>({\r\n resolver: zodResolver(schema as any),\r\n defaultValues: defaultValues as any,\r\n mode: 'onTouched',\r\n shouldFocusError: true,\r\n });\r\n\r\n const { reset } = methods;\r\n\r\n const handleFormReset = () => {\r\n reset(defaultValues as any);\r\n if (onReset) onReset();\r\n };\r\n\r\n return {\r\n methods,\r\n defaultValues,\r\n handleFormReset,\r\n };\r\n};\r\n","import React from 'react';\r\nimport { FormProvider } from 'react-hook-form';\r\nimport { Box, Button, Grid, Paper } from '@mui/material';\r\nimport * as ReactWindow from 'react-window';\r\nimport { FormBuilderProps } from './types/field.types';\r\nimport { FormField } from './FormField';\r\nimport { useFormBuilder } from '../../hooks/useFormBuilder';\r\n\r\nconst VirtualList = (ReactWindow as any).FixedSizeList;\r\n\r\nexport const FormBuilder = ({\r\n fields,\r\n schema,\r\n onSubmit,\r\n onCancel,\r\n onReset,\r\n submitText = 'Submit',\r\n cancelText = 'Cancel',\r\n resetText = 'Reset',\r\n spacing = 2,\r\n virtualize = false,\r\n}: FormBuilderProps) => {\r\n const { methods, handleFormReset } = useFormBuilder({\r\n fields,\r\n schema,\r\n onReset,\r\n });\r\n\r\n const {\r\n handleSubmit,\r\n control,\r\n formState: { isSubmitting },\r\n } = methods;\r\n\r\n const VirtualizedFieldList = ({ index, style }: { index: number; style: React.CSSProperties }) => {\r\n const field = fields[index];\r\n return (\r\n <div style={style}>\r\n <FormField key={field.name} fieldConfig={field} control={control} />\r\n </div>\r\n );\r\n };\r\n\r\n return (\r\n <FormProvider {...methods}>\r\n <form onSubmit={handleSubmit(onSubmit)} noValidate>\r\n <Paper elevation={0} sx={{ p: 0, bgcolor: 'transparent' }}>\r\n {virtualize ? (\r\n <VirtualList\r\n height={500}\r\n itemCount={fields.length}\r\n itemSize={100}\r\n width=\"100%\"\r\n >\r\n {VirtualizedFieldList}\r\n </VirtualList>\r\n ) : (\r\n <Grid container spacing={spacing}>\r\n {fields.map((field) => (\r\n <FormField key={field.name} fieldConfig={field} control={control} />\r\n ))}\r\n </Grid>\r\n )}\r\n\r\n <Box sx={{ mt: 4, display: 'flex', gap: 2, justifyContent: 'flex-end', flexWrap: 'wrap' }}>\r\n {onCancel && (\r\n <Button\r\n variant=\"outlined\"\r\n color=\"inherit\"\r\n onClick={onCancel}\r\n disabled={isSubmitting}\r\n sx={{ textTransform: 'none', fontWeight: 500 }}\r\n >\r\n {cancelText}\r\n </Button>\r\n )}\r\n {(onReset || resetText) && (\r\n <Button\r\n variant=\"text\"\r\n color=\"secondary\"\r\n onClick={handleFormReset}\r\n disabled={isSubmitting}\r\n sx={{ textTransform: 'none', fontWeight: 500 }}\r\n >\r\n {resetText}\r\n </Button>\r\n )}\r\n <Button\r\n type=\"submit\"\r\n variant=\"contained\"\r\n color=\"primary\"\r\n loading={isSubmitting}\r\n sx={{\r\n px: 4,\r\n py: 1,\r\n borderRadius: 2,\r\n textTransform: 'none',\r\n fontWeight: 600,\r\n }}\r\n >\r\n {submitText}\r\n </Button>\r\n </Box>\r\n </Paper>\r\n </form>\r\n </FormProvider>\r\n );\r\n};\r\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import * as react_hook_form from 'react-hook-form';
|
|
5
|
+
import { Control, FieldValues } from 'react-hook-form';
|
|
6
|
+
|
|
7
|
+
declare enum FieldType {
|
|
8
|
+
TEXT = "text",
|
|
9
|
+
NUMBER = "number",
|
|
10
|
+
SELECT = "select",
|
|
11
|
+
AUTOCOMPLETE = "autocomplete",
|
|
12
|
+
RADIO = "radio",
|
|
13
|
+
CHECKBOX = "checkbox",
|
|
14
|
+
TEXTAREA = "textarea",
|
|
15
|
+
DATE = "date"
|
|
16
|
+
}
|
|
17
|
+
interface Option {
|
|
18
|
+
label: string;
|
|
19
|
+
value: string | number;
|
|
20
|
+
}
|
|
21
|
+
interface GridConfig {
|
|
22
|
+
xs?: number;
|
|
23
|
+
sm?: number;
|
|
24
|
+
md?: number;
|
|
25
|
+
lg?: number;
|
|
26
|
+
xl?: number;
|
|
27
|
+
}
|
|
28
|
+
interface FieldConfig {
|
|
29
|
+
name: string;
|
|
30
|
+
label: string;
|
|
31
|
+
type: FieldType;
|
|
32
|
+
defaultValue?: any;
|
|
33
|
+
placeholder?: string;
|
|
34
|
+
options?: Option[];
|
|
35
|
+
multiple?: boolean;
|
|
36
|
+
disabled?: boolean;
|
|
37
|
+
fullWidth?: boolean;
|
|
38
|
+
size?: 'small' | 'medium';
|
|
39
|
+
required?: boolean;
|
|
40
|
+
grid?: GridConfig;
|
|
41
|
+
/**
|
|
42
|
+
* For Autocomplete async fetching
|
|
43
|
+
*/
|
|
44
|
+
fetchOptions?: (input: string) => Promise<Option[]>;
|
|
45
|
+
/**
|
|
46
|
+
* For dynamic visibility
|
|
47
|
+
*/
|
|
48
|
+
visibleIf?: (values: any) => boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Custom props for MUI components
|
|
51
|
+
*/
|
|
52
|
+
muiProps?: any;
|
|
53
|
+
}
|
|
54
|
+
interface FormBuilderProps {
|
|
55
|
+
fields: FieldConfig[];
|
|
56
|
+
schema: z.ZodType<any>;
|
|
57
|
+
onSubmit: (data: any) => void;
|
|
58
|
+
onCancel?: () => void;
|
|
59
|
+
onReset?: () => void;
|
|
60
|
+
submitText?: string;
|
|
61
|
+
cancelText?: string;
|
|
62
|
+
resetText?: string;
|
|
63
|
+
spacing?: number;
|
|
64
|
+
virtualize?: boolean;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
declare const FormBuilder: ({ fields, schema, onSubmit, onCancel, onReset, submitText, cancelText, resetText, spacing, virtualize, }: FormBuilderProps) => react_jsx_runtime.JSX.Element;
|
|
68
|
+
|
|
69
|
+
interface FormFieldProps {
|
|
70
|
+
fieldConfig: FieldConfig;
|
|
71
|
+
control: Control<any>;
|
|
72
|
+
}
|
|
73
|
+
declare const FormField: React.MemoExoticComponent<({ fieldConfig, control }: FormFieldProps) => react_jsx_runtime.JSX.Element | null>;
|
|
74
|
+
|
|
75
|
+
interface InputProps$5 {
|
|
76
|
+
fieldConfig: FieldConfig;
|
|
77
|
+
control: Control<any>;
|
|
78
|
+
}
|
|
79
|
+
declare const TextInput: React.MemoExoticComponent<({ fieldConfig, control }: InputProps$5) => react_jsx_runtime.JSX.Element>;
|
|
80
|
+
|
|
81
|
+
interface InputProps$4 {
|
|
82
|
+
fieldConfig: FieldConfig;
|
|
83
|
+
control: Control<any>;
|
|
84
|
+
}
|
|
85
|
+
declare const NumberInput: React.MemoExoticComponent<({ fieldConfig, control }: InputProps$4) => react_jsx_runtime.JSX.Element>;
|
|
86
|
+
|
|
87
|
+
interface InputProps$3 {
|
|
88
|
+
fieldConfig: FieldConfig;
|
|
89
|
+
control: Control<any>;
|
|
90
|
+
}
|
|
91
|
+
declare const SelectInput: React.MemoExoticComponent<({ fieldConfig, control }: InputProps$3) => react_jsx_runtime.JSX.Element>;
|
|
92
|
+
|
|
93
|
+
interface InputProps$2 {
|
|
94
|
+
fieldConfig: FieldConfig;
|
|
95
|
+
control: Control<any>;
|
|
96
|
+
}
|
|
97
|
+
declare const AutocompleteInput: React.MemoExoticComponent<({ fieldConfig, control }: InputProps$2) => react_jsx_runtime.JSX.Element>;
|
|
98
|
+
|
|
99
|
+
interface InputProps$1 {
|
|
100
|
+
fieldConfig: FieldConfig;
|
|
101
|
+
control: Control<any>;
|
|
102
|
+
}
|
|
103
|
+
declare const CheckboxInput: React.MemoExoticComponent<({ fieldConfig, control }: InputProps$1) => react_jsx_runtime.JSX.Element>;
|
|
104
|
+
|
|
105
|
+
interface InputProps {
|
|
106
|
+
fieldConfig: FieldConfig;
|
|
107
|
+
control: Control<any>;
|
|
108
|
+
}
|
|
109
|
+
declare const RadioInput: React.MemoExoticComponent<({ fieldConfig, control }: InputProps) => react_jsx_runtime.JSX.Element>;
|
|
110
|
+
|
|
111
|
+
declare const useFormBuilder: <T extends FieldValues = any>({ fields, schema, onReset, }: Pick<FormBuilderProps, "fields" | "schema" | "onReset">) => {
|
|
112
|
+
methods: react_hook_form.UseFormReturn<T, any, T>;
|
|
113
|
+
defaultValues: any;
|
|
114
|
+
handleFormReset: () => void;
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
declare function debounce<T extends (...args: any[]) => any>(func: T, wait: number): (...args: Parameters<T>) => void;
|
|
118
|
+
|
|
119
|
+
export { AutocompleteInput, CheckboxInput, type FieldConfig, FieldType, FormBuilder, type FormBuilderProps, FormField, type GridConfig, NumberInput, type Option, RadioInput, SelectInput, TextInput, debounce, useFormBuilder };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import * as react_hook_form from 'react-hook-form';
|
|
5
|
+
import { Control, FieldValues } from 'react-hook-form';
|
|
6
|
+
|
|
7
|
+
declare enum FieldType {
|
|
8
|
+
TEXT = "text",
|
|
9
|
+
NUMBER = "number",
|
|
10
|
+
SELECT = "select",
|
|
11
|
+
AUTOCOMPLETE = "autocomplete",
|
|
12
|
+
RADIO = "radio",
|
|
13
|
+
CHECKBOX = "checkbox",
|
|
14
|
+
TEXTAREA = "textarea",
|
|
15
|
+
DATE = "date"
|
|
16
|
+
}
|
|
17
|
+
interface Option {
|
|
18
|
+
label: string;
|
|
19
|
+
value: string | number;
|
|
20
|
+
}
|
|
21
|
+
interface GridConfig {
|
|
22
|
+
xs?: number;
|
|
23
|
+
sm?: number;
|
|
24
|
+
md?: number;
|
|
25
|
+
lg?: number;
|
|
26
|
+
xl?: number;
|
|
27
|
+
}
|
|
28
|
+
interface FieldConfig {
|
|
29
|
+
name: string;
|
|
30
|
+
label: string;
|
|
31
|
+
type: FieldType;
|
|
32
|
+
defaultValue?: any;
|
|
33
|
+
placeholder?: string;
|
|
34
|
+
options?: Option[];
|
|
35
|
+
multiple?: boolean;
|
|
36
|
+
disabled?: boolean;
|
|
37
|
+
fullWidth?: boolean;
|
|
38
|
+
size?: 'small' | 'medium';
|
|
39
|
+
required?: boolean;
|
|
40
|
+
grid?: GridConfig;
|
|
41
|
+
/**
|
|
42
|
+
* For Autocomplete async fetching
|
|
43
|
+
*/
|
|
44
|
+
fetchOptions?: (input: string) => Promise<Option[]>;
|
|
45
|
+
/**
|
|
46
|
+
* For dynamic visibility
|
|
47
|
+
*/
|
|
48
|
+
visibleIf?: (values: any) => boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Custom props for MUI components
|
|
51
|
+
*/
|
|
52
|
+
muiProps?: any;
|
|
53
|
+
}
|
|
54
|
+
interface FormBuilderProps {
|
|
55
|
+
fields: FieldConfig[];
|
|
56
|
+
schema: z.ZodType<any>;
|
|
57
|
+
onSubmit: (data: any) => void;
|
|
58
|
+
onCancel?: () => void;
|
|
59
|
+
onReset?: () => void;
|
|
60
|
+
submitText?: string;
|
|
61
|
+
cancelText?: string;
|
|
62
|
+
resetText?: string;
|
|
63
|
+
spacing?: number;
|
|
64
|
+
virtualize?: boolean;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
declare const FormBuilder: ({ fields, schema, onSubmit, onCancel, onReset, submitText, cancelText, resetText, spacing, virtualize, }: FormBuilderProps) => react_jsx_runtime.JSX.Element;
|
|
68
|
+
|
|
69
|
+
interface FormFieldProps {
|
|
70
|
+
fieldConfig: FieldConfig;
|
|
71
|
+
control: Control<any>;
|
|
72
|
+
}
|
|
73
|
+
declare const FormField: React.MemoExoticComponent<({ fieldConfig, control }: FormFieldProps) => react_jsx_runtime.JSX.Element | null>;
|
|
74
|
+
|
|
75
|
+
interface InputProps$5 {
|
|
76
|
+
fieldConfig: FieldConfig;
|
|
77
|
+
control: Control<any>;
|
|
78
|
+
}
|
|
79
|
+
declare const TextInput: React.MemoExoticComponent<({ fieldConfig, control }: InputProps$5) => react_jsx_runtime.JSX.Element>;
|
|
80
|
+
|
|
81
|
+
interface InputProps$4 {
|
|
82
|
+
fieldConfig: FieldConfig;
|
|
83
|
+
control: Control<any>;
|
|
84
|
+
}
|
|
85
|
+
declare const NumberInput: React.MemoExoticComponent<({ fieldConfig, control }: InputProps$4) => react_jsx_runtime.JSX.Element>;
|
|
86
|
+
|
|
87
|
+
interface InputProps$3 {
|
|
88
|
+
fieldConfig: FieldConfig;
|
|
89
|
+
control: Control<any>;
|
|
90
|
+
}
|
|
91
|
+
declare const SelectInput: React.MemoExoticComponent<({ fieldConfig, control }: InputProps$3) => react_jsx_runtime.JSX.Element>;
|
|
92
|
+
|
|
93
|
+
interface InputProps$2 {
|
|
94
|
+
fieldConfig: FieldConfig;
|
|
95
|
+
control: Control<any>;
|
|
96
|
+
}
|
|
97
|
+
declare const AutocompleteInput: React.MemoExoticComponent<({ fieldConfig, control }: InputProps$2) => react_jsx_runtime.JSX.Element>;
|
|
98
|
+
|
|
99
|
+
interface InputProps$1 {
|
|
100
|
+
fieldConfig: FieldConfig;
|
|
101
|
+
control: Control<any>;
|
|
102
|
+
}
|
|
103
|
+
declare const CheckboxInput: React.MemoExoticComponent<({ fieldConfig, control }: InputProps$1) => react_jsx_runtime.JSX.Element>;
|
|
104
|
+
|
|
105
|
+
interface InputProps {
|
|
106
|
+
fieldConfig: FieldConfig;
|
|
107
|
+
control: Control<any>;
|
|
108
|
+
}
|
|
109
|
+
declare const RadioInput: React.MemoExoticComponent<({ fieldConfig, control }: InputProps) => react_jsx_runtime.JSX.Element>;
|
|
110
|
+
|
|
111
|
+
declare const useFormBuilder: <T extends FieldValues = any>({ fields, schema, onReset, }: Pick<FormBuilderProps, "fields" | "schema" | "onReset">) => {
|
|
112
|
+
methods: react_hook_form.UseFormReturn<T, any, T>;
|
|
113
|
+
defaultValues: any;
|
|
114
|
+
handleFormReset: () => void;
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
declare function debounce<T extends (...args: any[]) => any>(func: T, wait: number): (...args: Parameters<T>) => void;
|
|
118
|
+
|
|
119
|
+
export { AutocompleteInput, CheckboxInput, type FieldConfig, FieldType, FormBuilder, type FormBuilderProps, FormField, type GridConfig, NumberInput, type Option, RadioInput, SelectInput, TextInput, debounce, useFormBuilder };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import {useController,useWatch,useForm,FormProvider}from'react-hook-form';import {Box,Typography,TextField,FormControl,Select,MenuItem,Checkbox,ListItemText,FormHelperText,Autocomplete,CircularProgress,RadioGroup,FormControlLabel,Radio,FormGroup,Grid,Paper,Button}from'@mui/material';import*as re from'react-window';import D,{useState,useMemo,useEffect}from'react';import {jsx,jsxs}from'react/jsx-runtime';import {zodResolver}from'@hookform/resolvers/zod';var te=(t=>(t.TEXT="text",t.NUMBER="number",t.SELECT="select",t.AUTOCOMPLETE="autocomplete",t.RADIO="radio",t.CHECKBOX="checkbox",t.TEXTAREA="textarea",t.DATE="date",t))(te||{});var d=D.memo(({label:e,required:n,disabled:o,error:r})=>jsx(Box,{sx:{mb:1,display:"flex",alignItems:"center"},children:jsxs(Typography,{variant:"subtitle2",sx:{fontWeight:600,color:r?"error.main":o?"text.disabled":"text.primary",fontSize:"0.875rem"},children:[e,n&&jsx(Box,{component:"span",sx:{color:"error.main",ml:.5},children:"*"})]})}));d.displayName="FieldLabel";var y=D.memo(({fieldConfig:e,control:n})=>{let{field:o,fieldState:{error:r}}=useController({name:e.name,control:n,defaultValue:e.defaultValue??""}),{ref:l,...u}=o;return jsxs(Box,{children:[jsx(d,{label:e.label,required:e.required,disabled:e.disabled,error:!!r}),jsx(TextField,{...u,slotProps:{htmlInput:{ref:l}},type:e.type==="date"?"date":"text",placeholder:e.placeholder,disabled:e.disabled,fullWidth:e.fullWidth??true,size:e.size??"medium",error:!!r,helperText:r?.message,multiline:e.type==="textarea",rows:e.type==="textarea"?4:1,...e.muiProps})]})});y.displayName="TextInput";var L=D.memo(({fieldConfig:e,control:n})=>{let{field:o,fieldState:{error:r}}=useController({name:e.name,control:n,defaultValue:e.defaultValue??""}),{ref:l,...u}=o;return jsxs(Box,{children:[jsx(d,{label:e.label,required:e.required,disabled:e.disabled,error:!!r}),jsx(TextField,{...u,slotProps:{htmlInput:{ref:l}},type:"number",placeholder:e.placeholder,disabled:e.disabled,fullWidth:e.fullWidth??true,size:e.size??"medium",error:!!r,helperText:r?.message,onChange:a=>{let s=a.target.value===""?"":Number(a.target.value);o.onChange(s);},...e.muiProps})]})});L.displayName="NumberInput";var A=D.memo(({fieldConfig:e,control:n})=>{let{field:o,fieldState:{error:r}}=useController({name:e.name,control:n,defaultValue:e.multiple?e.defaultValue??[]:e.defaultValue??""}),{ref:l,...u}=o;return jsxs(Box,{children:[jsx(d,{label:e.label,required:e.required,disabled:e.disabled,error:!!r}),jsxs(FormControl,{fullWidth:e.fullWidth??true,size:e.size??"medium",error:!!r,disabled:e.disabled,children:[jsx(Select,{...u,slotProps:{input:{ref:l}},multiple:e.multiple,displayEmpty:true,renderValue:e.multiple?a=>{let s=a;return !s||s.length===0?e.placeholder||"Select options":s.map(t=>e.options?.find(m=>m.value===t)?.label||t).join(", ")}:a=>a?e.options?.find(s=>s.value===a)?.label||a:e.placeholder||"Select an option",...e.muiProps,children:e.options?.map(a=>jsxs(MenuItem,{value:a.value,children:[e.multiple&&jsx(Checkbox,{checked:(o.value||[]).indexOf(a.value)>-1}),jsx(ListItemText,{primary:a.label})]},a.value))}),r&&jsx(FormHelperText,{children:r.message})]})]})});A.displayName="SelectInput";function g(e,n){let o=null;return (...r)=>{o&&clearTimeout(o),o=setTimeout(()=>e(...r),n);}}var W=D.memo(({fieldConfig:e,control:n})=>{let{field:o,fieldState:{error:r}}=useController({name:e.name,control:n,defaultValue:e.multiple?e.defaultValue??[]:e.defaultValue??null}),[l,u]=useState(false),[a,s]=useState(e.options||[]),[t,m]=useState(false),[x,f]=useState(""),v=useMemo(()=>g(async p=>{if(e.fetchOptions){m(true);try{let i=await e.fetchOptions(p);s(i);}catch(i){console.error("Failed to fetch options",i);}finally{m(false);}}},300),[e]);useEffect(()=>{!l&&e.fetchOptions&&s([]);},[l,e.fetchOptions]),useEffect(()=>{l&&e.fetchOptions&&v(x);},[l,x,v,e.fetchOptions]);let B=(p,i)=>{o.onChange(i);},{ref:F,...S}=o;return jsxs(Box,{children:[jsx(d,{label:e.label,required:e.required,disabled:e.disabled,error:!!r}),jsx(Autocomplete,{...S,multiple:e.multiple,open:l,onOpen:()=>u(true),onClose:()=>u(false),options:a,loading:t,disabled:e.disabled,getOptionLabel:p=>typeof p=="string"?p:p.label||"",isOptionEqualToValue:(p,i)=>p.value===i.value,onChange:B,onInputChange:(p,i)=>{f(i);},renderOption:(p,i,{selected:c})=>{let{key:z,...T}=p;return jsxs("li",{...T,children:[e.multiple&&jsx(Checkbox,{size:"small",style:{marginRight:8},checked:c}),i.label]},z)},renderInput:p=>{let{InputProps:i,inputProps:c,...z}=p;return jsx(TextField,{...z,placeholder:e.placeholder,size:e.size??"medium",error:!!r,helperText:r?.message,slotProps:{input:{...i,endAdornment:jsxs(D.Fragment,{children:[t?jsx(CircularProgress,{color:"inherit",size:20}):null,i?.endAdornment]})},htmlInput:{...c,ref:T=>{F(T),c?.ref&&(typeof c.ref=="function"?c.ref(T):c.ref.current=T);}}}})},...e.muiProps})]})});W.displayName="AutocompleteInput";var N=D.memo(({fieldConfig:e,control:n})=>{let{field:o,fieldState:{error:r}}=useController({name:e.name,control:n,defaultValue:e.defaultValue??""}),{ref:l,...u}=o;return jsxs(Box,{children:[jsx(d,{label:e.label,required:e.required,disabled:e.disabled,error:!!r}),jsxs(FormControl,{error:!!r,disabled:e.disabled,component:"fieldset",children:[jsx(RadioGroup,{...u,row:true,children:e.options?.map((a,s)=>jsx(FormControlLabel,{value:a.value,control:jsx(Radio,{size:e.size??"medium",slotProps:{input:{ref:s===0?l:void 0}}}),label:a.label},a.value))}),r&&jsx(FormHelperText,{children:r.message})]})]})});N.displayName="RadioInput";var G=D.memo(({fieldConfig:e,control:n})=>{let o=!!e.options,{field:r,fieldState:{error:l}}=useController({name:e.name,control:n,defaultValue:o?e.defaultValue??[]:e.defaultValue??false});if(o){let s=t=>{let m=r.value||[],x=m.includes(t)?m.filter(f=>f!==t):[...m,t];r.onChange(x);};return jsxs(Box,{children:[jsx(d,{label:e.label,required:e.required,disabled:e.disabled,error:!!l}),jsxs(FormControl,{error:!!l,component:"fieldset",disabled:e.disabled,children:[jsx(FormGroup,{row:true,children:e.options?.map((t,m)=>{let x=(r.value||[]).includes(t.value);return jsx(FormControlLabel,{control:jsx(Checkbox,{size:e.size??"medium",checked:x,onChange:()=>s(t.value),slotProps:{input:{ref:m===0?r.ref:void 0}}}),label:t.label},t.value)})}),l&&jsx(FormHelperText,{children:l.message})]})]})}let{ref:u,...a}=r;return jsxs(Box,{children:[jsx(d,{label:e.label,required:e.required,disabled:e.disabled,error:!!l}),jsxs(FormControl,{error:!!l,disabled:e.disabled,children:[jsx(FormControlLabel,{control:jsx(Checkbox,{...a,slotProps:{input:{ref:u}},size:e.size??"medium",checked:!!r.value,onChange:s=>r.onChange(s.target.checked)}),label:e.label}),l&&jsx(FormHelperText,{children:l.message})]})]})});G.displayName="CheckboxInput";var Ue={text:y,number:L,select:A,autocomplete:W,radio:N,checkbox:G,textarea:y,date:y},O=D.memo(({fieldConfig:e,control:n})=>{let o=useWatch({control:n});if(e.visibleIf&&!e.visibleIf(o))return null;let r=Ue[e.type]||y;return jsx(Grid,{size:e.grid||{xs:12},children:jsx(r,{fieldConfig:e,control:n})})});O.displayName="FormField";var j=({fields:e,schema:n,onReset:o})=>{let r=useMemo(()=>e.reduce((s,t)=>{let m=t.defaultValue;return m===void 0&&(t.multiple||t.type==="checkbox"&&t.options?m=[]:t.type==="checkbox"?m=false:m=""),s[t.name]=m,s},{}),[e]),l=useForm({resolver:zodResolver(n),defaultValues:r,mode:"onTouched",shouldFocusError:true}),{reset:u}=l;return {methods:l,defaultValues:r,handleFormReset:()=>{u(r),o&&o();}}};var er=re.FixedSizeList,yt=({fields:e,schema:n,onSubmit:o,onCancel:r,onReset:l,submitText:u="Submit",cancelText:a="Cancel",resetText:s="Reset",spacing:t=2,virtualize:m=false})=>{let{methods:x,handleFormReset:f}=j({fields:e,schema:n,onReset:l}),{handleSubmit:v,control:B,formState:{isSubmitting:F}}=x,S=({index:p,style:i})=>{let c=e[p];return jsx("div",{style:i,children:jsx(O,{fieldConfig:c,control:B},c.name)})};return jsx(FormProvider,{...x,children:jsx("form",{onSubmit:v(o),noValidate:true,children:jsxs(Paper,{elevation:0,sx:{p:0,bgcolor:"transparent"},children:[m?jsx(er,{height:500,itemCount:e.length,itemSize:100,width:"100%",children:S}):jsx(Grid,{container:true,spacing:t,children:e.map(p=>jsx(O,{fieldConfig:p,control:B},p.name))}),jsxs(Box,{sx:{mt:4,display:"flex",gap:2,justifyContent:"flex-end",flexWrap:"wrap"},children:[r&&jsx(Button,{variant:"outlined",color:"inherit",onClick:r,disabled:F,sx:{textTransform:"none",fontWeight:500},children:a}),(l||s)&&jsx(Button,{variant:"text",color:"secondary",onClick:f,disabled:F,sx:{textTransform:"none",fontWeight:500},children:s}),jsx(Button,{type:"submit",variant:"contained",color:"primary",loading:F,sx:{px:4,py:1,borderRadius:2,textTransform:"none",fontWeight:600},children:u})]})]})})})};export{W as AutocompleteInput,G as CheckboxInput,te as FieldType,yt as FormBuilder,O as FormField,L as NumberInput,N as RadioInput,A as SelectInput,y as TextInput,g as debounce,j as useFormBuilder};//# sourceMappingURL=index.js.map
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/form-builder/types/field.types.ts","../src/components/form-builder/inputs/FieldLabel.tsx","../src/components/form-builder/inputs/TextInput.tsx","../src/components/form-builder/inputs/NumberInput.tsx","../src/components/form-builder/inputs/SelectInput.tsx","../src/components/form-builder/utils/debounce.ts","../src/components/form-builder/inputs/AutocompleteInput.tsx","../src/components/form-builder/inputs/RadioInput.tsx","../src/components/form-builder/inputs/CheckboxInput.tsx","../src/components/form-builder/FormField.tsx","../src/hooks/useFormBuilder.ts","../src/components/form-builder/FormBuilder.tsx"],"names":["FieldType","FieldLabel","React","label","required","disabled","error","jsx","Box","jsxs","Typography","TextInput","fieldConfig","control","field","useController","fieldRef","fieldProps","TextField","NumberInput","e","val","SelectInput","FormControl","Select","selected","values","o","option","MenuItem","Checkbox","ListItemText","FormHelperText","debounce","func","wait","timeout","args","AutocompleteInput","open","setOpen","useState","options","setOptions","loading","setLoading","inputValue","setInputValue","debouncedFetch","useMemo","searchValue","results","err","useEffect","handleChange","_event","newValue","Autocomplete","value","newInputValue","props","key","otherProps","params","InputProps","inputProps","restParams","CircularProgress","node","RadioInput","RadioGroup","index","FormControlLabel","Radio","CheckboxInput","isGroup","handleGroupChange","currentValues","newValues","v","FormGroup","checked","fieldRegistry","FormField","useWatch","InputComponent","Grid","useFormBuilder","fields","schema","onReset","defaultValues","acc","defaultValue","methods","useForm","zodResolver","reset","VirtualList","FormBuilder","onSubmit","onCancel","submitText","cancelText","resetText","spacing","virtualize","handleFormReset","handleSubmit","isSubmitting","VirtualizedFieldList","style","FormProvider","Paper","Button"],"mappings":"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","file":"index.js","sourcesContent":["import { z } from 'zod';\r\n\r\nexport enum FieldType {\r\n TEXT = 'text',\r\n NUMBER = 'number',\r\n SELECT = 'select',\r\n AUTOCOMPLETE = 'autocomplete',\r\n RADIO = 'radio',\r\n CHECKBOX = 'checkbox',\r\n TEXTAREA = 'textarea',\r\n DATE = 'date'\r\n}\r\n\r\nexport interface Option {\r\n label: string;\r\n value: string | number;\r\n}\r\n\r\nexport interface GridConfig {\r\n xs?: number;\r\n sm?: number;\r\n md?: number;\r\n lg?: number;\r\n xl?: number;\r\n}\r\n\r\nexport interface FieldConfig {\r\n name: string;\r\n label: string;\r\n type: FieldType;\r\n defaultValue?: any;\r\n placeholder?: string;\r\n options?: Option[];\r\n multiple?: boolean;\r\n disabled?: boolean;\r\n fullWidth?: boolean;\r\n size?: 'small' | 'medium';\r\n required?: boolean;\r\n grid?: GridConfig;\r\n /**\r\n * For Autocomplete async fetching\r\n */\r\n fetchOptions?: (input: string) => Promise<Option[]>;\r\n /**\r\n * For dynamic visibility\r\n */\r\n visibleIf?: (values: any) => boolean;\r\n /**\r\n * Custom props for MUI components\r\n */\r\n muiProps?: any;\r\n}\r\n\r\nexport interface FormBuilderProps {\r\n fields: FieldConfig[];\r\n schema: z.ZodType<any>;\r\n onSubmit: (data: any) => void;\r\n onCancel?: () => void;\r\n onReset?: () => void;\r\n submitText?: string;\r\n cancelText?: string;\r\n resetText?: string;\r\n spacing?: number;\r\n virtualize?: boolean; // Enable if fields > 50\r\n}\r\n","import React from 'react';\r\nimport { Typography, Box } from '@mui/material';\r\n\r\ninterface FieldLabelProps {\r\n label: string;\r\n required?: boolean;\r\n disabled?: boolean;\r\n error?: boolean;\r\n}\r\n\r\nexport const FieldLabel = React.memo(({ label, required, disabled, error }: FieldLabelProps) => {\r\n return (\r\n <Box sx={{ mb: 1, display: 'flex', alignItems: 'center' }}>\r\n <Typography\r\n variant=\"subtitle2\"\r\n sx={{\r\n fontWeight: 600,\r\n color: error ? 'error.main' : disabled ? 'text.disabled' : 'text.primary',\r\n fontSize: '0.875rem',\r\n }}\r\n >\r\n {label}\r\n {required && (\r\n <Box component=\"span\" sx={{ color: 'error.main', ml: 0.5 }}>\r\n *\r\n </Box>\r\n )}\r\n </Typography>\r\n </Box>\r\n );\r\n});\r\n\r\nFieldLabel.displayName = 'FieldLabel';\r\n","import React from 'react';\r\nimport { TextField, Box } from '@mui/material';\r\nimport { useController, Control } from 'react-hook-form';\r\nimport { FieldConfig, FieldType } from '../types/field.types';\r\nimport { FieldLabel } from './FieldLabel';\r\n\r\ninterface InputProps {\r\n fieldConfig: FieldConfig;\r\n control: Control<any>;\r\n}\r\n\r\nexport const TextInput = React.memo(({ fieldConfig, control }: InputProps) => {\r\n const {\r\n field,\r\n fieldState: { error },\r\n } = useController({\r\n name: fieldConfig.name,\r\n control,\r\n defaultValue: fieldConfig.defaultValue ?? '',\r\n });\r\n\r\n const { ref: fieldRef, ...fieldProps } = field;\r\n\r\n return (\r\n <Box>\r\n <FieldLabel\r\n label={fieldConfig.label}\r\n required={fieldConfig.required}\r\n disabled={fieldConfig.disabled}\r\n error={!!error}\r\n />\r\n <TextField\r\n {...fieldProps}\r\n slotProps={{\r\n htmlInput: {\r\n ref: fieldRef\r\n }\r\n }}\r\n type={fieldConfig.type === FieldType.DATE ? 'date' : 'text'}\r\n placeholder={fieldConfig.placeholder}\r\n disabled={fieldConfig.disabled}\r\n fullWidth={fieldConfig.fullWidth ?? true}\r\n size={fieldConfig.size ?? 'medium'}\r\n error={!!error}\r\n helperText={error?.message}\r\n multiline={fieldConfig.type === FieldType.TEXTAREA}\r\n rows={fieldConfig.type === FieldType.TEXTAREA ? 4 : 1}\r\n {...fieldConfig.muiProps}\r\n />\r\n </Box>\r\n );\r\n});\r\n\r\nTextInput.displayName = 'TextInput';\r\n","import React from 'react';\r\nimport { TextField, Box } from '@mui/material';\r\nimport { useController, Control } from 'react-hook-form';\r\nimport { FieldConfig } from '../types/field.types';\r\nimport { FieldLabel } from './FieldLabel';\r\n\r\ninterface InputProps {\r\n fieldConfig: FieldConfig;\r\n control: Control<any>;\r\n}\r\n\r\nexport const NumberInput = React.memo(({ fieldConfig, control }: InputProps) => {\r\n const {\r\n field,\r\n fieldState: { error },\r\n } = useController({\r\n name: fieldConfig.name,\r\n control,\r\n defaultValue: fieldConfig.defaultValue ?? '',\r\n });\r\n\r\n const { ref: fieldRef, ...fieldProps } = field;\r\n\r\n return (\r\n <Box>\r\n <FieldLabel\r\n label={fieldConfig.label}\r\n required={fieldConfig.required}\r\n disabled={fieldConfig.disabled}\r\n error={!!error}\r\n />\r\n <TextField\r\n {...fieldProps}\r\n slotProps={{\r\n htmlInput: {\r\n ref: fieldRef\r\n }\r\n }}\r\n type=\"number\"\r\n placeholder={fieldConfig.placeholder}\r\n disabled={fieldConfig.disabled}\r\n fullWidth={fieldConfig.fullWidth ?? true}\r\n size={fieldConfig.size ?? 'medium'}\r\n error={!!error}\r\n helperText={error?.message}\r\n onChange={(e) => {\r\n const val = e.target.value === '' ? '' : Number(e.target.value);\r\n field.onChange(val);\r\n }}\r\n {...fieldConfig.muiProps}\r\n />\r\n </Box>\r\n );\r\n});\r\n\r\nNumberInput.displayName = 'NumberInput';\r\n","import React from 'react';\r\nimport {\r\n FormControl,\r\n Select,\r\n MenuItem,\r\n FormHelperText,\r\n Checkbox,\r\n ListItemText,\r\n Box,\r\n} from '@mui/material';\r\nimport { useController, Control } from 'react-hook-form';\r\nimport { FieldConfig } from '../types/field.types';\r\nimport { FieldLabel } from './FieldLabel';\r\n\r\ninterface InputProps {\r\n fieldConfig: FieldConfig;\r\n control: Control<any>;\r\n}\r\n\r\nexport const SelectInput = React.memo(({ fieldConfig, control }: InputProps) => {\r\n const {\r\n field,\r\n fieldState: { error },\r\n } = useController({\r\n name: fieldConfig.name,\r\n control,\r\n defaultValue: fieldConfig.multiple ? (fieldConfig.defaultValue ?? []) : (fieldConfig.defaultValue ?? ''),\r\n });\r\n\r\n const { ref: fieldRef, ...fieldProps } = field;\r\n\r\n return (\r\n <Box>\r\n <FieldLabel\r\n label={fieldConfig.label}\r\n required={fieldConfig.required}\r\n disabled={fieldConfig.disabled}\r\n error={!!error}\r\n />\r\n <FormControl\r\n fullWidth={fieldConfig.fullWidth ?? true}\r\n size={fieldConfig.size ?? 'medium'}\r\n error={!!error}\r\n disabled={fieldConfig.disabled}\r\n >\r\n <Select\r\n {...fieldProps}\r\n slotProps={{\r\n input: {\r\n ref: fieldRef\r\n }\r\n }}\r\n multiple={fieldConfig.multiple}\r\n displayEmpty\r\n renderValue={\r\n fieldConfig.multiple\r\n ? (selected) => {\r\n const values = selected as (string | number)[];\r\n if (!values || values.length === 0) return fieldConfig.placeholder || 'Select options';\r\n return values\r\n .map((val) => fieldConfig.options?.find((o) => o.value === val)?.label || val)\r\n .join(', ');\r\n }\r\n : (selected) => {\r\n if (!selected) return fieldConfig.placeholder || 'Select an option';\r\n return fieldConfig.options?.find((o) => o.value === selected)?.label || selected;\r\n }\r\n }\r\n {...fieldConfig.muiProps}\r\n >\r\n {fieldConfig.options?.map((option) => (\r\n <MenuItem key={option.value} value={option.value}>\r\n {fieldConfig.multiple && (\r\n <Checkbox checked={(field.value || []).indexOf(option.value) > -1} />\r\n )}\r\n <ListItemText primary={option.label} />\r\n </MenuItem>\r\n ))}\r\n </Select>\r\n {error && <FormHelperText>{error.message}</FormHelperText>}\r\n </FormControl>\r\n </Box>\r\n );\r\n});\r\n\r\nSelectInput.displayName = 'SelectInput';\r\n","export function debounce<T extends (...args: any[]) => any>(\r\n func: T,\r\n wait: number\r\n): (...args: Parameters<T>) => void {\r\n let timeout: ReturnType<typeof setTimeout> | null = null;\r\n return (...args: Parameters<T>) => {\r\n if (timeout) clearTimeout(timeout);\r\n timeout = setTimeout(() => func(...args), wait);\r\n };\r\n}\r\n","import React, { useState, useEffect, useMemo } from 'react';\r\nimport {\r\n Autocomplete,\r\n TextField,\r\n CircularProgress,\r\n Checkbox,\r\n Box,\r\n} from '@mui/material';\r\nimport { useController, Control } from 'react-hook-form';\r\nimport { FieldConfig, Option } from '../types/field.types';\r\nimport { debounce } from '../utils/debounce';\r\nimport { FieldLabel } from './FieldLabel';\r\n\r\ninterface InputProps {\r\n fieldConfig: FieldConfig;\r\n control: Control<any>;\r\n}\r\n\r\nexport const AutocompleteInput = React.memo(({ fieldConfig, control }: InputProps) => {\r\n const {\r\n field,\r\n fieldState: { error },\r\n } = useController({\r\n name: fieldConfig.name,\r\n control,\r\n defaultValue: fieldConfig.multiple ? (fieldConfig.defaultValue ?? []) : (fieldConfig.defaultValue ?? null),\r\n });\r\n\r\n const [open, setOpen] = useState(false);\r\n const [options, setOptions] = useState<Option[]>(fieldConfig.options || []);\r\n const [loading, setLoading] = useState(false);\r\n const [inputValue, setInputValue] = useState('');\r\n\r\n const debouncedFetch = useMemo(\r\n () =>\r\n debounce(async (searchValue: string) => {\r\n if (!fieldConfig.fetchOptions) return;\r\n setLoading(true);\r\n try {\r\n const results = await fieldConfig.fetchOptions(searchValue);\r\n setOptions(results);\r\n } catch (err) {\r\n console.error('Failed to fetch options', err);\r\n } finally {\r\n setLoading(false);\r\n }\r\n }, 300),\r\n [fieldConfig]\r\n );\r\n\r\n useEffect(() => {\r\n if (!open && fieldConfig.fetchOptions) {\r\n setOptions([]);\r\n }\r\n }, [open, fieldConfig.fetchOptions]);\r\n\r\n useEffect(() => {\r\n if (open && fieldConfig.fetchOptions) {\r\n debouncedFetch(inputValue);\r\n }\r\n }, [open, inputValue, debouncedFetch, fieldConfig.fetchOptions]);\r\n\r\n const handleChange = (_event: any, newValue: any) => {\r\n field.onChange(newValue);\r\n };\r\n\r\n const { ref: fieldRef, ...fieldProps } = field;\r\n\r\n return (\r\n <Box>\r\n <FieldLabel\r\n label={fieldConfig.label}\r\n required={fieldConfig.required}\r\n disabled={fieldConfig.disabled}\r\n error={!!error}\r\n />\r\n <Autocomplete\r\n {...fieldProps}\r\n multiple={fieldConfig.multiple}\r\n open={open}\r\n onOpen={() => setOpen(true)}\r\n onClose={() => setOpen(false)}\r\n options={options}\r\n loading={loading}\r\n disabled={fieldConfig.disabled}\r\n getOptionLabel={(option: any) => (typeof option === 'string' ? option : (option.label || ''))}\r\n isOptionEqualToValue={(option: any, value: any) => option.value === value.value}\r\n onChange={handleChange}\r\n onInputChange={(_event, newInputValue) => {\r\n setInputValue(newInputValue);\r\n }}\r\n renderOption={(props, option: any, { selected }) => {\r\n const { key, ...otherProps } = props;\r\n return (\r\n <li key={key} {...otherProps}>\r\n {fieldConfig.multiple && (\r\n <Checkbox\r\n size=\"small\"\r\n style={{ marginRight: 8 }}\r\n checked={selected}\r\n />\r\n )}\r\n {option.label}\r\n </li>\r\n );\r\n }}\r\n renderInput={(params) => {\r\n const { InputProps, inputProps, ...restParams } = params as any;\r\n return (\r\n <TextField\r\n {...restParams}\r\n placeholder={fieldConfig.placeholder}\r\n size={fieldConfig.size ?? 'medium'}\r\n error={!!error}\r\n helperText={error?.message}\r\n slotProps={{\r\n input: {\r\n ...InputProps,\r\n endAdornment: (\r\n <React.Fragment>\r\n {loading ? <CircularProgress color=\"inherit\" size={20} /> : null}\r\n {InputProps?.endAdornment}\r\n </React.Fragment>\r\n ),\r\n },\r\n htmlInput: {\r\n ...inputProps,\r\n ref: (node: HTMLInputElement | null) => {\r\n fieldRef(node);\r\n if (inputProps?.ref) {\r\n if (typeof inputProps.ref === 'function') {\r\n inputProps.ref(node);\r\n } else {\r\n inputProps.ref.current = node;\r\n }\r\n }\r\n },\r\n },\r\n }}\r\n />\r\n );\r\n }}\r\n {...fieldConfig.muiProps}\r\n />\r\n </Box>\r\n );\r\n});\r\n\r\nAutocompleteInput.displayName = 'AutocompleteInput';\r\n","import React from 'react';\r\nimport {\r\n FormControl,\r\n RadioGroup,\r\n FormControlLabel,\r\n Radio,\r\n FormHelperText,\r\n Box,\r\n} from '@mui/material';\r\nimport { useController, Control } from 'react-hook-form';\r\nimport { FieldConfig } from '../types/field.types';\r\nimport { FieldLabel } from './FieldLabel';\r\n\r\ninterface InputProps {\r\n fieldConfig: FieldConfig;\r\n control: Control<any>;\r\n}\r\n\r\nexport const RadioInput = React.memo(({ fieldConfig, control }: InputProps) => {\r\n const {\r\n field,\r\n fieldState: { error },\r\n } = useController({\r\n name: fieldConfig.name,\r\n control,\r\n defaultValue: fieldConfig.defaultValue ?? '',\r\n });\r\n\r\n const { ref: fieldRef, ...fieldProps } = field;\r\n\r\n return (\r\n <Box>\r\n <FieldLabel\r\n label={fieldConfig.label}\r\n required={fieldConfig.required}\r\n disabled={fieldConfig.disabled}\r\n error={!!error}\r\n />\r\n <FormControl error={!!error} disabled={fieldConfig.disabled} component=\"fieldset\">\r\n <RadioGroup {...fieldProps} row>\r\n {fieldConfig.options?.map((option, index) => (\r\n <FormControlLabel\r\n key={option.value}\r\n value={option.value}\r\n control={\r\n <Radio \r\n size={fieldConfig.size ?? 'medium'} \r\n slotProps={{ input: { ref: index === 0 ? fieldRef : undefined } } as any} \r\n />\r\n }\r\n label={option.label}\r\n />\r\n ))}\r\n </RadioGroup>\r\n {error && <FormHelperText>{error.message}</FormHelperText>}\r\n </FormControl>\r\n </Box>\r\n );\r\n});\r\n\r\nRadioInput.displayName = 'RadioInput';\r\n","import React from 'react';\r\nimport {\r\n FormControl,\r\n FormControlLabel,\r\n Checkbox,\r\n FormHelperText,\r\n FormGroup,\r\n Box,\r\n} from '@mui/material';\r\nimport { useController, Control } from 'react-hook-form';\r\nimport { FieldConfig } from '../types/field.types';\r\nimport { FieldLabel } from './FieldLabel';\r\n\r\ninterface InputProps {\r\n fieldConfig: FieldConfig;\r\n control: Control<any>;\r\n}\r\n\r\nexport const CheckboxInput = React.memo(({ fieldConfig, control }: InputProps) => {\r\n // Checkbox can be single boolean or group of strings\r\n const isGroup = !!fieldConfig.options;\r\n\r\n const {\r\n field,\r\n fieldState: { error },\r\n } = useController({\r\n name: fieldConfig.name,\r\n control,\r\n defaultValue: isGroup ? (fieldConfig.defaultValue ?? []) : (fieldConfig.defaultValue ?? false),\r\n });\r\n\r\n if (isGroup) {\r\n const handleGroupChange = (value: any) => {\r\n const currentValues = (field.value as any[]) || [];\r\n const newValues = currentValues.includes(value)\r\n ? currentValues.filter((v) => v !== value)\r\n : [...currentValues, value];\r\n field.onChange(newValues);\r\n };\r\n\r\n return (\r\n <Box>\r\n <FieldLabel\r\n label={fieldConfig.label}\r\n required={fieldConfig.required}\r\n disabled={fieldConfig.disabled}\r\n error={!!error}\r\n />\r\n <FormControl error={!!error} component=\"fieldset\" disabled={fieldConfig.disabled}>\r\n <FormGroup row>\r\n {fieldConfig.options?.map((option, index) => {\r\n const checked = (field.value || []).includes(option.value);\r\n return (\r\n <FormControlLabel\r\n key={option.value}\r\n control={\r\n <Checkbox\r\n size={fieldConfig.size ?? 'medium'}\r\n checked={checked}\r\n onChange={() => handleGroupChange(option.value)}\r\n slotProps={{ input: { ref: index === 0 ? field.ref : undefined } } as any}\r\n />\r\n }\r\n label={option.label}\r\n />\r\n );\r\n })}\r\n </FormGroup>\r\n {error && <FormHelperText>{error.message}</FormHelperText>}\r\n </FormControl>\r\n </Box>\r\n );\r\n }\r\n\r\n const { ref: fieldRef, ...fieldProps } = field;\r\n\r\n return (\r\n <Box>\r\n <FieldLabel\r\n label={fieldConfig.label}\r\n required={fieldConfig.required}\r\n disabled={fieldConfig.disabled}\r\n error={!!error}\r\n />\r\n <FormControl error={!!error} disabled={fieldConfig.disabled}>\r\n <FormControlLabel\r\n control={\r\n <Checkbox\r\n {...fieldProps}\r\n slotProps={{ input: { ref: fieldRef } } as any}\r\n size={fieldConfig.size ?? 'medium'}\r\n checked={!!field.value}\r\n onChange={(e) => field.onChange(e.target.checked)}\r\n />\r\n }\r\n label={fieldConfig.label}\r\n />\r\n {error && <FormHelperText>{error.message}</FormHelperText>}\r\n </FormControl>\r\n </Box>\r\n );\r\n});\r\n\r\nCheckboxInput.displayName = 'CheckboxInput';\r\n","import React from 'react';\r\nimport { Control, useWatch } from 'react-hook-form';\r\nimport { Grid } from '@mui/material';\r\nimport { FieldConfig, FieldType } from './types/field.types';\r\nimport { TextInput } from './inputs/TextInput';\r\nimport { NumberInput } from './inputs/NumberInput';\r\nimport { SelectInput } from './inputs/SelectInput';\r\nimport { AutocompleteInput } from './inputs/AutocompleteInput';\r\nimport { RadioInput } from './inputs/RadioInput';\r\nimport { CheckboxInput } from './inputs/CheckboxInput';\r\n\r\ninterface FormFieldProps {\r\n fieldConfig: FieldConfig;\r\n control: Control<any>;\r\n}\r\n\r\nconst fieldRegistry: Record<FieldType, React.ComponentType<any>> = {\r\n [FieldType.TEXT]: TextInput,\r\n [FieldType.NUMBER]: NumberInput,\r\n [FieldType.SELECT]: SelectInput,\r\n [FieldType.AUTOCOMPLETE]: AutocompleteInput,\r\n [FieldType.RADIO]: RadioInput,\r\n [FieldType.CHECKBOX]: CheckboxInput,\r\n [FieldType.TEXTAREA]: TextInput, // Uses same text component with multiline prop\r\n [FieldType.DATE]: TextInput, // Fallback for simple date or placeholder\r\n};\r\n\r\nexport const FormField = React.memo(({ fieldConfig, control }: FormFieldProps) => {\r\n // Watch all values for dynamic visibility check\r\n const values = useWatch({ control });\r\n \r\n if (fieldConfig.visibleIf && !fieldConfig.visibleIf(values)) {\r\n return null;\r\n }\r\n\r\n const InputComponent = fieldRegistry[fieldConfig.type] || TextInput;\r\n\r\n return (\r\n <Grid size={fieldConfig.grid || { xs: 12 }}>\r\n <InputComponent fieldConfig={fieldConfig} control={control} />\r\n </Grid>\r\n );\r\n});\r\n\r\nFormField.displayName = 'FormField';\r\n","import { useMemo } from 'react';\r\nimport { useForm, FieldValues } from 'react-hook-form';\r\nimport { zodResolver } from '@hookform/resolvers/zod';\r\nimport { FieldType, FormBuilderProps } from '../components/form-builder/types/field.types';\r\n\r\nexport const useFormBuilder = <T extends FieldValues = any>({\r\n fields,\r\n schema,\r\n onReset,\r\n}: Pick<FormBuilderProps, 'fields' | 'schema' | 'onReset'>) => {\r\n const defaultValues = useMemo(() => {\r\n return fields.reduce((acc, field) => {\r\n let defaultValue = field.defaultValue;\r\n\r\n if (defaultValue === undefined) {\r\n if (field.multiple || (field.type === FieldType.CHECKBOX && field.options)) {\r\n defaultValue = [];\r\n } else if (field.type === FieldType.CHECKBOX) {\r\n defaultValue = false;\r\n } else {\r\n defaultValue = '';\r\n }\r\n }\r\n\r\n acc[field.name] = defaultValue;\r\n return acc;\r\n }, {} as any);\r\n }, [fields]);\r\n\r\n const methods = useForm<T>({\r\n resolver: zodResolver(schema as any),\r\n defaultValues: defaultValues as any,\r\n mode: 'onTouched',\r\n shouldFocusError: true,\r\n });\r\n\r\n const { reset } = methods;\r\n\r\n const handleFormReset = () => {\r\n reset(defaultValues as any);\r\n if (onReset) onReset();\r\n };\r\n\r\n return {\r\n methods,\r\n defaultValues,\r\n handleFormReset,\r\n };\r\n};\r\n","import React from 'react';\r\nimport { FormProvider } from 'react-hook-form';\r\nimport { Box, Button, Grid, Paper } from '@mui/material';\r\nimport * as ReactWindow from 'react-window';\r\nimport { FormBuilderProps } from './types/field.types';\r\nimport { FormField } from './FormField';\r\nimport { useFormBuilder } from '../../hooks/useFormBuilder';\r\n\r\nconst VirtualList = (ReactWindow as any).FixedSizeList;\r\n\r\nexport const FormBuilder = ({\r\n fields,\r\n schema,\r\n onSubmit,\r\n onCancel,\r\n onReset,\r\n submitText = 'Submit',\r\n cancelText = 'Cancel',\r\n resetText = 'Reset',\r\n spacing = 2,\r\n virtualize = false,\r\n}: FormBuilderProps) => {\r\n const { methods, handleFormReset } = useFormBuilder({\r\n fields,\r\n schema,\r\n onReset,\r\n });\r\n\r\n const {\r\n handleSubmit,\r\n control,\r\n formState: { isSubmitting },\r\n } = methods;\r\n\r\n const VirtualizedFieldList = ({ index, style }: { index: number; style: React.CSSProperties }) => {\r\n const field = fields[index];\r\n return (\r\n <div style={style}>\r\n <FormField key={field.name} fieldConfig={field} control={control} />\r\n </div>\r\n );\r\n };\r\n\r\n return (\r\n <FormProvider {...methods}>\r\n <form onSubmit={handleSubmit(onSubmit)} noValidate>\r\n <Paper elevation={0} sx={{ p: 0, bgcolor: 'transparent' }}>\r\n {virtualize ? (\r\n <VirtualList\r\n height={500}\r\n itemCount={fields.length}\r\n itemSize={100}\r\n width=\"100%\"\r\n >\r\n {VirtualizedFieldList}\r\n </VirtualList>\r\n ) : (\r\n <Grid container spacing={spacing}>\r\n {fields.map((field) => (\r\n <FormField key={field.name} fieldConfig={field} control={control} />\r\n ))}\r\n </Grid>\r\n )}\r\n\r\n <Box sx={{ mt: 4, display: 'flex', gap: 2, justifyContent: 'flex-end', flexWrap: 'wrap' }}>\r\n {onCancel && (\r\n <Button\r\n variant=\"outlined\"\r\n color=\"inherit\"\r\n onClick={onCancel}\r\n disabled={isSubmitting}\r\n sx={{ textTransform: 'none', fontWeight: 500 }}\r\n >\r\n {cancelText}\r\n </Button>\r\n )}\r\n {(onReset || resetText) && (\r\n <Button\r\n variant=\"text\"\r\n color=\"secondary\"\r\n onClick={handleFormReset}\r\n disabled={isSubmitting}\r\n sx={{ textTransform: 'none', fontWeight: 500 }}\r\n >\r\n {resetText}\r\n </Button>\r\n )}\r\n <Button\r\n type=\"submit\"\r\n variant=\"contained\"\r\n color=\"primary\"\r\n loading={isSubmitting}\r\n sx={{\r\n px: 4,\r\n py: 1,\r\n borderRadius: 2,\r\n textTransform: 'none',\r\n fontWeight: 600,\r\n }}\r\n >\r\n {submitText}\r\n </Button>\r\n </Box>\r\n </Paper>\r\n </form>\r\n </FormProvider>\r\n );\r\n};\r\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mui-schema-form-builder",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A production-grade, schema-driven form builder for MUI and React Hook Form",
|
|
5
|
+
"author": "AI Studio Builder",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "./dist/index.cjs",
|
|
9
|
+
"module": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"import": "./dist/index.js",
|
|
15
|
+
"require": "./dist/index.cjs"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"dev": "vite --port=3000 --host=0.0.0.0",
|
|
23
|
+
"build": "tsup",
|
|
24
|
+
"build:example": "vite build",
|
|
25
|
+
"watch": "tsup --watch",
|
|
26
|
+
"clean": "rimraf dist",
|
|
27
|
+
"lint": "tsc --noEmit && eslint src",
|
|
28
|
+
"preview": "vite preview",
|
|
29
|
+
"typecheck": "tsc --noEmit",
|
|
30
|
+
"release": "npm run build && changeset publish",
|
|
31
|
+
"prepare": "husky"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@hookform/resolvers": "^5.2.2"
|
|
35
|
+
},
|
|
36
|
+
"peerDependencies": {
|
|
37
|
+
"@emotion/react": "^11.14.0",
|
|
38
|
+
"@emotion/styled": "^11.14.1",
|
|
39
|
+
"@mui/icons-material": "^5.14.0 || ^6.0.0 || ^9.0.1",
|
|
40
|
+
"@mui/material": "^5.14.0 || ^6.0.0 || ^9.0.0",
|
|
41
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
42
|
+
"react-dom": "^18.0.0 || ^19.0.0",
|
|
43
|
+
"react-hook-form": "^7.0.0",
|
|
44
|
+
"react-window": "^1.8.0",
|
|
45
|
+
"zod": "^3.0.0 || ^4.0.0"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@changesets/cli": "^2.28.1",
|
|
49
|
+
"@emotion/react": "^11.14.0",
|
|
50
|
+
"@emotion/styled": "^11.14.1",
|
|
51
|
+
"@mui/icons-material": "^9.0.1",
|
|
52
|
+
"@mui/material": "^9.0.1",
|
|
53
|
+
"@types/node": "^22.14.0",
|
|
54
|
+
"@types/react": "^19.0.1",
|
|
55
|
+
"@types/react-dom": "^19.0.1",
|
|
56
|
+
"@types/react-window": "^1.8.8",
|
|
57
|
+
"@typescript-eslint/eslint-plugin": "^5.62.0",
|
|
58
|
+
"@typescript-eslint/parser": "^5.62.0",
|
|
59
|
+
"@vitejs/plugin-react": "^5.0.4",
|
|
60
|
+
"eslint": "^8.57.1",
|
|
61
|
+
"eslint-plugin-react-hooks": "^4.6.2",
|
|
62
|
+
"husky": "^9.1.7",
|
|
63
|
+
"lint-staged": "^15.4.3",
|
|
64
|
+
"react": "^19.0.1",
|
|
65
|
+
"react-dom": "^19.0.1",
|
|
66
|
+
"react-hook-form": "^7.75.0",
|
|
67
|
+
"react-window": "^2.2.7",
|
|
68
|
+
"rimraf": "^6.0.1",
|
|
69
|
+
"tsup": "^8.4.0",
|
|
70
|
+
"typescript": "~5.8.2",
|
|
71
|
+
"vite": "^6.2.3",
|
|
72
|
+
"zod": "^4.4.3"
|
|
73
|
+
},
|
|
74
|
+
"sideEffects": false,
|
|
75
|
+
"publishConfig": {
|
|
76
|
+
"access": "public"
|
|
77
|
+
}
|
|
78
|
+
}
|