Skip to content

Commit

Permalink
fix: adapt to the breaking changes in #vue-1682 closes #2873
Browse files Browse the repository at this point in the history
  • Loading branch information
logaretm committed Aug 28, 2020
1 parent 1ee4962 commit 05f7df3
Show file tree
Hide file tree
Showing 7 changed files with 487 additions and 476 deletions.
30 changes: 15 additions & 15 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@
"docs:deploy": "./scripts/deploy-docs.sh"
},
"devDependencies": {
"@commitlint/cli": "^9.1.1",
"@commitlint/config-conventional": "^9.1.1",
"@types/jest": "^26.0.9",
"@types/yup": "^0.29.4",
"@typescript-eslint/eslint-plugin": "^3.9.0",
"@typescript-eslint/parser": "^3.9.0",
"@commitlint/cli": "^9.1.2",
"@commitlint/config-conventional": "^9.1.2",
"@types/jest": "^26.0.10",
"@types/yup": "^0.29.6",
"@typescript-eslint/eslint-plugin": "^3.10.1",
"@typescript-eslint/parser": "^3.10.1",
"chalk": "^4.1.0",
"eslint": "^7.6.0",
"eslint": "^7.7.0",
"eslint-config-prettier": "^6.11.0",
"eslint-config-standard": "^14.1.1",
"eslint-plugin-import": "^2.22.0",
Expand All @@ -38,21 +38,21 @@
"fs-extra": "^9.0.0",
"gzip-size": "^5.1.1",
"husky": "^4.2.5",
"jest": "^26.4.0",
"jest": "^26.4.2",
"lerna": "^3.22.1",
"lint-staged": "^10.2.11",
"prettier": "^2.0.5",
"lint-staged": "^10.2.13",
"prettier": "^2.1.1",
"raf-stub": "^3.0.0",
"rollup": "^2.23.1",
"rollup-plugin-dts": "^1.4.10",
"rollup": "^2.26.6",
"rollup-plugin-dts": "^1.4.12",
"rollup-plugin-json": "^4.0.0",
"rollup-plugin-replace": "^2.2.0",
"rollup-plugin-typescript2": "^0.27.2",
"terser": "^5.0.0",
"ts-jest": "^26.2.0",
"terser": "^5.2.1",
"ts-jest": "^26.3.0",
"tslint-config-prettier": "^1.18.0",
"tslint-config-standard": "^9.0.0",
"typescript": "^3.9.3",
"typescript": "^4.0.2",
"vue": "^3.0.0-beta.15",
"yup": "^0.29.3"
},
Expand Down
19 changes: 9 additions & 10 deletions packages/core/src/Field.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { computed, h, defineComponent, nextTick } from 'vue';
import { getConfig } from './config';
import { useField } from './useField';
import { useRefsObjToComputed, normalizeChildren, isHTMLTag, hasCheckedAttr } from './utils';
import { normalizeChildren, isHTMLTag, hasCheckedAttr } from './utils';

