Skip to content

Commit

Permalink
fix: fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
s7dhansh committed Jun 28, 2021
1 parent b7b7cfa commit dfce98b
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 46 deletions.
2 changes: 2 additions & 0 deletions react-hook-form-mui/src/Input.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ const module = function({type, rhf}) {
return rhf ? require('./react-hook-form/Select').default : require('./forms/Select').default;
case 'buttons':
return rhf ? require('./react-hook-form/ButtonGroup').default : require('./forms/ButtonGroup').default;
case 'multiLevelButtons':
return rhf ? require('./react-hook-form/MultiButtonGroup').default : require('./forms/ButtonGroup').default;
}
return rhf ? require('./react-hook-form/TextField').default : require('./forms/TextField').default;
};
Expand Down
1 change: 0 additions & 1 deletion react-hook-form-mui/src/react-hook-form/ButtonGroup.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ export default function RHFButtonGroup(props) {

return (
<ButtonGroup
aria-label='text alignment'
exclusive
{...p}
/>
Expand Down
1 change: 0 additions & 1 deletion react-hook-form-mui/src/react-hook-form/InputArray.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import PropTypes from 'prop-types';
import React, {Fragment} from 'react';
import Grid from '@material-ui/core/Grid';
import Input from '../Input';
import Add from '@material-ui/icons/Add';
import Delete from '@material-ui/icons/Delete';
import IconButton from '@material-ui/core/IconButton';
import Button from '@material-ui/core/Button';
Expand Down
106 changes: 89 additions & 17 deletions react-hook-form-mui/src/react-hook-form/MultiButtonGroup.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,102 @@
import PropTypes from 'prop-types';
import React from 'react';
import {useController} from 'react-hook-form';
import {useRMController} from './useRMController';
import ButtonGroup from '../forms/ButtonGroup';

export default function RHFButtonGroup({control, name, ...rest}) {
function getNextOptions({
values,
options,
}) {
if (!values.length) return null;

for (let i = 0; i < options.length; i++) {
const matches = options[i].value.startsWith(values[0]);
if (!matches) continue;
return options[i].options;
}
return null;
}

function RecursiveButtonGroup({
values,
options,
onChange,
onBlur,
...rest
}) {
if (!values.length) return null;

const nextOptions = getNextOptions({values, options});
if (!nextOptions) return null;
const nextToNextOptions = getNextOptions({options: nextOptions, values: values.slice(1)});
return (
<>
<ButtonGroup
exclusive
onBlur={onBlur}
onChange={onChange}
options={nextOptions}
value={(values[1] + (nextToNextOptions ? '-' : '')) || values[0]}
{...rest}
/>
<RecursiveButtonGroup {...{options: nextOptions, values: values.slice(1), onChange, onBlur}}/>
</>
);
}

RecursiveButtonGroup.propTypes = {
onBlur: PropTypes.func,
onChange: PropTypes.func,
options: PropTypes.array,
values: PropTypes.array,
};

function getAllValues(value, startIndex = 0) {
if (!value || (startIndex >= value.length)) return [];

const ind = value.indexOf(':', startIndex);
if (ind === -1) {
const v = value.replace(/-$/, '');
return [
v,
...(v !== value ? [] : [v]),
];
}
return [
value.substr(0, ind),
...getAllValues(value, ind + 1),
];
}

// eslint-disable-next-line react/no-multi-comp
export default function RHFMultiButtonGroup(props) {
const {
field: {ref, ...inputProps},
} = useController({
name,
control,
rules: {required: rest.required},
defaultValue: rest.defaultValue,
});
// eslint-disable-next-line no-unused-vars
fieldState,
// eslint-disable-next-line no-unused-vars
formState,
...p
} = useRMController(props);

const {options} = props;
const {value, onChange, onBlur} = p;

const values = getAllValues(value);

return (
<ButtonGroup
aria-label='text alignment'
exclusive
ref={ref}
{...inputProps}
{...rest}
/>
<>
<ButtonGroup
exclusive
{...p}
value={values[0] + '-'}
/>
<RecursiveButtonGroup {...{options, values, onChange, onBlur}}/>
</>
);
}

RHFButtonGroup.propTypes = {
RHFMultiButtonGroup.propTypes = {
control: PropTypes.object,
name: PropTypes.string,
options: PropTypes.array,
};
94 changes: 67 additions & 27 deletions react-hook-form-mui/stories/react-hook-form/Fields.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,9 @@ import {MuiPickersUtilsProvider} from '@material-ui/pickers';
// import FilterField from '../components/FilterField';
// import DateTimePicker from '../components/DateTimePicker';
import {useWatch, useForm} from 'react-hook-form';

// const vvv = values => ({...values, files: (values.files || []).map(f => ({
// name: f.name,
// ...f,
// }))});
// import ButtonGroup from '../../src/forms/ButtonGroup';
import MultiButtonGroup from '../../src/react-hook-form/MultiButtonGroup';
// import CurrencyField from '../../src/react-hook-form/CurrencyField';

const eee = errors => Object.entries(errors).reduce((a, [k, {message, type}]) => ({...a, [k]: {message, type}}), {});

Expand All @@ -26,19 +24,57 @@ const arrayMeta = [
{name: 'mobile', label: 'Mobile', required: true, type: 'mobile', container: {xs: 7}, validate: true},
];

const validate = function(values) {
let errors = {};
if ((values.negotiable || {}).no || !(values.negotiable || {}).upto) return errors;
let diff = (values.current.value - values.negotiable.upto) * 100 / values.current.value;
let minDiff = values.current.value > 20000000 ? 7 : values.current.value > 10000000 ? 5 : 3, maxDiff = 10;
if (diff < minDiff || diff > maxDiff) {
errors = setIn(errors, 'negotiable.upto', diff > maxDiff
? `The difference must be less than ${maxDiff}%. Negotiable Upto must be more than ${currencify({amount: Math.round((100 - maxDiff) * values.current.value / 100), abbreviated: true})}`
: `The difference must be more than ${minDiff}%. Negotiable Upto must be less than ${currencify({amount: Math.round((100 - minDiff) * values.current.value / 100), abbreviated: true})}`
);
}
return errors;
};
const options = [
{value: 'a-', label: 'Apartment', options: [
{value: 'a', label: 'Any Apartment', finalValue: {type: 'apartment', gated: true, project: true}},
{value: 'a:n', label: 'Only Apartment', finalValue: {type: 'apartment', gated: true, project: true, penthouse: false, villament: false}},
{value: 'a:p', label: 'Penthouse', finalValue: {type: 'apartment', gated: true, project: true, penthouse: true, villament: false}},
{value: 'a:v', label: 'Villament', finalValue: {type: 'apartment', gated: true, project: true, villament: true, penthouse: false}},
]},
{
value: 'h-', label: 'House', options: [
// gated, project, single, villa, villaType mandatory
{value: 'h', label: 'Any House', finalValue: {type: 'house', villa: false}},
{
value: 'h:g-', label: 'House in Gated Community', options: [
{value: 'h:g', label: 'Any Gated Community House', finalValue: {type: 'house', gated: true, project: false, villa: false}},
{value: 'h:g:s', label: 'Single Family House (GC)', finalValue: {type: 'house', gated: true, project: false, single: true, villa: false, villaType: null}},
{value: 'h:g:m', label: 'Multi Family House (GC)', finalValue: {type: 'house', gated: true, project: false, single: false, villa: false, villaType: null}},
],
},
{value: 'h:p-', label: 'House in a Project', options: [
{value: 'h:p', label: 'Any House in a Project', finalValue: {type: 'house', gated: true, project: true, villa: false}},
{value: 'h:p:s', label: 'Single Family House in Project', finalValue: {type: 'house', gated: true, project: true, single: true, villa: false, villaType: null}},
{value: 'h:p:m', label: 'Multi Family House in Project', finalValue: {type: 'house', gated: true, project: true, single: false, villa: false, villaType: null}},
]},
{
value: 'h:i-', label: 'Independent House', options: [
{value: 'h:i', label: 'Any Independent House', finalValue: {type: 'house', gated: false, project: false, villa: false}},
{value: 'h:i:s', label: 'Single Family House (I)', finalValue: {type: 'house', gated: false, project: false, single: true, villa: false, villaType: null}},
{value: 'h:i:m', label: 'Multi Family House (I)', finalValue: {type: 'house', gated: false, project: false, single: false, villa: false, villaType: null}},
],
},
],
},
{
value: 'v-', label: 'Villa', options: [
// gated, project, single, villa, villaType mandatory
{value: 'v', label: 'Any Villa', finalValue: {type: 'house', gated: true, project: true, villa: true, single: true}},
{value: 'v:s', label: 'Standalone (Villa)', finalValue: {type: 'house', gated: true, project: true, villa: true, single: true, villaType: 'standalone'}},
{value: 'v:1', label: '1-2 (Villa)', finalValue: {type: 'house', gated: true, project: true, villa: true, single: true, villaType: '1-2'}},
{value: 'v:r', label: 'Row (Villa)', finalValue: {type: 'house', gated: true, project: true, villa: true, single: true, villaType: 'row'}},
],
},
{
value: 'p-', label: 'Plot', options: [
// gated, project mandatory
{value: 'p', label: 'Any Plot', finalValue: {type: 'plot'}},
{value: 'p:p', label: 'Gated Builder Plot', finalValue: {type: 'plot', gated: true, project: true}},
{value: 'p:g', label: 'Gated Community Plot', finalValue: {type: 'plot', gated: true, project: false}},
{value: 'p:i', label: 'Independent Plot', finalValue: {type: 'plot', gated: false, project: false}},
],
},
];

function IsolateReRender({control, name}) {
const values = useWatch({
Expand All @@ -47,7 +83,7 @@ function IsolateReRender({control, name}) {
});

return (
<div>
<div style={{marginTop: '7%'}}>
{JSON.stringify(values)}
</div>
); // only re-render at the component level
Expand All @@ -69,8 +105,9 @@ function DemoForm({onSubmit}) {
}, 1000);
};

console.log(10);
const defaultValues = {text: 'name'};
const {register, handleSubmit, formState: {errors, isSubmitting, isDirty, isValid}, control, getValues} = useForm({
const {handleSubmit, formState: {errors, isSubmitting, isDirty, isValid}, control} = useForm({
defaultValues,
mode: 'onChange',
});
Expand All @@ -80,7 +117,7 @@ function DemoForm({onSubmit}) {
return (
<MuiPickersUtilsProvider utils={DayJSUtils}>
<Grid container item spacing={1} style={{padding: '2rem'}}>
<form onSubmit={handleSubmit(onSubmit)} style={{width: '100%'}}>
<form onSubmit={handleSubmit(hSubmit)} style={{width: '100%'}}>
<Grid container item spacing={1} xs={12}>
<Grid item xs={6}>
<Typography>
Expand Down Expand Up @@ -149,19 +186,18 @@ function DemoForm({onSubmit}) {
<Grid container item spacing={1} style={{marginTop: '16px'}} xs={12}>
<Input compact container={{xs: 6}} control={control} label='Text' name='text' type='text'/>
<Input container={{xs: 6}} control={control} label='Text Area' multiline name='textArea' required type='textarea'/>
{/* <Input components={{input: CurrencyField}} control={control} name='currency' type='inr'/> */}
</Grid>
<Grid container item spacing={1} style={{marginTop: '16px'}} xs={12}>
<Input
components={{input: MultiButtonGroup}}
container={{xs: 6}}
control={control}
label='Button Groups'
name='buttonGroups'
options={[
{value: '1', label: '1'},
{value: '2', label: '2'},
]}
name='propertyType'
options={options} // or components={{Field: ButtonGroup}} or components={{input: ButtonGroup}}
required
type='buttons' // or components={{Field: ButtonGroup}} or components={{input: ButtonGroup}}
type='buttons'
/>
</Grid>
</Grid>
Expand All @@ -182,4 +218,8 @@ function DemoForm({onSubmit}) {
);
}

DemoForm.propTypes = {
onSubmit: PropTypes.func,
};

export default DemoForm;

0 comments on commit dfce98b

Please sign in to comment.