Skip to content

Commit e94da20

Browse files
committed
angular-material: Add OneOfEnumControlRenderer
1 parent 815ba6e commit e94da20

File tree

7 files changed

+647
-86
lines changed

7 files changed

+647
-86
lines changed

packages/angular-material/.eslintrc.js

Lines changed: 48 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -9,45 +9,54 @@ module.exports = {
99
},
1010
// There is no file include in ESLint. Thus, ignore all and include files via negative ignore (!)
1111
ignorePatterns: ['/*', '!/src', '!/test', '!/example', '/example/dist'],
12-
extends: [
13-
'eslint:recommended',
14-
'plugin:@typescript-eslint/recommended',
15-
'plugin:import/recommended',
16-
'plugin:import/typescript',
17-
'plugin:@angular-eslint/recommended',
18-
'plugin:@angular-eslint/template/process-inline-templates',
19-
'plugin:prettier/recommended',
20-
],
21-
rules: {
22-
'@angular-eslint/component-class-suffix': 'off',
23-
'@angular-eslint/directive-class-suffix': 'off',
24-
'@angular-eslint/no-conflicting-lifecycle': 'warn',
25-
'@typescript-eslint/no-explicit-any': 'off',
26-
// Base rule must be disabled to avoid incorrect errors
27-
'no-unused-vars': 'off',
28-
'@typescript-eslint/no-unused-vars': [
29-
'warn', // or "error"
30-
{
31-
argsIgnorePattern: '^_',
32-
varsIgnorePattern: '^_',
33-
caughtErrorsIgnorePattern: '^_',
34-
},
35-
],
36-
// workaround for
37-
// https://github.com/import-js/eslint-plugin-import/issues/1810:
38-
'import/no-unresolved': [
39-
'error',
40-
{
41-
ignore: [
42-
'@angular/cdk/.*',
43-
'@angular/core/.*',
44-
'@angular/material/.*',
45-
'@angular/platform-browser/.*',
46-
'@angular/platform-browser-dynamic/.*',
47-
'core-js/es7/.*',
48-
'zone.js/.*',
12+
overrides: [
13+
{
14+
files: ['*.ts'],
15+
extends: [
16+
'eslint:recommended',
17+
'plugin:@typescript-eslint/recommended',
18+
'plugin:import/recommended',
19+
'plugin:import/typescript',
20+
'plugin:@angular-eslint/recommended',
21+
'plugin:@angular-eslint/template/process-inline-templates',
22+
'plugin:prettier/recommended',
23+
],
24+
rules: {
25+
'@angular-eslint/component-class-suffix': 'off',
26+
'@angular-eslint/directive-class-suffix': 'off',
27+
'@angular-eslint/no-conflicting-lifecycle': 'warn',
28+
'@typescript-eslint/no-explicit-any': 'off',
29+
// Base rule must be disabled to avoid incorrect errors
30+
'no-unused-vars': 'off',
31+
'@typescript-eslint/no-unused-vars': [
32+
'warn', // or "error"
33+
{
34+
argsIgnorePattern: '^_',
35+
varsIgnorePattern: '^_',
36+
caughtErrorsIgnorePattern: '^_',
37+
},
38+
],
39+
// workaround for
40+
// https://github.com/import-js/eslint-plugin-import/issues/1810:
41+
'import/no-unresolved': [
42+
'error',
43+
{
44+
ignore: [
45+
'@angular/cdk/.*',
46+
'@angular/core/.*',
47+
'@angular/material/.*',
48+
'@angular/platform-browser/.*',
49+
'@angular/platform-browser-dynamic/.*',
50+
'core-js/es7/.*',
51+
'zone.js/.*',
52+
],
53+
},
4954
],
5055
},
51-
],
52-
},
56+
},
57+
{
58+
files: '*.html',
59+
extends: ['plugin:@angular-eslint/template/recommended'],
60+
}
61+
],
5362
};
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<mat-form-field [ngStyle]="{ display: hidden ? 'none' : '' }">
2+
<mat-label>{{ label }}</mat-label>
3+
<input
4+
matInput
5+
type="text"
6+
(change)="onChange($event)"
7+
[id]="id"
8+
[formControl]="form"
9+
[matAutocomplete]="auto"
10+
(keydown)="updateFilter($event)"
11+
(focus)="focused = true"
12+
(focusout)="focused = false"
13+
/>
14+
<mat-autocomplete
15+
autoActiveFirstOption
16+
#auto="matAutocomplete"
17+
(optionSelected)="onSelect($event)"
18+
[displayWith]="displayFn"
19+
>
20+
@for (option of filteredOptions | async; track option.value) {
21+
<mat-option [value]="option">
22+
{{ option.label }}
23+
</mat-option>
24+
}
25+
</mat-autocomplete>
26+
<mat-hint *ngIf="shouldShowUnfocusedDescription() || focused">{{
27+
description
28+
}}</mat-hint>
29+
<mat-error>{{ error }}</mat-error>
30+
</mat-form-field>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
:host {
2+
display: flex;
3+
flex-direction: row;
4+
}
5+
mat-form-field {
6+
flex: 1 1 auto;
7+
}

packages/angular-material/src/library/controls/enum.renderer.ts

Lines changed: 48 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@ import {
3636
ControlElement,
3737
EnumOption,
3838
isEnumControl,
39+
isOneOfEnumControl,
3940
JsonFormsState,
4041
mapStateToEnumControlProps,
42+
mapStateToOneOfEnumControlProps,
4143
OwnPropsOfControl,
4244
OwnPropsOfEnum,
4345
RankedTester,
@@ -53,50 +55,9 @@ import { MatInputModule } from '@angular/material/input';
5355
import { MatAutocompleteModule } from '@angular/material/autocomplete';
5456

5557
@Component({
56-
selector: 'EnumControlRenderer, AutocompleteControlRenderer',
57-
template: `
58-
<mat-form-field [ngStyle]="{ display: hidden ? 'none' : '' }">
59-
<mat-label>{{ label }}</mat-label>
60-
<input
61-
matInput
62-
type="text"
63-
(change)="onChange($event)"
64-
[id]="id"
65-
[formControl]="form"
66-
[matAutocomplete]="auto"
67-
(keydown)="updateFilter($event)"
68-
(focus)="focused = true"
69-
(focusout)="focused = false"
70-
/>
71-
<mat-autocomplete
72-
autoActiveFirstOption
73-
#auto="matAutocomplete"
74-
(optionSelected)="onSelect($event)"
75-
[displayWith]="displayFn"
76-
>
77-
@for (option of filteredOptions | async; track option.value) {
78-
<mat-option [value]="option">
79-
{{ option.label }}
80-
</mat-option>
81-
}
82-
</mat-autocomplete>
83-
<mat-hint *ngIf="shouldShowUnfocusedDescription() || focused">{{
84-
description
85-
}}</mat-hint>
86-
<mat-error>{{ error }}</mat-error>
87-
</mat-form-field>
88-
`,
89-
styles: [
90-
`
91-
:host {
92-
display: flex;
93-
flex-direction: row;
94-
}
95-
mat-form-field {
96-
flex: 1 1 auto;
97-
}
98-
`,
99-
],
58+
selector: 'OneOfEnumControlRenderer',
59+
templateUrl: './enum.renderer.html',
60+
styleUrls: ['./enum.renderer.scss'],
10061
changeDetection: ChangeDetectionStrategy.OnPush,
10162
imports: [
10263
CommonModule,
@@ -106,8 +67,11 @@ import { MatAutocompleteModule } from '@angular/material/autocomplete';
10667
MatAutocompleteModule,
10768
],
10869
})
109-
export class EnumControlRenderer extends JsonFormsControl implements OnInit {
110-
@Input() options?: EnumOption[] | string[];
70+
export class OneOfEnumControlRenderer
71+
extends JsonFormsControl
72+
implements OnInit
73+
{
74+
@Input() options?: EnumOption[];
11175
valuesToTranslatedOptions?: Map<string, EnumOption>;
11276
filteredOptions: Observable<EnumOption[]>;
11377
shouldFilter: boolean;
@@ -120,7 +84,7 @@ export class EnumControlRenderer extends JsonFormsControl implements OnInit {
12084
protected override mapToProps(
12185
state: JsonFormsState
12286
): StatePropsOfControl & OwnPropsOfEnum {
123-
return mapStateToEnumControlProps(state, this.getOwnProps());
87+
return mapStateToOneOfEnumControlProps(state, this.getOwnProps());
12488
}
12589

12690
getEventValue = (event: any) => event.target.value;
@@ -231,6 +195,43 @@ export class EnumControlRenderer extends JsonFormsControl implements OnInit {
231195
}
232196
}
233197

198+
export const oneOfEnumControlTester: RankedTester = rankWith(
199+
5,
200+
isOneOfEnumControl
201+
);
202+
203+
@Component({
204+
selector: 'EnumControlRenderer, AutocompleteControlRenderer',
205+
templateUrl: './enum.renderer.html',
206+
styleUrls: ['./enum.renderer.scss'],
207+
changeDetection: ChangeDetectionStrategy.OnPush,
208+
imports: [
209+
CommonModule,
210+
ReactiveFormsModule,
211+
MatFormFieldModule,
212+
MatInputModule,
213+
MatAutocompleteModule,
214+
],
215+
})
216+
export class EnumControlRenderer extends OneOfEnumControlRenderer {
217+
// eslint-disable-next-line @angular-eslint/no-input-rename
218+
@Input('options')
219+
set stringOptions(strOptions: string[]) {
220+
this.options = strOptions.map((str) => {
221+
return {
222+
label: str,
223+
value: str,
224+
};
225+
});
226+
}
227+
228+
protected override mapToProps(
229+
state: JsonFormsState
230+
): StatePropsOfControl & OwnPropsOfEnum {
231+
return mapStateToEnumControlProps(state, this.getOwnProps());
232+
}
233+
}
234+
234235
/**
235236
* For {@link AutocompleteControlRenderer} class name backwards compatibility
236237
*/

packages/angular-material/src/library/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ import {
5757
EnumControlRenderer,
5858
enumControlTester,
5959
} from './controls/enum.renderer';
60+
import {
61+
OneOfEnumControlRenderer,
62+
oneOfEnumControlTester,
63+
} from './controls/enum.renderer';
6064
import {
6165
ObjectControlRenderer,
6266
ObjectControlRendererTester,
@@ -107,6 +111,7 @@ export const angularMaterialRenderers: {
107111
{ tester: DateControlRendererTester, renderer: DateControlRenderer },
108112
{ tester: ToggleControlRendererTester, renderer: ToggleControlRenderer },
109113
{ tester: enumControlTester, renderer: EnumControlRenderer },
114+
{ tester: oneOfEnumControlTester, renderer: OneOfEnumControlRenderer },
110115
{ tester: ObjectControlRendererTester, renderer: ObjectControlRenderer },
111116
// layouts
112117
{ tester: verticalLayoutTester, renderer: VerticalLayoutRenderer },

packages/angular-material/src/library/module.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ import { JsonFormsModule } from '@jsonforms/angular';
4848
import { BooleanControlRenderer } from './controls/boolean.renderer';
4949
import { DateControlRenderer } from './controls/date.renderer';
5050
import { EnumControlRenderer } from './controls/enum.renderer';
51+
import { OneOfEnumControlRenderer } from './controls/enum.renderer';
5152
import { NumberControlRenderer } from './controls/number.renderer';
5253
import { RangeControlRenderer } from './controls/range.renderer';
5354
import { TextAreaRenderer } from './controls/textarea.renderer';
@@ -105,6 +106,7 @@ import { LayoutChildrenRenderPropsPipe } from './layouts';
105106
JsonFormsDetailComponent,
106107
ObjectControlRenderer,
107108
EnumControlRenderer,
109+
OneOfEnumControlRenderer,
108110
TableRenderer,
109111
ArrayLayoutRenderer,
110112
LayoutChildrenRenderPropsPipe,
@@ -145,6 +147,7 @@ import { LayoutChildrenRenderPropsPipe } from './layouts';
145147
JsonFormsDetailComponent,
146148
ObjectControlRenderer,
147149
EnumControlRenderer,
150+
OneOfEnumControlRenderer,
148151
TableRenderer,
149152
ArrayLayoutRenderer,
150153
LayoutChildrenRenderPropsPipe,

0 commit comments

Comments
 (0)