Skip to content

Commit 1b21527

Browse files
committed
fix(ui): fix circular dependency
1 parent c1de21d commit 1b21527

3 files changed

Lines changed: 63 additions & 56 deletions

File tree

packages/ui/src/components/form/abstract-control.ts

Lines changed: 1 addition & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,16 @@
11
/* eslint-disable @typescript-eslint/no-this-alias */
2+
import type { FormGroup } from './form-group';
23
import type { AsyncValidatorFn, ValidationErrors, ValidatorFn } from './validators';
34
import type { Subscription } from 'rxjs';
45

56
import { isArray } from 'lodash';
67
import { from, Subject } from 'rxjs';
78
import { forkJoin } from 'rxjs';
89

9-
import { FormGroup } from './form-group';
10-
1110
export type FormControlStatus = 'VALID' | 'INVALID' | 'PENDING' | 'DISABLED';
1211

1312
export const [VALID, INVALID, PENDING, DISABLED] = ['VALID', 'INVALID', 'PENDING', 'DISABLED'] as FormControlStatus[];
1413

15-
type Mutable<T> = {
16-
-readonly [P in keyof T]: T[P];
17-
};
18-
19-
type GetFormControlPropertyFromArray<T, A> = Mutable<A> extends [infer K, ...infer R]
20-
? K extends keyof T
21-
? GetFormControlPropertyFromArray<T[K], R>
22-
: null
23-
: T;
24-
25-
type GetFormControlProperty<T, S> = S extends `${infer K}.${infer R}`
26-
? K extends keyof T
27-
? GetFormControlProperty<T[K], R>
28-
: null
29-
: S extends keyof T
30-
? T[S]
31-
: null;
32-
33-
function find(control: AbstractControl, path: string[] | string, delimiter: string) {
34-
if (path == null) return null;
35-
36-
if (!Array.isArray(path)) {
37-
path = path.split(delimiter);
38-
}
39-
if (Array.isArray(path) && path.length === 0) return null;
40-
41-
// Not using Array.reduce here due to a Chrome 80 bug
42-
// https://bugs.chromium.org/p/chromium/issues/detail?id=1049982
43-
let controlToFind: AbstractControl | null = control;
44-
path.forEach((name) => {
45-
if (controlToFind instanceof FormGroup) {
46-
controlToFind = name in controlToFind.controls ? controlToFind.controls[name] : null;
47-
} else {
48-
controlToFind = null;
49-
}
50-
});
51-
return controlToFind;
52-
}
53-
5414
function mergeErrors(arrayOfErrors: (ValidationErrors | null)[]): ValidationErrors | null {
5515
const res: { [key: string]: any } = {};
5616

@@ -323,21 +283,6 @@ export abstract class AbstractControl<V = any> {
323283
}
324284
}
325285

326-
get<S extends string>(path: S): AbstractControl<GetFormControlProperty<V, S>>;
327-
get<S extends ArrayLike<string>>(path: S): AbstractControl<GetFormControlPropertyFromArray<V, S>>;
328-
get(path: string[] | string): AbstractControl | null {
329-
return find(this, path, '.');
330-
}
331-
332-
getError(errorCode: string, path?: string[] | string): any {
333-
const control = path ? this.get(path) : this;
334-
return control && control.errors ? control.errors[errorCode] : null;
335-
}
336-
337-
hasError(errorCode: string, path?: string[] | string): boolean {
338-
return !!this.getError(errorCode, path);
339-
}
340-
341286
protected abstract _value: V;
342287

343288
protected abstract _status: FormControlStatus;

packages/ui/src/components/form/form-control.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ export class FormControl<V> extends AbstractControl<V> {
2626
this.updateValueAndValidity(true);
2727
}
2828

29+
getError(errorCode: string): any {
30+
return this && this.errors ? this.errors[errorCode] : null;
31+
}
32+
33+
hasError(errorCode: string): boolean {
34+
return !!this.getError(errorCode);
35+
}
36+
2937
override setValue(value: V, onlySelf?: boolean): void {
3038
this._value = value;
3139
this.updateValueAndValidity(onlySelf);

packages/ui/src/components/form/form-group.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,45 @@ import type { AsyncValidatorFn, ValidatorFn } from './validators';
33

44
import { AbstractControl, VALID } from './abstract-control';
55

6+
type Mutable<T> = {
7+
-readonly [P in keyof T]: T[P];
8+
};
9+
10+
type GetFormControlPropertyFromArray<T, A> = Mutable<A> extends [infer K, ...infer R]
11+
? K extends keyof T
12+
? GetFormControlPropertyFromArray<T[K], R>
13+
: null
14+
: T;
15+
16+
type GetFormControlProperty<T, S> = S extends `${infer K}.${infer R}`
17+
? K extends keyof T
18+
? GetFormControlProperty<T[K], R>
19+
: null
20+
: S extends keyof T
21+
? T[S]
22+
: null;
23+
24+
function find(control: AbstractControl, path: string[] | string, delimiter: string) {
25+
if (path == null) return null;
26+
27+
if (!Array.isArray(path)) {
28+
path = path.split(delimiter);
29+
}
30+
if (Array.isArray(path) && path.length === 0) return null;
31+
32+
// Not using Array.reduce here due to a Chrome 80 bug
33+
// https://bugs.chromium.org/p/chromium/issues/detail?id=1049982
34+
let controlToFind: AbstractControl | null = control;
35+
path.forEach((name) => {
36+
if (controlToFind instanceof FormGroup) {
37+
controlToFind = name in controlToFind.controls ? controlToFind.controls[name] : null;
38+
} else {
39+
controlToFind = null;
40+
}
41+
});
42+
return controlToFind;
43+
}
44+
645
export class FormGroup<T extends { [K in keyof T]: AbstractControl } = any> extends AbstractControl<{ [K in keyof T]: T[K]['value'] }> {
746
protected _value!: { [K in keyof T]: T[K]['value'] };
847
protected _status: FormControlStatus = VALID;
@@ -17,6 +56,21 @@ export class FormGroup<T extends { [K in keyof T]: AbstractControl } = any> exte
1756
this.updateValueAndValidity(true);
1857
}
1958

59+
get<S extends string>(path: S): AbstractControl<GetFormControlProperty<T, S>>;
60+
get<S extends ArrayLike<string>>(path: S): AbstractControl<GetFormControlPropertyFromArray<T, S>>;
61+
get(path: string[] | string): AbstractControl | null {
62+
return find(this, path, '.');
63+
}
64+
65+
getError(errorCode: string, path?: string[] | string): any {
66+
const control = path ? this.get(path) : this;
67+
return control && control.errors ? control.errors[errorCode] : null;
68+
}
69+
70+
hasError(errorCode: string, path?: string[] | string): boolean {
71+
return !!this.getError(errorCode, path);
72+
}
73+
2074
addControl<K extends keyof T>(name: K, control: T[K]): void;
2175
addControl(name: string, control: AbstractControl): void;
2276
addControl(name: string, control: AbstractControl): void {

0 commit comments

Comments
 (0)