Skip to content

Commit 05f7df3

Browse files
committed
fix: adapt to the breaking changes in #vue-1682 closes #2873
1 parent 1ee4962 commit 05f7df3

7 files changed

Lines changed: 487 additions & 476 deletions

File tree

package.json

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@
1717
"docs:deploy": "./scripts/deploy-docs.sh"
1818
},
1919
"devDependencies": {
20-
"@commitlint/cli": "^9.1.1",
21-
"@commitlint/config-conventional": "^9.1.1",
22-
"@types/jest": "^26.0.9",
23-
"@types/yup": "^0.29.4",
24-
"@typescript-eslint/eslint-plugin": "^3.9.0",
25-
"@typescript-eslint/parser": "^3.9.0",
20+
"@commitlint/cli": "^9.1.2",
21+
"@commitlint/config-conventional": "^9.1.2",
22+
"@types/jest": "^26.0.10",
23+
"@types/yup": "^0.29.6",
24+
"@typescript-eslint/eslint-plugin": "^3.10.1",
25+
"@typescript-eslint/parser": "^3.10.1",
2626
"chalk": "^4.1.0",
27-
"eslint": "^7.6.0",
27+
"eslint": "^7.7.0",
2828
"eslint-config-prettier": "^6.11.0",
2929
"eslint-config-standard": "^14.1.1",
3030
"eslint-plugin-import": "^2.22.0",
@@ -38,21 +38,21 @@
3838
"fs-extra": "^9.0.0",
3939
"gzip-size": "^5.1.1",
4040
"husky": "^4.2.5",
41-
"jest": "^26.4.0",
41+
"jest": "^26.4.2",
4242
"lerna": "^3.22.1",
43-
"lint-staged": "^10.2.11",
44-
"prettier": "^2.0.5",
43+
"lint-staged": "^10.2.13",
44+
"prettier": "^2.1.1",
4545
"raf-stub": "^3.0.0",
46-
"rollup": "^2.23.1",
47-
"rollup-plugin-dts": "^1.4.10",
46+
"rollup": "^2.26.6",
47+
"rollup-plugin-dts": "^1.4.12",
4848
"rollup-plugin-json": "^4.0.0",
4949
"rollup-plugin-replace": "^2.2.0",
5050
"rollup-plugin-typescript2": "^0.27.2",
51-
"terser": "^5.0.0",
52-
"ts-jest": "^26.2.0",
51+
"terser": "^5.2.1",
52+
"ts-jest": "^26.3.0",
5353
"tslint-config-prettier": "^1.18.0",
5454
"tslint-config-standard": "^9.0.0",
55-
"typescript": "^3.9.3",
55+
"typescript": "^4.0.2",
5656
"vue": "^3.0.0-beta.15",
5757
"yup": "^0.29.3"
5858
},

packages/core/src/Field.ts

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { computed, h, defineComponent, nextTick } from 'vue';
22
import { getConfig } from './config';
33
import { useField } from './useField';
4-
import { useRefsObjToComputed, normalizeChildren, isHTMLTag, hasCheckedAttr } from './utils';
4+
import { normalizeChildren, isHTMLTag, hasCheckedAttr } from './utils';
55