export const Field = defineComponent({
name: 'Field',
Expand Down Expand Up @@ -74,9 +74,7 @@ export const Field = defineComponent({
}
: handleChange;

const unwrappedMeta = useRefsObjToComputed(meta);

const slotProps = computed(() => {
const makeSlotProps = () => {
const fieldProps: Record<string, any> = {
name: fieldName,
disabled: props.disabled,
Expand All @@ -97,17 +95,18 @@ export const Field = defineComponent({
return {
field: fieldProps,
aria: aria.value,
meta: unwrappedMeta.value,
meta,
errors: errors.value,
errorMessage: errorMessage.value,
validate: validateField,
reset,
handleChange: onChangeHandler,
};
});
};

return () => {
let tag = props.as;
let tag: string | undefined = props.as;
const slotProps = makeSlotProps();
if (!props.as && !ctx.slots.default) {
tag = 'input';
}
Expand All @@ -121,14 +120,14 @@ export const Field = defineComponent({
});
}

const children = normalizeChildren(ctx, slotProps.value);
const children = normalizeChildren(ctx, slotProps);
if (tag) {
return h(
tag,
{
...ctx.attrs,
...slotProps.value.field,
...(isHTMLTag(tag) ? slotProps.value.aria : {}),
...slotProps.field,
...(isHTMLTag(tag) ? slotProps.aria : {}),
},
children
);
Expand Down
35 changes: 17 additions & 18 deletions packages/core/src/Form.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { computed, h, defineComponent } from 'vue';
import { h, defineComponent, watch } from 'vue';
import { useForm } from './useForm';
import { SubmissionHandler } from './types';
import { useRefsObjToComputed, normalizeChildren } from './utils';
import { normalizeChildren } from './utils';

export const Form = defineComponent({
name: 'Form',
Expand All @@ -26,21 +26,6 @@ export const Form = defineComponent({
initialValues: props.initialValues,
});

const unwrappedMeta = useRefsObjToComputed(meta);

const slotProps = computed(() => {
return {
meta: unwrappedMeta.value,
errors: errors.value,
values: values.value,
isSubmitting: isSubmitting.value,
validate,
handleSubmit,
handleReset,
submitForm,
};
});

const onSubmit = ctx.attrs.onSubmit ? handleSubmit(ctx.attrs.onSubmit as SubmissionHandler) : submitForm;
function handleFormReset() {
handleReset();
Expand All @@ -49,8 +34,22 @@ export const Form = defineComponent({
}
}

// FIXME: for whatever reason that's beyond me, this fixes the reactivity issue
// eslint-disable-next-line @typescript-eslint/no-empty-function
watch(errors, () => {});

return () => {
const children = normalizeChildren(ctx, slotProps.value);
const children = normalizeChildren(ctx, {
meta: meta.value,
errors: errors.value,
values: values.value,
isSubmitting: isSubmitting.value,
validate,
handleSubmit,
handleReset,
submitForm,
});

if (!props.as) {
return children;
}
Expand Down
56 changes: 25 additions & 31 deletions packages/core/src/useField.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export function useField(fieldName: MaybeReactive<string>, rules: RuleExpression
});

const runValidation = async (): Promise<ValidationResult> => {
meta.pending.value = true;
meta.pending = true;
if (!form || !form.validateSchema) {
const result = await validate(value.value, normalizedRules.value, {
name: unwrap(fieldName),
Expand All @@ -58,15 +58,15 @@ export function useField(fieldName: MaybeReactive<string>, rules: RuleExpression

// Must be updated regardless if a mutation is needed or not
// FIXME: is this needed?
meta.valid.value = !result.errors.length;
meta.invalid.value = !!result.errors.length;
meta.pending.value = false;
meta.valid = !result.errors.length;
meta.invalid = !!result.errors.length;
meta.pending = false;

return result;
}

const results = await form.validateSchema();
meta.pending.value = false;
meta.pending = false;

return results[unwrap(fieldName)];
};
Expand Down Expand Up @@ -165,7 +165,7 @@ export function useField(fieldName: MaybeReactive<string>, rules: RuleExpression

// For each dependent field, validate it if it was validated before
dependencies.value.forEach(dep => {
if (dep in form.values && meta.validated.value) {
if (dep in form.values && meta.validated) {
runValidationWithMutation();
}
});
Expand Down Expand Up @@ -211,17 +211,17 @@ function useValidationState(fieldName: MaybeReactive<string>, initValue: any, fo
// Common input/change event handler
const handleChange = (e: Event) => {
value.value = normalizeEventValue(e);
meta.dirty.value = true;
meta.pristine.value = false;
meta.dirty = true;
meta.pristine = false;
};

// Updates the validation state with the validation result
function patch(result: ValidationResult) {
errors.value = result.errors;
meta.changed.value = initialValue !== value.value;
meta.valid.value = !result.errors.length;
meta.invalid.value = !!result.errors.length;
meta.validated.value = true;
meta.changed = initialValue !== value.value;
meta.valid = !result.errors.length;
meta.invalid = !!result.errors.length;
meta.validated = true;

return result;
}
Expand Down Expand Up @@ -261,54 +261,48 @@ function useMeta() {
failed: false,
});

const flags = reactive(initialMeta());
const meta = reactive(initialMeta());

const passed = computed(() => {
return flags.valid && flags.validated;
});

const failed = computed(() => {
return flags.invalid && flags.validated;
// FIXME: Fix computation of passed
watchEffect(() => {
meta.passed = meta.valid && meta.validated;
meta.failed = meta.invalid && meta.validated;
});

/**
* Handles common onBlur meta update
*/
const onBlur = () => {
flags.touched = true;
flags.untouched = false;
meta.touched = true;
meta.untouched = false;
};

/**
* Resets the flag state
*/
function reset() {
const defaults = initialMeta();
Object.keys(flags).forEach((key: string) => {
Object.keys(meta).forEach((key: string) => {
// Skip these, since they are computed anyways
if (key === 'passed' || key === 'failed') {
if (['passed', 'failed'].includes(key)) {
return;
}

flags[key as Flag] = defaults[key as Flag];
meta[key as Flag] = defaults[key as Flag];
});
}

return {
meta: {
...toRefs(flags),
passed,
failed,
},
meta,
onBlur,
reset,
};
}

function useAriAttrs(fieldName: MaybeReactive<string>, meta: Record<Flag, Ref<boolean>>) {
function useAriAttrs(fieldName: MaybeReactive<string>, meta: Record<string, boolean>) {
return computed(() => {
return {
'aria-invalid': meta.failed.value ? 'true' : 'false',
'aria-invalid': meta.failed ? 'true' : 'false',
'aria-describedBy': genFieldErrorId(unwrap(fieldName)),
};
});
Expand Down
15 changes: 7 additions & 8 deletions packages/core/src/useForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ export function useForm(opts?: FormOptions) {

const errors = computed(() => {
return activeFields.value.reduce((acc: Record<string, string>, field) => {
acc[field.name] = field.errorMessage;
acc[field.name] = unwrap(field.errorMessage);

return acc;
}, {});
Expand Down Expand Up @@ -247,15 +247,14 @@ const MERGE_STRATEGIES: Record<Flag, 'every' | 'some'> = {
function useFormMeta(fields: Ref<any[]>) {
const flags: Flag[] = Object.keys(MERGE_STRATEGIES) as Flag[];

return flags.reduce((acc, flag: Flag) => {
acc[flag] = computed(() => {
return computed(() => {
return flags.reduce((acc, flag: Flag) => {
const mergeMethod = MERGE_STRATEGIES[flag];
acc[flag] = fields.value[mergeMethod](field => field.meta[flag]);

return fields.value[mergeMethod](field => field.meta[flag]);
});

return acc;
}, {} as Record<Flag, Ref<boolean>>);
return acc;
}, {} as Record<string, boolean>);
});
}

async function validateYupSchema(
Expand Down
12 changes: 1 addition & 11 deletions packages/core/src/utils/refs.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,6 @@
import { isRef, Ref, computed } from 'vue';
import { isRef } from 'vue';
import { MaybeReactive } from '../types';

export function unwrap<T>(ref: MaybeReactive<T>) {
return isRef(ref) ? ref.value : ref;
}

export function useRefsObjToComputed<TKey extends string, TValue>(refsObj: Record<TKey, Ref<TValue>>) {
return computed(() => {
return Object.keys(refsObj).reduce((acc, key) => {
acc[key as TKey] = refsObj[key as TKey].value;

return acc;
}, {} as Record<TKey, TValue>);
});
}
Loading

0 comments on commit 05f7df3

Please sign in to comment.