Skip to content

Commit

Permalink
fix: expose react hook form in the input onClick, onBlur, onKeyUp
Browse files Browse the repository at this point in the history
  • Loading branch information
jlison committed Aug 31, 2019
1 parent b70f5b5 commit b78aa7d
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 24 deletions.
16 changes: 8 additions & 8 deletions src/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import useForm from 'react-hook-form';
import {useTranslation} from 'react-i18next';
import {Col, Form, Row} from 'reactstrap';

import {FormConfig, FormHeader, FormHooks} from './interfaces/FormConfig';
import {FormConfig, FormHeader, Hooks} from './interfaces/FormConfig';
import fetch from './utils/fetch';
import InputForm from './components/Input';
import SelectForm from './components/SingleSelect';
Expand All @@ -14,8 +14,8 @@ import ToggleForm from './components/Toggle';
interface Props extends FormProps<any> {
form: FormConfig[];
csrfUrl?: string;
getForm?: (formHooks: FormHooks) => any;
onSubmit: <T>(...args: any) => Promise<T | void> | T | void;
getForm?: (formHooks: Hooks) => any;
onSubmit: <T>(data: any, formHooks: Hooks) => Promise<T | void> | T | void;
valid?: {[key: string]: any};
}

Expand Down Expand Up @@ -44,10 +44,10 @@ export default ({
*/
useEffect(() => {
const setCsrfToken = async () => {
const {token} = await fetch(csrfUrl);
const {csrf} = await fetch(csrfUrl);

if (token && token.csrf) {
setCsrf(token.csrf);
if (csrf) {
setCsrf(csrf);
}
};

Expand All @@ -66,7 +66,7 @@ export default ({
key={`${dep.name}-${elementConfig.name}-${elementConfig.type}`}
elementConfig={elementConfig}
valid={valid}
{...formHooks}
formHooks={formHooks}
/>
);
});
Expand Down Expand Up @@ -173,7 +173,7 @@ export default ({
data.csrf = csrf;
}

return onSubmit(data);
return onSubmit(data, formHooks);
};

if (typeof getForm === 'function') {
Expand Down
28 changes: 18 additions & 10 deletions src/components/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,9 @@ import {
import {DefaultInputProps, FormConfig} from '../interfaces/FormConfig';

/** Input field */
export default ({
elementConfig,
errors,
formState,
getValues,
register,
triggerValidation,
valid,
}: DefaultInputProps) => {
export default ({elementConfig, formHooks, valid}: DefaultInputProps) => {
const {t} = useTranslation();
const {errors, formState, getValues, register, triggerValidation} = formHooks;
const values = getValues();

const {addon, className, name, placeholder} = elementConfig;
Expand Down Expand Up @@ -73,7 +66,22 @@ export default ({
}
invalid={!!errors[name]}
placeholder={t(placeholder)}
onBlur={() => triggerValidation([{name}])}
onBlur={(e) => {
triggerValidation([{name}]);
if (elementConfig.onBlur) {
elementConfig.onBlur(e, formHooks);
}
}}
onKeyUp={(e) => {
if (elementConfig.onKeyUp) {
elementConfig.onKeyUp(e, formHooks);
}
}}
onFocus={(e) => {
if (elementConfig.onFocus) {
elementConfig.onFocus(e, formHooks);
}
}}
/>
<Label
for={name}
Expand Down
13 changes: 12 additions & 1 deletion src/components/SingleSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ interface Props extends DefaultInputProps {
}

/** Render a generic single select input */
export default ({elementConfig, formState, register, setValue}: Props) => {
export default ({elementConfig, formHooks}: Props) => {
const {
className,
isMulti,
Expand All @@ -27,6 +27,7 @@ export default ({elementConfig, formState, register, setValue}: Props) => {
placeholder,
required,
} = elementConfig;
const {formState, register, setValue} = formHooks;
const {touched} = formState as FormProps['formState'];
const {t} = useTranslation();
const [values, setReactSelectValue] = useState({selectedOption: []} as any);
Expand Down Expand Up @@ -73,6 +74,16 @@ export default ({elementConfig, formState, register, setValue}: Props) => {
options={translateLabels(options as SelectSelectionInterface[])}
value={translateLabels(values.selectedOption)}
isMulti={isMulti || false}
onBlur={(e) => {
if (elementConfig.onBlur) {
elementConfig.onBlur(e, formHooks);
}
}}
onFocus={(e) => {
if (elementConfig.onFocus) {
elementConfig.onFocus(e, formHooks);
}
}}
/>
<Label
for={name}
Expand Down
8 changes: 7 additions & 1 deletion src/components/Toggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {Input, Label} from 'reactstrap';
import {DefaultInputProps} from '../interfaces/FormConfig';

/** Toggle button */
export default ({elementConfig, register, watch}: DefaultInputProps) => {
export default ({elementConfig, formHooks}: DefaultInputProps) => {
const {
className,
name,
Expand All @@ -20,6 +20,7 @@ export default ({elementConfig, register, watch}: DefaultInputProps) => {
placeholder,
} = elementConfig;
const {t} = useTranslation();
const {register, watch} = formHooks;
const isToggled = watch(name);

return (
Expand All @@ -39,6 +40,11 @@ export default ({elementConfig, register, watch}: DefaultInputProps) => {
validate,
})}
placeholder={t(placeholder)}
onClick={(e) => {
if (elementConfig.onClick) {
elementConfig.onClick(e, formHooks);
}
}}
/>
<span className={`rbf-slider ${shape ? shape : 'round'}`}>
<span
Expand Down
28 changes: 24 additions & 4 deletions src/interfaces/FormConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,35 @@ export interface FormConfig extends RegisterInput {
color?: string;
block?: boolean;
disabled?: boolean;
onKeyUp?: (
e: React.FormEvent<HTMLInputElement>,
formHooks: Hooks,
) => Promise<void> | void;
onBlur?: (
e: React.FormEvent<HTMLInputElement> | React.FocusEvent<HTMLElement>,
formHooks: Hooks,
) => Promise<void> | void;
onFocus?: (
e: React.FormEvent<HTMLInputElement> | React.FocusEvent<HTMLElement>,
formHooks: Hooks,
) => Promise<void> | void;
onClick?: (
e: React.FormEvent<HTMLInputElement>,
formHooks: Hooks,
) => Promise<void> | void;
}

export interface DefaultInputProps
extends Omit<Partial<FormProps>, 'formState'> {
elementConfig: FormConfig;
export interface Hooks extends Omit<Partial<FormProps>, 'formState'> {
formState: FormProps['formState'] | unknown[] | unknown;
csrf?: string;
}

export interface DefaultInputProps {
formHooks: Hooks;
elementConfig: FormConfig;
valid?: {[key: string]: any};
}

export interface FormHooks extends Omit<DefaultInputProps, 'elementConfig'> {
csrf: string;
csrf?: string;
}

0 comments on commit b78aa7d

Please sign in to comment.