66
export const Field = defineComponent({
77
name: 'Field',
@@ -74,9 +74,7 @@ export const Field = defineComponent({
7474
}
7575
: handleChange;
7676

77-
const unwrappedMeta = useRefsObjToComputed(meta);
78-
79-
const slotProps = computed(() => {
77+
const makeSlotProps = () => {
8078
const fieldProps: Record<string, any> = {
8179
name: fieldName,
8280
disabled: props.disabled,
@@ -97,17 +95,18 @@ export const Field = defineComponent({
9795
return {
9896
field: fieldProps,
9997
aria: aria.value,
100-
meta: unwrappedMeta.value,
98+
meta,
10199
errors: errors.value,
102100
errorMessage: errorMessage.value,
103101
validate: validateField,
104102
reset,
105103
handleChange: onChangeHandler,
106104
};
107-
});
105+
};
108106

109107
return () => {
110-
let tag = props.as;
108+
let tag: string | undefined = props.as;
109+
const slotProps = makeSlotProps();
111110
if (!props.as && !ctx.slots.default) {
112111
tag = 'input';
113112
}
@@ -121,14 +120,14 @@ export const Field = defineComponent({
121120
});
122121
}
123122

124-
const children = normalizeChildren(ctx, slotProps.value);
123+
const children = normalizeChildren(ctx, slotProps);
125124
if (tag) {
126125
return h(
127126
tag,
128127
{
129128
...ctx.attrs,
130-
...slotProps.value.field,
131-
...(isHTMLTag(tag) ? slotProps.value.aria : {}),
129+
...slotProps.field,
130+
...(isHTMLTag(tag) ? slotProps.aria : {}),
132131
},
133132
children
134133
);

packages/core/src/Form.ts

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { computed, h, defineComponent } from 'vue';
1+
import { h, defineComponent, watch } from 'vue';
22
import { useForm } from './useForm';
33
import { SubmissionHandler } from './types';
4-
import { useRefsObjToComputed, normalizeChildren } from './utils';
4+
import { normalizeChildren } from './utils';
55

66
export const Form = defineComponent({
77
name: 'Form',
@@ -26,21 +26,6 @@ export const Form = defineComponent({
2626
initialValues: props.initialValues,
2727
});
2828

29-
const unwrappedMeta = useRefsObjToComputed(meta);
30-
31-
const slotProps = computed(() => {
32-
return {
33-
meta: unwrappedMeta.value,
34-
errors: errors.value,
35-
values: values.value,
36-
isSubmitting: isSubmitting.value,
37-
validate,
38-
handleSubmit,
39-
handleReset,
40-
submitForm,
41-
};
42-
});
43-
4429
const onSubmit = ctx.attrs.onSubmit ? handleSubmit(ctx.attrs.onSubmit as SubmissionHandler) : submitForm;
4530
function handleFormReset() {
4631
handleReset();
@@ -49,8 +34,22 @@ export const Form = defineComponent({
4934
}
5035
}
5136

37+
// FIXME: for whatever reason that's beyond me, this fixes the reactivity issue
38+
// eslint-disable-next-line @typescript-eslint/no-empty-function
39+
watch(errors, () => {});
40+
5241
return () => {
53-
const children = normalizeChildren(ctx, slotProps.value);
42+
const children = normalizeChildren(ctx, {
43+
meta: meta.value,
44+
errors: errors.value,
45+
values: values.value,
46+
isSubmitting: isSubmitting.value,
47+
validate,
48+
handleSubmit,
49+
handleReset,
50+
submitForm,
51+
});
52+
5453
if (!props.as) {
5554
return children;
5655
}

packages/core/src/useField.ts

Lines changed: 25 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export function useField(fieldName: MaybeReactive<string>, rules: RuleExpression
4848
});
4949

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

5959
// Must be updated regardless if a mutation is needed or not
6060
// FIXME: is this needed?
61-
meta.valid.value = !result.errors.length;
62-
meta.invalid.value = !!result.errors.length;
63-
meta.pending.value = false;
61+
meta.valid = !result.errors.length;
62+
meta.invalid = !!result.errors.length;
63+
meta.pending = false;
6464

6565
return result;
6666
}
6767

6868
const results = await form.validateSchema();
69-
meta.pending.value = false;
69+
meta.pending = false;
7070

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

166166
// For each dependent field, validate it if it was validated before
167167
dependencies.value.forEach(dep => {
168-
if (dep in form.values && meta.validated.value) {
168+
if (dep in form.values && meta.validated) {
169169
runValidationWithMutation();
170170
}
171171
});
@@ -211,17 +211,17 @@ function useValidationState(fieldName: MaybeReactive<string>, initValue: any, fo
211211
// Common input/change event handler
212212
const handleChange = (e: Event) => {
213213
value.value = normalizeEventValue(e);
214-
meta.dirty.value = true;
215-
meta.pristine.value = false;
214+
meta.dirty = true;
215+
meta.pristine = false;
216216
};
217217

218218
// Updates the validation state with the validation result
219219
function patch(result: ValidationResult) {
220220
errors.value = result.errors;
221-
meta.changed.value = initialValue !== value.value;
222-
meta.valid.value = !result.errors.length;
223-
meta.invalid.value = !!result.errors.length;
224-
meta.validated.value = true;
221+
meta.changed = initialValue !== value.value;
222+
meta.valid = !result.errors.length;
223+
meta.invalid = !!result.errors.length;
224+
meta.validated = true;
225225

226226
return result;
227227
}
@@ -261,54 +261,48 @@ function useMeta() {
261261
failed: false,
262262
});
263263

264-
const flags = reactive(initialMeta());
264+
const meta = reactive(initialMeta());
265265

266-
const passed = computed(() => {
267-
return flags.valid && flags.validated;
268-
});
269-
270-
const failed = computed(() => {
271-
return flags.invalid && flags.validated;
266+
// FIXME: Fix computation of passed
267+
watchEffect(() => {
268+
meta.passed = meta.valid && meta.validated;
269+
meta.failed = meta.invalid && meta.validated;
272270
});
273271

274272
/**
275273
* Handles common onBlur meta update
276274
*/
277275
const onBlur = () => {
278-
flags.touched = true;
279-
flags.untouched = false;
276+
meta.touched = true;
277+
meta.untouched = false;
280278
};
281279

282280
/**
283281
* Resets the flag state
284282
*/
285283
function reset() {
286284
const defaults = initialMeta();
287-
Object.keys(flags).forEach((key: string) => {
285+
Object.keys(meta).forEach((key: string) => {
288286
// Skip these, since they are computed anyways
289-
if (key === 'passed' || key === 'failed') {
287+
if (['passed', 'failed'].includes(key)) {
290288
return;
291289
}
292290

293-
flags[key as Flag] = defaults[key as Flag];
291+
meta[key as Flag] = defaults[key as Flag];
294292
});
295293
}
296294

297295
return {
298-
meta: {
299-
...toRefs(flags),
300-
passed,
301-
failed,
302-
},
296+
meta,
303297
onBlur,
304298
reset,
305299
};
306300
}
307301

308-
function useAriAttrs(fieldName: MaybeReactive<string>, meta: Record<Flag, Ref<boolean>>) {
302+
function useAriAttrs(fieldName: MaybeReactive<string>, meta: Record<string, boolean>) {
309303
return computed(() => {
310304
return {
311-
'aria-invalid': meta.failed.value ? 'true' : 'false',
305+
'aria-invalid': meta.failed ? 'true' : 'false',
312306
'aria-describedBy': genFieldErrorId(unwrap(fieldName)),
313307
};
314308
});

packages/core/src/useForm.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ export function useForm(opts?: FormOptions) {
168168

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

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

250-
return flags.reduce((acc, flag: Flag) => {
251-
acc[flag] = computed(() => {
250+
return computed(() => {
251+
return flags.reduce((acc, flag: Flag) => {
252252
const mergeMethod = MERGE_STRATEGIES[flag];
253+
acc[flag] = fields.value[mergeMethod](field => field.meta[flag]);
253254

254-
return fields.value[mergeMethod](field => field.meta[flag]);
255-
});
256-
257-
return acc;
258-
}, {} as Record<Flag, Ref<boolean>>);
255+
return acc;
256+
}, {} as Record<string, boolean>);
257+
});
259258
}
260259

261260
async function validateYupSchema(

packages/core/src/utils/refs.ts

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,6 @@
1-
import { isRef, Ref, computed } from 'vue';
1+
import { isRef } from 'vue';
22
import { MaybeReactive } from '../types';
33

44
export function unwrap<T>(ref: MaybeReactive<T>) {
55
return isRef(ref) ? ref.value : ref;
66
}
7-
8-
export function useRefsObjToComputed<TKey extends string, TValue>(refsObj: Record<TKey, Ref<TValue>>) {
9-
return computed(() => {
10-
return Object.keys(refsObj).reduce((acc, key) => {
11-
acc[key as TKey] = refsObj[key as TKey].value;
12-
13-
return acc;
14-
}, {} as Record<TKey, TValue>);
15-
});
16-
}

0 commit comments

Comments
 (0)