Skip to content

Commit

Permalink
feat(form): radio input with radio group component
Browse files Browse the repository at this point in the history
  • Loading branch information
erfanmoghadasi committed Apr 29, 2024
1 parent 8e4fdc1 commit 944db6b
Show file tree
Hide file tree
Showing 8 changed files with 196 additions and 2 deletions.
15 changes: 15 additions & 0 deletions apps/docs/src/app/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down
Original file line number Diff line number Diff line change
@@ -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<RadioProps> = (props) => {
const { getFormControlLabelProps, getRadioInputProps } = useRadio(props);

return (
<FormControlLabel
{...getFormControlLabelProps()}
control={<MuiRadio {...getRadioInputProps()} />}
/>
);
};

export default Radio;
Original file line number Diff line number Diff line change
@@ -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<FormControlLabelProps, 'control'> & {
radioInputProps?: MuiRadioProps;
};

export type RadioGroupProps = MuiRadioGroupProps & {
id: Id;
formId: FormId;
script?: Script;
dependesies?: Dependesies;
propsController?: Record<string, any>;
api?: Api;
rule?: Rule;
show?: boolean;
radioInputsList: RadioProps[];
};
Original file line number Diff line number Diff line change
@@ -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<RadioGroupProps> = (props) => {
const { getRadioGroupProps, radioInputsList } = useRadioGroup(props);

return (
<MuiRadioGroup {...getRadioGroupProps()}>
{radioInputsList.map((radio) => (
<Radio key={radio.id} {...radio} />
))}
</MuiRadioGroup>
);
};

export default RadioGroup;
Original file line number Diff line number Diff line change
@@ -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;
Original file line number Diff line number Diff line change
@@ -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;
5 changes: 3 additions & 2 deletions packages/core/src/modules/form/src/types/public.types.ts
Original file line number Diff line number Diff line change
@@ -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';

Expand All @@ -10,9 +11,9 @@ export type Forms = Record<string, Form>;

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[];

Expand Down
12 changes: 12 additions & 0 deletions packages/core/src/modules/form/src/utils/selector/formSelector.tsx
Original file line number Diff line number Diff line change
@@ -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';

Expand Down Expand Up @@ -38,6 +39,17 @@ const FormSelector: FC<FormSelectorProps> = ({
</Suspense>
);

case 'radio':
SelectedComponent = lazy(
() => import('../../components/fields/radio/radioGroup')
);

return (
<Suspense key={fieldProps.id} fallback={<SubmitLoading {...loading} />}>
<SelectedComponent {...(fieldProps as RadioGroupProps)} />
</Suspense>
);

default:
SelectedComponent = Fragment;

Expand Down

0 comments on commit 944db6b

Please sign in to comment.