Skip to content

Commit

Permalink
feat: update to react-hook-form v7
Browse files Browse the repository at this point in the history
BREAKING CHANGE: Require react-hook-form >= 7
  • Loading branch information
jorisre authored Jan 28, 2021
1 parent e76743d commit 5fdc7f9
Show file tree
Hide file tree
Showing 23 changed files with 183 additions and 79 deletions.
10 changes: 7 additions & 3 deletions joi/src/__tests__/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,20 @@ interface Props {
}

function TestComponent({ onSubmit }: Props) {
const { register, errors, handleSubmit } = useForm<FormData>({
const {
register,
formState: { errors },
handleSubmit,
} = useForm<FormData>({
resolver: joiResolver(schema), // Useful to check TypeScript regressions
});

return (
<form onSubmit={handleSubmit(onSubmit)}>
<input name="username" ref={register} />
<input {...register('username')} />
{errors.username && <span role="alert">{errors.username.message}</span>}

<input name="password" ref={register} />
<input {...register('password')} />
{errors.password && <span role="alert">{errors.password.message}</span>}

<button type="submit">submit</button>
Expand Down
26 changes: 20 additions & 6 deletions joi/src/__tests__/joi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ describe('joiResolver', () => {
const validateAsyncSpy = jest.spyOn(schema, 'validateAsync');
const validateSpy = jest.spyOn(schema, 'validate');

const result = await joiResolver(schema)(data);
const result = await joiResolver(schema)(data, undefined, { fields: {} });

expect(validateSpy).not.toHaveBeenCalled();
expect(validateAsyncSpy).toHaveBeenCalledTimes(1);
Expand All @@ -62,7 +62,11 @@ describe('joiResolver', () => {
const validateAsyncSpy = jest.spyOn(schema, 'validateAsync');
const validateSpy = jest.spyOn(schema, 'validate');

const result = await joiResolver(schema, undefined, { mode: 'sync' })(data);
const result = await joiResolver(schema, undefined, { mode: 'sync' })(
data,
undefined,
{ fields: {} },
);

expect(validateAsyncSpy).not.toHaveBeenCalled();
expect(validateSpy).toHaveBeenCalledTimes(1);
Expand All @@ -76,7 +80,7 @@ describe('joiResolver', () => {
birthYear: 'birthYear',
};

const result = await joiResolver(schema)(data);
const result = await joiResolver(schema)(data, undefined, { fields: {} });

expect(result).toMatchSnapshot();
});
Expand All @@ -91,7 +95,11 @@ describe('joiResolver', () => {
const validateAsyncSpy = jest.spyOn(schema, 'validateAsync');
const validateSpy = jest.spyOn(schema, 'validate');

const result = await joiResolver(schema, undefined, { mode: 'sync' })(data);
const result = await joiResolver(schema, undefined, { mode: 'sync' })(
data,
undefined,
{ fields: {} },
);

expect(validateAsyncSpy).not.toHaveBeenCalled();
expect(validateSpy).toHaveBeenCalledTimes(1);
Expand All @@ -105,7 +113,10 @@ describe('joiResolver', () => {
birthYear: 'birthYear',
};

const result = await joiResolver(schema)(data, undefined, true);
const result = await joiResolver(schema)(data, undefined, {
fields: {},
criteriaMode: 'all',
});

expect(result).toMatchSnapshot();
});
Expand All @@ -120,7 +131,10 @@ describe('joiResolver', () => {
const result = await joiResolver(schema, undefined, { mode: 'sync' })(
data,
undefined,
true,
{
fields: {},
criteriaMode: 'all',
},
);

expect(result).toMatchSnapshot();
Expand Down
4 changes: 2 additions & 2 deletions joi/src/joi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export const joiResolver: Resolver = (
abortEarly: false,
},
{ mode } = { mode: 'async' },
) => async (values, _, validateAllFieldCriteria = false) => {
) => async (values, _, { criteriaMode }) => {
try {
let result;
if (mode === 'async') {
Expand All @@ -73,7 +73,7 @@ export const joiResolver: Resolver = (
return {
values: {},
errors: transformToNestObject(
parseErrorSchema(e, validateAllFieldCriteria),
parseErrorSchema(e, criteriaMode === 'all'),
),
};
}
Expand Down
7 changes: 4 additions & 3 deletions joi/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
FieldValues,
ResolverOptions,
ResolverResult,
UnpackNestedValue,
} from 'react-hook-form';
Expand All @@ -8,9 +9,9 @@ import type { AsyncValidationOptions, Schema } from 'joi';
export type Resolver = <T extends Schema>(
schema: T,
schemaOptions?: AsyncValidationOptions,
resolverOptions?: { mode: 'async' | 'sync' },
factoryOptions?: { mode: 'async' | 'sync' },
) => <TFieldValues extends FieldValues, TContext>(
values: UnpackNestedValue<TFieldValues>,
context?: TContext,
validateAllFieldCriteria?: boolean,
context: TContext | undefined,
options: ResolverOptions<TFieldValues>,
) => Promise<ResolverResult<TFieldValues>>;
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@
"prettier": "^2.2.1",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-hook-form": "^6.14.2",
"react-hook-form": "^7.0.0-alpha.0",
"semantic-release": "^17.3.6",
"superstruct": "^0.13.3",
"ts-jest": "^26.4.4",
Expand All @@ -139,7 +139,7 @@
"zod": "^1.11.11"
},
"peerDependencies": {
"react-hook-form": ">=6.6.0"
"react-hook-form": "^7.0.0"
},
"husky": {
"hooks": {
Expand Down
10 changes: 7 additions & 3 deletions superstruct/src/__tests__/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,20 @@ interface Props {
}

function TestComponent({ onSubmit }: Props) {
const { register, errors, handleSubmit } = useForm<FormData>({
const {
register,
formState: { errors },
handleSubmit,
} = useForm<FormData>({
resolver: superstructResolver(schema), // Useful to check TypeScript regressions
});

return (
<form onSubmit={handleSubmit(onSubmit)}>
<input name="username" ref={register} />
<input {...register('username')} />
{errors.username && <span role="alert">{errors.username.message}</span>}

<input name="password" ref={register} />
<input {...register('password')} />
{errors.password && <span role="alert">{errors.password.message}</span>}

<button type="submit">submit</button>
Expand Down
13 changes: 10 additions & 3 deletions superstruct/src/__tests__/superstruct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ describe('superstructResolver', () => {
enabled: true,
};

const result = await superstructResolver(schema)(data);
const result = await superstructResolver(schema)(data, undefined, {
fields: {},
});

expect(result).toEqual({ errors: {}, values: data });
});
Expand All @@ -53,7 +55,9 @@ describe('superstructResolver', () => {
birthYear: 'birthYear',
};

const result = await superstructResolver(schema)(data);
const result = await superstructResolver(schema)(data, undefined, {
fields: {},
});

expect(result).toMatchSnapshot();
});
Expand All @@ -65,7 +69,10 @@ describe('superstructResolver', () => {
birthYear: 'birthYear',
};

const result = await superstructResolver(schema)(data, undefined, true);
const result = await superstructResolver(schema)(data, undefined, {
fields: {},
criteriaMode: 'all',
});

expect(result).toMatchSnapshot();
});
Expand Down
4 changes: 2 additions & 2 deletions superstruct/src/superstruct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,15 @@ const parseErrorSchema = (
export const superstructResolver: Resolver = (schema, options) => async (
values,
_context,
validateAllFieldCriteria = false,
{ criteriaMode },
) => {
const [errors, result] = validate(values, schema, options);

if (errors != null) {
return {
values: {},
errors: transformToNestObject(
parseErrorSchema(errors, validateAllFieldCriteria),
parseErrorSchema(errors, criteriaMode === 'all'),
),
};
}
Expand Down
7 changes: 4 additions & 3 deletions superstruct/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
FieldValues,
ResolverOptions,
ResolverResult,
UnpackNestedValue,
} from 'react-hook-form';
Expand All @@ -9,9 +10,9 @@ type Options = Parameters<typeof validate>[2];

export type Resolver = <T extends Struct<any, any>>(
schema: T,
options?: Options,
factoryOtions?: Options,
) => <TFieldValues extends FieldValues, TContext>(
values: UnpackNestedValue<TFieldValues>,
context?: TContext,
validateAllFieldCriteria?: boolean,
context: TContext | undefined,
options: ResolverOptions<TFieldValues>,
) => Promise<ResolverResult<TFieldValues>>;
10 changes: 7 additions & 3 deletions vest/src/__tests__/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,20 @@ interface Props {
}

function TestComponent({ onSubmit }: Props) {
const { register, errors, handleSubmit } = useForm<FormData>({
const {
register,
formState: { errors },
handleSubmit,
} = useForm<FormData>({
resolver: vestResolver(validationSuite), // Useful to check TypeScript regressions
});

return (
<form onSubmit={handleSubmit(onSubmit)}>
<input name="username" ref={register} />
<input {...register('username')} />
{errors.username && <span role="alert">{errors.username.message}</span>}

<input name="password" ref={register} />
<input {...register('password')} />
{errors.password && <span role="alert">{errors.password.message}</span>}

<button type="submit">submit</button>
Expand Down
28 changes: 22 additions & 6 deletions vest/src/__tests__/vest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ describe('vestResolver', () => {
data: 'test',
},
};
expect(await vestResolver(validationSuite)(data)).toEqual({
expect(
await vestResolver(validationSuite)(data, undefined, { fields: {} }),
).toEqual({
values: data,
errors: {},
});
Expand All @@ -55,7 +57,11 @@ describe('vestResolver', () => {
},
};
expect(
await vestResolver(validationSuite, undefined, { mode: 'sync' })(data),
await vestResolver(validationSuite, undefined, { mode: 'sync' })(
data,
undefined,
{ fields: {} },
),
).toEqual({
values: data,
errors: {},
Expand All @@ -71,7 +77,9 @@ describe('vestResolver', () => {
},
};

expect(await vestResolver(validationSuite)(data)).toMatchSnapshot();
expect(
await vestResolver(validationSuite)(data, undefined, { fields: {} }),
).toMatchSnapshot();
});

it('should return single error message from vestResolver when validation fails and validateAllFieldCriteria set to false and `mode: sync`', async () => {
Expand All @@ -84,7 +92,11 @@ describe('vestResolver', () => {
};

expect(
await vestResolver(validationSuite, undefined, { mode: 'sync' })(data),
await vestResolver(validationSuite, undefined, { mode: 'sync' })(
data,
undefined,
{ fields: {} },
),
).toMatchSnapshot();
});

Expand All @@ -98,7 +110,11 @@ describe('vestResolver', () => {
};

expect(
await vestResolver(validationSuite)(data, {}, true),
await vestResolver(validationSuite)(
data,
{},
{ fields: {}, criteriaMode: 'all' },
),
).toMatchSnapshot();
});

Expand All @@ -115,7 +131,7 @@ describe('vestResolver', () => {
await vestResolver(validationSuite, undefined, { mode: 'sync' })(
data,
{},
true,
{ fields: {}, criteriaMode: 'all' },
),
).toMatchSnapshot();
});
Expand Down
7 changes: 4 additions & 3 deletions vest/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
FieldValues,
ResolverOptions,
ResolverResult,
UnpackNestedValue,
} from 'react-hook-form';
Expand All @@ -10,11 +11,11 @@ export type ICreateResult = ReturnType<typeof Vest.create>;
export type Resolver = (
schema: ICreateResult,
schemaOptions?: never,
resolverOptions?: { mode: 'async' | 'sync' },
factoryOptions?: { mode: 'async' | 'sync' },
) => <TFieldValues extends FieldValues, TContext>(
values: UnpackNestedValue<TFieldValues>,
context?: TContext,
validateAllFieldCriteria?: boolean,
context: TContext | undefined,
options: ResolverOptions<TFieldValues>,
) => Promise<ResolverResult<TFieldValues>>;

export type VestErrors = Record<string, string[]>;
4 changes: 2 additions & 2 deletions vest/src/vest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const vestResolver: Resolver = (
schema,
_,
{ mode } = { mode: 'async' },
) => async (values, _context, validateAllFieldCriteria = false) => {
) => async (values, _context, { criteriaMode }) => {
let result: IVestResult | DraftResult;
if (mode === 'async') {
const validateSchema = promisify(schema);
Expand All @@ -50,7 +50,7 @@ export const vestResolver: Resolver = (
return {
values: {},
errors: transformToNestObject(
parseErrorSchema(errors, validateAllFieldCriteria),
parseErrorSchema(errors, criteriaMode === 'all'),
),
};
};
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8107,10 +8107,10 @@ react-dom@^17.0.1:
object-assign "^4.1.1"
scheduler "^0.20.1"

react-hook-form@^6.14.2:
version "6.14.2"
resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-6.14.2.tgz#60ab0b5367b220a3d96aa0b17bd0f13f9d8c326a"
integrity sha512-GgDUuT3Yfhl1BOcMl862uAFbCixSomtm3CVlQQ1qVu9Tq5BN2uUIRUIXP8l2Gy99eLUrBqU9x4E7N+si9cnvaw==
react-hook-form@^7.0.0-alpha.0:
version "7.0.0-alpha.0"
resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.0.0-alpha.0.tgz#e4d6f58308e99c9667c901809c4f729209f58257"
integrity sha512-p7zDRjVrDVRgrCiXyjbyWLdluenfDLWRT0xO9In5n9E8Kv2+J9mjULm7ElMcJ4+7pcfrz6vVQzTq/lSVxbAJqA==

react-is@^17.0.1:
version "17.0.1"
Expand Down
Loading

0 comments on commit 5fdc7f9

Please sign in to comment.