diff --git a/apps/docs/src/app/app.tsx b/apps/docs/src/app/app.tsx index 2622b92..7cbc907 100644 --- a/apps/docs/src/app/app.tsx +++ b/apps/docs/src/app/app.tsx @@ -163,6 +163,21 @@ export function App() { }, }, }, + { + id: 'form-radio-1', + groupType: 'form', + type: 'radio', + props: { + formId: '18', + id: 'radio-1', + name: 'fol', + defaultValue: '2', + radioInputsList: [ + { label: 'radio-num-1', value: '1' }, + { label: 'radio-num-2', value: '2' }, + ], + }, + }, ]; return ( diff --git a/packages/core/src/modules/form/src/components/fields/radio/radio.tsx b/packages/core/src/modules/form/src/components/fields/radio/radio.tsx new file mode 100644 index 0000000..5f2d228 --- /dev/null +++ b/packages/core/src/modules/form/src/components/fields/radio/radio.tsx @@ -0,0 +1,20 @@ +import { FC } from 'react'; + +import { FormControlLabel, Radio as MuiRadio } from '@mui/material'; + +import { RadioProps } from './radio.types'; + +import useRadio from './useRadio'; + +const Radio: FC = (props) => { + const { getFormControlLabelProps, getRadioInputProps } = useRadio(props); + + return ( + } + /> + ); +}; + +export default Radio; diff --git a/packages/core/src/modules/form/src/components/fields/radio/radio.types.ts b/packages/core/src/modules/form/src/components/fields/radio/radio.types.ts new file mode 100644 index 0000000..f8f5ca4 --- /dev/null +++ b/packages/core/src/modules/form/src/components/fields/radio/radio.types.ts @@ -0,0 +1,27 @@ +import { + FormControlLabelProps, + RadioGroupProps as MuiRadioGroupProps, + RadioProps as MuiRadioProps, +} from '@mui/material'; + +import { Api } from '@mui-builder/types/api.types'; +import { Script } from '@mui-builder/types/script.types'; + +import { Dependesies, FormId, Id } from '../../../types/public.types'; +import { Rule } from '../../../types/validation.types'; + +export type RadioProps = Omit & { + radioInputProps?: MuiRadioProps; +}; + +export type RadioGroupProps = MuiRadioGroupProps & { + id: Id; + formId: FormId; + script?: Script; + dependesies?: Dependesies; + propsController?: Record; + api?: Api; + rule?: Rule; + show?: boolean; + radioInputsList: RadioProps[]; +}; diff --git a/packages/core/src/modules/form/src/components/fields/radio/radioGroup.tsx b/packages/core/src/modules/form/src/components/fields/radio/radioGroup.tsx new file mode 100644 index 0000000..dc4eae1 --- /dev/null +++ b/packages/core/src/modules/form/src/components/fields/radio/radioGroup.tsx @@ -0,0 +1,22 @@ +import { FC } from 'react'; + +import { RadioGroup as MuiRadioGroup } from '@mui/material'; + +import { RadioGroupProps } from './radio.types'; + +import Radio from './radio'; +import useRadioGroup from './useRadioGroup'; + +const RadioGroup: FC = (props) => { + const { getRadioGroupProps, radioInputsList } = useRadioGroup(props); + + return ( + + {radioInputsList.map((radio) => ( + + ))} + + ); +}; + +export default RadioGroup; diff --git a/packages/core/src/modules/form/src/components/fields/radio/useRadio.ts b/packages/core/src/modules/form/src/components/fields/radio/useRadio.ts new file mode 100644 index 0000000..3c9fed5 --- /dev/null +++ b/packages/core/src/modules/form/src/components/fields/radio/useRadio.ts @@ -0,0 +1,13 @@ +import { RadioProps } from './radio.types'; + +const useRadio = (props: RadioProps) => { + const { radioInputProps, ...restRadioProps } = props; + + const getRadioInputProps = () => ({ ...radioInputProps }); + + const getFormControlLabelProps = () => ({ ...restRadioProps }); + + return { getRadioInputProps, getFormControlLabelProps }; +}; + +export default useRadio; diff --git a/packages/core/src/modules/form/src/components/fields/radio/useRadioGroup.ts b/packages/core/src/modules/form/src/components/fields/radio/useRadioGroup.ts new file mode 100644 index 0000000..1669b03 --- /dev/null +++ b/packages/core/src/modules/form/src/components/fields/radio/useRadioGroup.ts @@ -0,0 +1,84 @@ +import { useController, useWatch } from 'react-hook-form'; + +import useQueryBuilder from '@mui-builder/utils/useQueryBuilder/useQueryBuilder'; +import UseScript from '@mui-builder/utils/useScript/useScript'; + +import axios from 'axios'; + +import { RadioGroupProps } from './radio.types'; + +import useForms from '../../../hooks/useForms/useForms'; +import usePropsController from '../../../hooks/usePropsController/usePropsController'; +import useRule from '../../../hooks/useRule/useRule'; + +const useRadioGroup = (props: RadioGroupProps) => { + const { + id, + api, + script, + formId, + show = true, + dependesies, + defaultValue, + radioInputsList, + ...restRadioGroupProps + } = props; + + const { configs, queries } = api || {}; + + const { forms } = useForms(); + const formMethod = forms?.[formId]; + + const { setProps, propsController } = usePropsController(); + const newProps = propsController?.[id] || {}; + + useQueryBuilder({ + apiInstance: axios, + apiConfigs: configs ?? {}, + apiQuery: queries ?? {}, + formMethod, + formId, + forms, + }); + + // Handle Wtach Fields + useWatch({ + control: formMethod.control, + name: dependesies ?? [], + }); + + // Controller + const { + field, + formState: { errors }, + } = useController({ + name: id, + control: formMethod.control, + // disabled: restRadioGroupProps.disabled, + rules: useRule(restRadioGroupProps?.rule), + defaultValue, + }); + + const error = errors?.[id]; + + // Handle Script + const { scriptResult } = UseScript({ + script, + formMethod, + forms, + formId, + setProps, + }); + + const getRadioGroupProps = () => ({ + ...field, + ...restRadioGroupProps, + error, + ...scriptResult, + ...newProps, + }); + + return { getRadioGroupProps, radioInputsList }; +}; + +export default useRadioGroup; diff --git a/packages/core/src/modules/form/src/types/public.types.ts b/packages/core/src/modules/form/src/types/public.types.ts index 7994a36..9c1b422 100644 --- a/packages/core/src/modules/form/src/types/public.types.ts +++ b/packages/core/src/modules/form/src/types/public.types.ts @@ -1,6 +1,7 @@ import { SkeletonOwnProps } from '@mui/material'; import { SubmitFieldProps } from '../components/actions/submit/submit.types'; +import { RadioGroupProps } from '../components/fields/radio/radio.types'; import { TextProps } from '../components/fields/text/text.types'; import { Form } from '../hooks/useForms/useForms.types'; @@ -10,9 +11,9 @@ export type Forms = Record; export type Id = string; -export type FormTypes = 'field-text' | 'action-submit'; +export type FormTypes = 'field-text' | 'action-submit' | 'radio'; -export type FieldProps = TextProps | SubmitFieldProps; +export type FieldProps = TextProps | SubmitFieldProps | RadioGroupProps; export type Dependesies = string[]; diff --git a/packages/core/src/modules/form/src/utils/selector/formSelector.tsx b/packages/core/src/modules/form/src/utils/selector/formSelector.tsx index 9903b60..2d90801 100644 --- a/packages/core/src/modules/form/src/utils/selector/formSelector.tsx +++ b/packages/core/src/modules/form/src/utils/selector/formSelector.tsx @@ -1,6 +1,7 @@ import { FC, Fragment, Suspense, lazy } from 'react'; import { SubmitFieldProps } from '../../components/actions/submit/submit.types'; +import { RadioGroupProps } from '../../components/fields/radio/radio.types'; import { TextProps } from '../../components/fields/text/text.types'; import { FormSelectorProps } from './formSelector.types'; @@ -38,6 +39,17 @@ const FormSelector: FC = ({ ); + case 'radio': + SelectedComponent = lazy( + () => import('../../components/fields/radio/radioGroup') + ); + + return ( + }> + + + ); + default: SelectedComponent = Fragment;