Skip to content

Commit

Permalink
feat: added built-in support for yup validation schema
Browse files Browse the repository at this point in the history
  • Loading branch information
logaretm committed Jul 15, 2020
1 parent 0802512 commit e436b75
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 4 deletions.
29 changes: 25 additions & 4 deletions packages/core/src/useField.ts
Expand Up @@ -26,7 +26,8 @@ type RuleExpression = MaybeReactive<string | Record<string, any> | GenericValida
export function useField(fieldName: MaybeReactive<string>, rules: RuleExpression, opts?: Partial<FieldOptions>) {
const { value, form, immediate, bails, disabled } = normalizeOptions(opts);
const { meta, errors, failedRules, onBlur, handleChange, reset, patch } = useValidationState(value);
let schemaValidation: GenericValidateFunction | string | Record<string, any>;
// eslint-disable-next-line prefer-const
let schemaValidation: GenericValidateFunction | string | Record<string, any> | undefined;
const normalizedRules = computed(() => {
return normalizeRules(schemaValidation || unwrap(rules));
});
Expand Down Expand Up @@ -97,9 +98,7 @@ export function useField(fieldName: MaybeReactive<string>, rules: RuleExpression
form.register(field);

// set the rules if present in schema
if (form.schema?.[unwrap(fieldName)]) {
schemaValidation = form.schema[unwrap(fieldName)];
}
schemaValidation = extractRuleFromSchema(form.schema, unwrap(fieldName));

// extract cross-field dependencies in a computed prop
const dependencies = computed(() => {
Expand Down Expand Up @@ -270,3 +269,25 @@ function useAriAttrs(fieldName: MaybeReactive<string>, meta: Record<Flag, Ref<bo
};
});
}

/**
* Extracts the validation rules from a schema
*/
function extractRuleFromSchema(schema: Record<string, any> | undefined, fieldName: string) {
// no schema at all
if (!schema) {
return undefined;
}

// a yup schema
if (schema.fields?.[fieldName]) {
return schema.fields?.[fieldName];
}

// there is a key on the schema object for this field
if (schema[fieldName]) {
return schema[fieldName];
}

return undefined;
}
35 changes: 35 additions & 0 deletions packages/core/tests/Form.spec.ts
@@ -1,6 +1,7 @@
import flushPromises from 'flush-promises';
import { defineRule } from '@vee-validate/core';
import { mountWithHoc, setValue } from './helpers';
import * as yup from 'yup';

describe('<Form />', () => {
const REQUIRED_MESSAGE = `This field is required`;
Expand Down Expand Up @@ -245,6 +246,40 @@ describe('<Form />', () => {
expect(submitMock).toHaveBeenCalledTimes(1);
});

// test('validation schema with yup', async () => {
// const wrapper = mountWithHoc({
// setup() {
// const schema = yup.object().shape({
// email: yup.string().email(),
// password: yup.string().required().min(8),
// });

// return {
// schema,
// };
// },
// template: `
// <VForm @submit="submit" as="form" :validationSchema="schema" v-slot="{ errors }">
// <Field name="field" as="input" />
// <span id="field">{{ errors.field }}</span>

// <Field name="other" as="input" />
// <span id="other">{{ errors.other }}</span>

// <button>Validate</button>
// </VForm>
// `,
// });

// const first = wrapper.$el.querySelector('#field');
// const second = wrapper.$el.querySelector('#other');

// await flushPromises();

// expect(first.textContent).toBe('this is required');
// expect(second.textContent).toBe('this is required');
// });

test('validation schema to validate form', async () => {
const wrapper = mountWithHoc({
setup() {
Expand Down

0 comments on commit e436b75

Please sign in to comment.