From 1b0c8eebfd42f2df7825c4f6b36c771d7afd0189 Mon Sep 17 00:00:00 2001 From: Lucas Koehler Date: Thu, 6 Nov 2025 15:03:34 +0100 Subject: [PATCH] angular: Migrate to standalone components Starting with Angular 19, standalone components are the new default and non-standalone components are discouraged producing a lint error. This migrates all components of the Angular and Angular Material packages to be standalone. Backwards compatibility is maintained by keeping existing NG modules which now import and export all components. Thus, users can use the modules as before. --- packages/angular-material/.eslintrc.js | 2 - .../example/app/app.component.ts | 4 +- .../example/app/app.module.ts | 2 +- .../library/controls/autocomplete.renderer.ts | 13 +++- .../src/library/controls/boolean.renderer.ts | 5 +- .../src/library/controls/date.renderer.ts | 17 ++++- .../src/library/controls/number.renderer.ts | 11 +++- .../src/library/controls/range.renderer.ts | 5 +- .../src/library/controls/text.renderer.ts | 11 +++- .../src/library/controls/textarea.renderer.ts | 11 +++- .../src/library/controls/toggle.renderer.ts | 5 +- .../library/layouts/array-layout.renderer.ts | 17 ++++- .../layouts/categorization-layout.renderer.ts | 5 +- .../library/layouts/group-layout.renderer.ts | 16 ++++- .../layouts/horizontal-layout.renderer.ts | 10 ++- .../src/library/layouts/layout.renderer.ts | 3 +- .../layouts/vertical-layout.renderer.ts | 10 ++- .../angular-material/src/library/module.ts | 22 ++++++- .../src/library/other/label.renderer.ts | 1 - .../src/library/other/master-detail/detail.ts | 4 +- .../src/library/other/master-detail/master.ts | 15 ++++- .../src/library/other/object.renderer.ts | 4 +- .../src/library/other/table.renderer.ts | 64 +++++++++++-------- .../test/autocomplete-control.spec.ts | 12 ++-- .../test/categorization-tab-layout.spec.ts | 3 +- .../angular-material/test/common/layout.ts | 9 +-- packages/angular-material/test/common/util.ts | 3 +- .../test/date-control.spec.ts | 9 +-- .../test/label-renderer.spec.ts | 2 +- .../test/master-detail.spec.ts | 13 +--- .../test/object-control.spec.ts | 4 +- .../test/table-control.spec.ts | 4 +- packages/angular/.eslintrc.js | 2 - .../angular/src/library/abstract-control.ts | 1 - .../src/library/jsonforms-root.component.ts | 3 +- .../src/library/jsonforms.component.ts | 1 - .../angular/src/library/jsonforms.module.ts | 2 +- .../angular/src/library/unknown.component.ts | 1 - 38 files changed, 223 insertions(+), 103 deletions(-) diff --git a/packages/angular-material/.eslintrc.js b/packages/angular-material/.eslintrc.js index 3b3b0a1563..2b67856c2c 100644 --- a/packages/angular-material/.eslintrc.js +++ b/packages/angular-material/.eslintrc.js @@ -22,8 +22,6 @@ module.exports = { '@angular-eslint/component-class-suffix': 'off', '@angular-eslint/directive-class-suffix': 'off', '@angular-eslint/no-conflicting-lifecycle': 'warn', - // Starting with Angular 19, non-standalone components produce a lint error. Reduce to warning until we migrate. - '@angular-eslint/prefer-standalone': 'warn', '@typescript-eslint/no-explicit-any': 'off', // Base rule must be disabled to avoid incorrect errors 'no-unused-vars': 'off', diff --git a/packages/angular-material/example/app/app.component.ts b/packages/angular-material/example/app/app.component.ts index 1d93aaef5a..24b3aaea58 100644 --- a/packages/angular-material/example/app/app.component.ts +++ b/packages/angular-material/example/app/app.component.ts @@ -23,6 +23,8 @@ THE SOFTWARE. */ import { Component } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { JsonFormsModule } from '@jsonforms/angular'; import { ExampleDescription, getExamples } from '@jsonforms/examples'; import { JsonFormsI18nState, @@ -87,7 +89,7 @@ const itemTester: UISchemaTester = (_schema, schemaPath, _path) => { [readonly]="readonly" > `, - standalone: false, + imports: [CommonModule, JsonFormsModule], }) export class AppComponent { readonly renderers = angularMaterialRenderers; diff --git a/packages/angular-material/example/app/app.module.ts b/packages/angular-material/example/app/app.module.ts index 0acb9995c1..d045d782c1 100644 --- a/packages/angular-material/example/app/app.module.ts +++ b/packages/angular-material/example/app/app.module.ts @@ -29,11 +29,11 @@ import { AppComponent } from './app.component'; import { JsonFormsAngularMaterialModule } from '../../src/library'; @NgModule({ - declarations: [AppComponent], imports: [ BrowserModule, BrowserAnimationsModule, JsonFormsAngularMaterialModule, + AppComponent, ], bootstrap: [AppComponent], schemas: [CUSTOM_ELEMENTS_SCHEMA], diff --git a/packages/angular-material/src/library/controls/autocomplete.renderer.ts b/packages/angular-material/src/library/controls/autocomplete.renderer.ts index a1d64b3eb8..596af746f5 100644 --- a/packages/angular-material/src/library/controls/autocomplete.renderer.ts +++ b/packages/angular-material/src/library/controls/autocomplete.renderer.ts @@ -41,6 +41,11 @@ import { } from '@jsonforms/core'; import type { Observable } from 'rxjs'; import { map, startWith } from 'rxjs/operators'; +import { CommonModule } from '@angular/common'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; +import { MatAutocompleteModule } from '@angular/material/autocomplete'; /** * To use this component you will need to add your own tester: @@ -110,7 +115,13 @@ import { map, startWith } from 'rxjs/operators'; `, ], changeDetection: ChangeDetectionStrategy.OnPush, - standalone: false, + imports: [ + CommonModule, + ReactiveFormsModule, + MatFormFieldModule, + MatInputModule, + MatAutocompleteModule, + ], }) export class AutocompleteControlRenderer extends JsonFormsControl diff --git a/packages/angular-material/src/library/controls/boolean.renderer.ts b/packages/angular-material/src/library/controls/boolean.renderer.ts index 37b1c798ad..deabc86519 100644 --- a/packages/angular-material/src/library/controls/boolean.renderer.ts +++ b/packages/angular-material/src/library/controls/boolean.renderer.ts @@ -30,6 +30,9 @@ import { } from '@angular/core'; import { JsonFormsAngularService, JsonFormsControl } from '@jsonforms/angular'; import { isBooleanControl, RankedTester, rankWith } from '@jsonforms/core'; +import { CommonModule } from '@angular/common'; +import { MatCheckboxModule } from '@angular/material/checkbox'; +import { MatFormFieldModule } from '@angular/material/form-field'; @Component({ selector: 'BooleanControlRenderer', @@ -65,7 +68,7 @@ import { isBooleanControl, RankedTester, rankWith } from '@jsonforms/core'; `, ], changeDetection: ChangeDetectionStrategy.OnPush, - standalone: false, + imports: [CommonModule, MatCheckboxModule, MatFormFieldModule], }) export class BooleanControlRenderer extends JsonFormsControl { constructor( diff --git a/packages/angular-material/src/library/controls/date.renderer.ts b/packages/angular-material/src/library/controls/date.renderer.ts index c272e98ddc..c378987a96 100644 --- a/packages/angular-material/src/library/controls/date.renderer.ts +++ b/packages/angular-material/src/library/controls/date.renderer.ts @@ -40,7 +40,14 @@ import { JsonFormsAngularService, JsonFormsControl } from '@jsonforms/angular'; import { DateAdapter, MAT_DATE_FORMATS } from '@angular/material/core'; import { MyFormat } from '../util/date-format'; import { DayJsDateAdapter } from '../util/dayjs-date-adapter'; -import { MatDatepicker } from '@angular/material/datepicker'; +import { + MatDatepicker, + MatDatepickerModule, +} from '@angular/material/datepicker'; +import { CommonModule } from '@angular/common'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; @Component({ selector: 'DateControlRenderer', @@ -105,7 +112,13 @@ import { MatDatepicker } from '@angular/material/datepicker'; useClass: MyFormat, }, ], - standalone: false, + imports: [ + CommonModule, + ReactiveFormsModule, + MatFormFieldModule, + MatInputModule, + MatDatepickerModule, + ], }) export class DateControlRenderer extends JsonFormsControl { focused = false; diff --git a/packages/angular-material/src/library/controls/number.renderer.ts b/packages/angular-material/src/library/controls/number.renderer.ts index 297c30e324..d82bb7e17f 100644 --- a/packages/angular-material/src/library/controls/number.renderer.ts +++ b/packages/angular-material/src/library/controls/number.renderer.ts @@ -33,6 +33,10 @@ import { StatePropsOfControl, } from '@jsonforms/core'; import merge from 'lodash/merge'; +import { CommonModule } from '@angular/common'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; @Component({ selector: 'NumberControlRenderer', @@ -69,7 +73,12 @@ import merge from 'lodash/merge'; `, ], changeDetection: ChangeDetectionStrategy.OnPush, - standalone: false, + imports: [ + CommonModule, + ReactiveFormsModule, + MatFormFieldModule, + MatInputModule, + ], }) export class NumberControlRenderer extends JsonFormsControl { private readonly MAXIMUM_FRACTIONAL_DIGITS = 20; diff --git a/packages/angular-material/src/library/controls/range.renderer.ts b/packages/angular-material/src/library/controls/range.renderer.ts index 1d7bca3779..e72d11a114 100644 --- a/packages/angular-material/src/library/controls/range.renderer.ts +++ b/packages/angular-material/src/library/controls/range.renderer.ts @@ -29,6 +29,9 @@ import { } from '@angular/core'; import { JsonFormsAngularService, JsonFormsControl } from '@jsonforms/angular'; import { isRangeControl, RankedTester, rankWith } from '@jsonforms/core'; +import { CommonModule } from '@angular/common'; +import { MatSliderModule } from '@angular/material/slider'; +import { MatFormFieldModule } from '@angular/material/form-field'; @Component({ selector: 'RangeControlRenderer', @@ -69,7 +72,7 @@ import { isRangeControl, RankedTester, rankWith } from '@jsonforms/core'; `, ], changeDetection: ChangeDetectionStrategy.OnPush, - standalone: false, + imports: [CommonModule, MatSliderModule, MatFormFieldModule], }) export class RangeControlRenderer extends JsonFormsControl { min: number; diff --git a/packages/angular-material/src/library/controls/text.renderer.ts b/packages/angular-material/src/library/controls/text.renderer.ts index 0c388ff4a3..19f0795048 100644 --- a/packages/angular-material/src/library/controls/text.renderer.ts +++ b/packages/angular-material/src/library/controls/text.renderer.ts @@ -25,6 +25,10 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; import { JsonFormsAngularService, JsonFormsControl } from '@jsonforms/angular'; import { isStringControl, RankedTester, rankWith } from '@jsonforms/core'; +import { CommonModule } from '@angular/common'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; @Component({ selector: 'TextControlRenderer', @@ -58,7 +62,12 @@ import { isStringControl, RankedTester, rankWith } from '@jsonforms/core'; `, ], changeDetection: ChangeDetectionStrategy.OnPush, - standalone: false, + imports: [ + CommonModule, + ReactiveFormsModule, + MatFormFieldModule, + MatInputModule, + ], }) export class TextControlRenderer extends JsonFormsControl { focused = false; diff --git a/packages/angular-material/src/library/controls/textarea.renderer.ts b/packages/angular-material/src/library/controls/textarea.renderer.ts index c3ec5f56d3..721a2e08cb 100644 --- a/packages/angular-material/src/library/controls/textarea.renderer.ts +++ b/packages/angular-material/src/library/controls/textarea.renderer.ts @@ -25,6 +25,10 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; import { JsonFormsAngularService, JsonFormsControl } from '@jsonforms/angular'; import { isMultiLineControl, RankedTester, rankWith } from '@jsonforms/core'; +import { CommonModule } from '@angular/common'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; @Component({ selector: 'TextAreaRenderer', @@ -57,7 +61,12 @@ import { isMultiLineControl, RankedTester, rankWith } from '@jsonforms/core'; `, ], changeDetection: ChangeDetectionStrategy.OnPush, - standalone: false, + imports: [ + CommonModule, + ReactiveFormsModule, + MatFormFieldModule, + MatInputModule, + ], }) export class TextAreaRenderer extends JsonFormsControl { focused = false; diff --git a/packages/angular-material/src/library/controls/toggle.renderer.ts b/packages/angular-material/src/library/controls/toggle.renderer.ts index 15b2bf891f..430f0a6d6c 100644 --- a/packages/angular-material/src/library/controls/toggle.renderer.ts +++ b/packages/angular-material/src/library/controls/toggle.renderer.ts @@ -35,6 +35,9 @@ import { RankedTester, rankWith, } from '@jsonforms/core'; +import { CommonModule } from '@angular/common'; +import { MatSlideToggleModule } from '@angular/material/slide-toggle'; +import { MatFormFieldModule } from '@angular/material/form-field'; @Component({ selector: 'ToggleControlRenderer', @@ -55,7 +58,7 @@ import { `, changeDetection: ChangeDetectionStrategy.OnPush, - standalone: false, + imports: [CommonModule, MatSlideToggleModule, MatFormFieldModule], }) export class ToggleControlRenderer extends JsonFormsControl { constructor( diff --git a/packages/angular-material/src/library/layouts/array-layout.renderer.ts b/packages/angular-material/src/library/layouts/array-layout.renderer.ts index 846af7277d..d1f0f130db 100644 --- a/packages/angular-material/src/library/layouts/array-layout.renderer.ts +++ b/packages/angular-material/src/library/layouts/array-layout.renderer.ts @@ -23,9 +23,16 @@ THE SOFTWARE. */ import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { MatCardModule } from '@angular/material/card'; +import { MatButtonModule } from '@angular/material/button'; +import { MatIconModule } from '@angular/material/icon'; +import { MatBadgeModule } from '@angular/material/badge'; +import { MatTooltipModule } from '@angular/material/tooltip'; import { JsonFormsAngularService, JsonFormsAbstractControl, + JsonFormsModule, } from '@jsonforms/angular'; import { arrayDefaultTranslations, @@ -161,7 +168,15 @@ import { `, ], changeDetection: ChangeDetectionStrategy.OnPush, - standalone: false, + imports: [ + CommonModule, + JsonFormsModule, + MatCardModule, + MatButtonModule, + MatIconModule, + MatBadgeModule, + MatTooltipModule, + ], }) export class ArrayLayoutRenderer extends JsonFormsAbstractControl diff --git a/packages/angular-material/src/library/layouts/categorization-layout.renderer.ts b/packages/angular-material/src/library/layouts/categorization-layout.renderer.ts index 999843f2f5..23526554c5 100644 --- a/packages/angular-material/src/library/layouts/categorization-layout.renderer.ts +++ b/packages/angular-material/src/library/layouts/categorization-layout.renderer.ts @@ -43,7 +43,10 @@ import { Component, OnInit } from '@angular/core'; import { JsonFormsAngularService, JsonFormsBaseRenderer, + JsonFormsModule, } from '@jsonforms/angular'; +import { CommonModule } from '@angular/common'; +import { MatTabsModule } from '@angular/material/tabs'; @Component({ selector: 'jsonforms-categorization-layout', @@ -66,7 +69,7 @@ import { `, - standalone: false, + imports: [CommonModule, JsonFormsModule, MatTabsModule], }) export class CategorizationTabLayoutRenderer extends JsonFormsBaseRenderer diff --git a/packages/angular-material/src/library/layouts/group-layout.renderer.ts b/packages/angular-material/src/library/layouts/group-layout.renderer.ts index ecfb6cd505..0be5bfa82b 100644 --- a/packages/angular-material/src/library/layouts/group-layout.renderer.ts +++ b/packages/angular-material/src/library/layouts/group-layout.renderer.ts @@ -28,8 +28,13 @@ import { Component, } from '@angular/core'; import { GroupLayout, RankedTester, rankWith, uiTypeIs } from '@jsonforms/core'; -import { LayoutRenderer } from './layout.renderer'; -import { JsonFormsAngularService } from '@jsonforms/angular'; +import { + LayoutRenderer, + LayoutChildrenRenderPropsPipe, +} from './layout.renderer'; +import { JsonFormsAngularService, JsonFormsModule } from '@jsonforms/angular'; +import { CommonModule } from '@angular/common'; +import { MatCardModule } from '@angular/material/card'; @Component({ selector: 'GroupLayoutRenderer', @@ -64,7 +69,12 @@ import { JsonFormsAngularService } from '@jsonforms/angular'; `, ], changeDetection: ChangeDetectionStrategy.OnPush, - standalone: false, + imports: [ + CommonModule, + JsonFormsModule, + LayoutChildrenRenderPropsPipe, + MatCardModule, + ], }) export class GroupLayoutRenderer extends LayoutRenderer { constructor( diff --git a/packages/angular-material/src/library/layouts/horizontal-layout.renderer.ts b/packages/angular-material/src/library/layouts/horizontal-layout.renderer.ts index 86f6f4c7c2..1a9e055118 100644 --- a/packages/angular-material/src/library/layouts/horizontal-layout.renderer.ts +++ b/packages/angular-material/src/library/layouts/horizontal-layout.renderer.ts @@ -33,8 +33,12 @@ import { rankWith, uiTypeIs, } from '@jsonforms/core'; -import { LayoutRenderer } from './layout.renderer'; -import { JsonFormsAngularService } from '@jsonforms/angular'; +import { + LayoutRenderer, + LayoutChildrenRenderPropsPipe, +} from './layout.renderer'; +import { JsonFormsAngularService, JsonFormsModule } from '@jsonforms/angular'; +import { CommonModule } from '@angular/common'; @Component({ selector: 'HorizontalLayoutRenderer', @@ -68,7 +72,7 @@ import { JsonFormsAngularService } from '@jsonforms/angular'; `, ], changeDetection: ChangeDetectionStrategy.OnPush, - standalone: false, + imports: [CommonModule, JsonFormsModule, LayoutChildrenRenderPropsPipe], }) export class HorizontalLayoutRenderer extends LayoutRenderer { constructor( diff --git a/packages/angular-material/src/library/layouts/layout.renderer.ts b/packages/angular-material/src/library/layouts/layout.renderer.ts index 23d57aab05..109b1a269e 100644 --- a/packages/angular-material/src/library/layouts/layout.renderer.ts +++ b/packages/angular-material/src/library/layouts/layout.renderer.ts @@ -44,7 +44,6 @@ import { @Component({ template: '', - standalone: false, }) export class LayoutRenderer extends JsonFormsBaseRenderer @@ -80,7 +79,7 @@ export class LayoutRenderer } } -@Pipe({ name: 'layoutChildrenRenderProps', standalone: false }) +@Pipe({ name: 'layoutChildrenRenderProps' }) export class LayoutChildrenRenderPropsPipe implements PipeTransform { transform( uischema: Layout, diff --git a/packages/angular-material/src/library/layouts/vertical-layout.renderer.ts b/packages/angular-material/src/library/layouts/vertical-layout.renderer.ts index 80a1cdafdb..fc5d300334 100644 --- a/packages/angular-material/src/library/layouts/vertical-layout.renderer.ts +++ b/packages/angular-material/src/library/layouts/vertical-layout.renderer.ts @@ -33,8 +33,12 @@ import { uiTypeIs, VerticalLayout, } from '@jsonforms/core'; -import { LayoutRenderer } from './layout.renderer'; -import { JsonFormsAngularService } from '@jsonforms/angular'; +import { + LayoutRenderer, + LayoutChildrenRenderPropsPipe, +} from './layout.renderer'; +import { JsonFormsAngularService, JsonFormsModule } from '@jsonforms/angular'; +import { CommonModule } from '@angular/common'; @Component({ selector: 'VerticalLayoutRenderer', @@ -63,7 +67,7 @@ import { JsonFormsAngularService } from '@jsonforms/angular'; `, ], changeDetection: ChangeDetectionStrategy.OnPush, - standalone: false, + imports: [CommonModule, JsonFormsModule, LayoutChildrenRenderPropsPipe], }) export class VerticalLayoutRenderer extends LayoutRenderer { constructor( diff --git a/packages/angular-material/src/library/module.ts b/packages/angular-material/src/library/module.ts index 15866aeb2a..bee96ef8ff 100644 --- a/packages/angular-material/src/library/module.ts +++ b/packages/angular-material/src/library/module.ts @@ -89,8 +89,6 @@ import { LayoutChildrenRenderPropsPipe } from './layouts'; MatToolbarModule, MatTooltipModule, MatBadgeModule, - ], - declarations: [ BooleanControlRenderer, TextAreaRenderer, TextControlRenderer, @@ -131,6 +129,26 @@ import { LayoutChildrenRenderPropsPipe } from './layouts'; MatButtonModule, MatIconModule, MatAutocompleteModule, + BooleanControlRenderer, + TextAreaRenderer, + TextControlRenderer, + NumberControlRenderer, + RangeControlRenderer, + DateControlRenderer, + ToggleControlRenderer, + VerticalLayoutRenderer, + HorizontalLayoutRenderer, + CategorizationTabLayoutRenderer, + GroupLayoutRenderer, + LabelRenderer, + MasterListComponent, + JsonFormsDetailComponent, + ObjectControlRenderer, + AutocompleteControlRenderer, + TableRenderer, + ArrayLayoutRenderer, + LayoutChildrenRenderPropsPipe, + GetProps, ], schemas: [CUSTOM_ELEMENTS_SCHEMA], providers: [], diff --git a/packages/angular-material/src/library/other/label.renderer.ts b/packages/angular-material/src/library/other/label.renderer.ts index ec5f7e4263..3a049ec37c 100644 --- a/packages/angular-material/src/library/other/label.renderer.ts +++ b/packages/angular-material/src/library/other/label.renderer.ts @@ -47,7 +47,6 @@ import { } `, ], - standalone: false, }) export class LabelRenderer extends JsonFormsBaseRenderer diff --git a/packages/angular-material/src/library/other/master-detail/detail.ts b/packages/angular-material/src/library/other/master-detail/detail.ts index 832815b7f5..a0723f96b3 100644 --- a/packages/angular-material/src/library/other/master-detail/detail.ts +++ b/packages/angular-material/src/library/other/master-detail/detail.ts @@ -23,6 +23,8 @@ THE SOFTWARE. */ import { Component, Input } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { JsonFormsModule } from '@jsonforms/angular'; @Component({ selector: 'jsonforms-detail', @@ -31,7 +33,7 @@ import { Component, Input } from '@angular/core'; `, - standalone: false, + imports: [CommonModule, JsonFormsModule], }) export class JsonFormsDetailComponent { _item: any; diff --git a/packages/angular-material/src/library/other/master-detail/master.ts b/packages/angular-material/src/library/other/master-detail/master.ts index a918d69de9..7e8ad9e49f 100644 --- a/packages/angular-material/src/library/other/master-detail/master.ts +++ b/packages/angular-material/src/library/other/master-detail/master.ts @@ -30,6 +30,11 @@ import { Component, OnInit, } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { MatSidenavModule } from '@angular/material/sidenav'; +import { MatListModule } from '@angular/material/list'; +import { MatButtonModule } from '@angular/material/button'; +import { MatIconModule } from '@angular/material/icon'; import { JsonFormsAngularService, JsonFormsArrayControl, @@ -54,6 +59,7 @@ import { StatePropsOfArrayControl, uiTypeIs, } from '@jsonforms/core'; +import { JsonFormsDetailComponent } from './detail'; const keywords = ['#', 'properties', 'items']; @@ -159,7 +165,14 @@ export const removeSchemaKeywords = (path: string) => { `, ], changeDetection: ChangeDetectionStrategy.OnPush, - standalone: false, + imports: [ + CommonModule, + MatSidenavModule, + MatListModule, + MatButtonModule, + MatIconModule, + JsonFormsDetailComponent, + ], }) export class MasterListComponent extends JsonFormsArrayControl diff --git a/packages/angular-material/src/library/other/object.renderer.ts b/packages/angular-material/src/library/other/object.renderer.ts index 7f5e5e96d5..c85657c8b9 100644 --- a/packages/angular-material/src/library/other/object.renderer.ts +++ b/packages/angular-material/src/library/other/object.renderer.ts @@ -28,7 +28,9 @@ import { ChangeDetectionStrategy, Component } from '@angular/core'; import { JsonFormsAngularService, JsonFormsControlWithDetail, + JsonFormsModule, } from '@jsonforms/angular'; +import { MatCardModule } from '@angular/material/card'; import { ControlWithDetailProps, findUISchema, @@ -62,7 +64,7 @@ import cloneDeep from 'lodash/cloneDeep'; `, ], changeDetection: ChangeDetectionStrategy.OnPush, - standalone: false, + imports: [JsonFormsModule, MatCardModule], }) export class ObjectControlRenderer extends JsonFormsControlWithDetail { detailUiSchema: UISchemaElement; diff --git a/packages/angular-material/src/library/other/table.renderer.ts b/packages/angular-material/src/library/other/table.renderer.ts index 6d86304136..52593e9f8e 100644 --- a/packages/angular-material/src/library/other/table.renderer.ts +++ b/packages/angular-material/src/library/other/table.renderer.ts @@ -24,9 +24,15 @@ */ import startCase from 'lodash/startCase'; import { Component, OnInit, Pipe, PipeTransform } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { MatTableModule } from '@angular/material/table'; +import { MatButtonModule } from '@angular/material/button'; +import { MatIconModule } from '@angular/material/icon'; +import { MatTooltipModule } from '@angular/material/tooltip'; import { JsonFormsAngularService, JsonFormsArrayControl, + JsonFormsModule, } from '@jsonforms/angular'; import { ArrayControlProps, @@ -48,6 +54,30 @@ import { UISchemaElement, } from '@jsonforms/core'; +interface ColumnDescription { + property: string; + header: string; + props: OwnPropsOfRenderer; +} + +export const controlWithoutLabel = (scope: string): ControlElement => ({ + type: 'Control', + scope: scope, + label: false, +}); + +@Pipe({ name: 'getProps' }) +export class GetProps implements PipeTransform { + transform(index: number, props: OwnPropsOfRenderer) { + const rowPath = Paths.compose(props.path, `${index}`); + return { + schema: props.schema, + uischema: props.uischema, + path: rowPath, + }; + } +} + @Component({ selector: 'TableRenderer', template: ` @@ -148,7 +178,15 @@ import { '.sort-column { min-width: 12vw;}', '.table-container {max-width: 100%; overflow: auto;}', ], - standalone: false, + imports: [ + CommonModule, + JsonFormsModule, + MatTableModule, + MatButtonModule, + MatIconModule, + MatTooltipModule, + GetProps, + ], }) export class TableRenderer extends JsonFormsArrayControl implements OnInit { detailUiSchema: UISchemaElement; @@ -260,27 +298,3 @@ export const TableRendererTester: RankedTester = rankWith( 3, or(isObjectArrayControl, isPrimitiveArrayControl) ); - -interface ColumnDescription { - property: string; - header: string; - props: OwnPropsOfRenderer; -} - -export const controlWithoutLabel = (scope: string): ControlElement => ({ - type: 'Control', - scope: scope, - label: false, -}); - -@Pipe({ name: 'getProps', standalone: false }) -export class GetProps implements PipeTransform { - transform(index: number, props: OwnPropsOfRenderer) { - const rowPath = Paths.compose(props.path, `${index}`); - return { - schema: props.schema, - uischema: props.uischema, - path: rowPath, - }; - } -} diff --git a/packages/angular-material/test/autocomplete-control.spec.ts b/packages/angular-material/test/autocomplete-control.spec.ts index 2594330bac..53a0bd645d 100644 --- a/packages/angular-material/test/autocomplete-control.spec.ts +++ b/packages/angular-material/test/autocomplete-control.spec.ts @@ -88,8 +88,7 @@ describe('Autocomplete control Base Tests', () => { let inputElement: HTMLInputElement; beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - declarations: [componentUT], - imports: imports, + imports: [componentUT, ...imports], providers: providers, }).compileComponents(); })); @@ -216,8 +215,7 @@ describe('AutoComplete control Input Event Tests', () => { let loader: HarnessLoader; beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - declarations: [componentUT], - imports: imports, + imports: [componentUT, ...imports], providers: [...providers], }).compileComponents(); })); @@ -283,8 +281,7 @@ describe('AutoComplete control Error Tests', () => { let component: AutocompleteControlRenderer; beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - declarations: [componentUT], - imports: imports, + imports: [componentUT, ...imports], providers: providers, }).compileComponents(); })); @@ -329,8 +326,7 @@ describe('AutoComplete control updateFilter function', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - declarations: [componentUT], - imports: imports, + imports: [componentUT, ...imports], providers: providers, }).compileComponents(); })); diff --git a/packages/angular-material/test/categorization-tab-layout.spec.ts b/packages/angular-material/test/categorization-tab-layout.spec.ts index 5174d4583e..87772253e5 100644 --- a/packages/angular-material/test/categorization-tab-layout.spec.ts +++ b/packages/angular-material/test/categorization-tab-layout.spec.ts @@ -71,8 +71,9 @@ describe('Categorization tab layout', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - declarations: [CategorizationTabLayoutRenderer, TextControlRenderer], imports: [ + CategorizationTabLayoutRenderer, + TextControlRenderer, CommonModule, MatTabsModule, NoopAnimationsModule, diff --git a/packages/angular-material/test/common/layout.ts b/packages/angular-material/test/common/layout.ts index 8fbee8225e..a8751581ed 100644 --- a/packages/angular-material/test/common/layout.ts +++ b/packages/angular-material/test/common/layout.ts @@ -23,19 +23,14 @@ THE SOFTWARE. */ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { - JsonFormsAngularService, - JsonFormsOutlet, - UnknownRenderer, -} from '@jsonforms/angular'; +import { JsonFormsAngularService, JsonFormsModule } from '@jsonforms/angular'; export const beforeEachLayoutTest = ( Renderer: any, { declarations = [], imports = [], providers = [] }: any = {} ): ComponentFixture => { TestBed.configureTestingModule({ - declarations: [Renderer, UnknownRenderer, JsonFormsOutlet, ...declarations], - imports, + imports: [Renderer, JsonFormsModule, ...imports, ...declarations], providers: [JsonFormsAngularService, ...providers], }).compileComponents(); return TestBed.createComponent(Renderer); diff --git a/packages/angular-material/test/common/util.ts b/packages/angular-material/test/common/util.ts index 044fc72910..12b7a6f4d4 100644 --- a/packages/angular-material/test/common/util.ts +++ b/packages/angular-material/test/common/util.ts @@ -48,8 +48,7 @@ export const baseSetup = ( ) => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - declarations: [testConfig.componentUT], - imports: testConfig.imports, + imports: [testConfig.componentUT].concat(testConfig.imports), providers: [JsonFormsAngularService].concat(testConfig.providers), }).compileComponents(); })); diff --git a/packages/angular-material/test/date-control.spec.ts b/packages/angular-material/test/date-control.spec.ts index 01f8ca640b..22900d69de 100644 --- a/packages/angular-material/test/date-control.spec.ts +++ b/packages/angular-material/test/date-control.spec.ts @@ -94,8 +94,7 @@ describe('Date control Base Tests', () => { let inputElement: HTMLInputElement; beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - declarations: [componentUT], - imports: imports, + imports: [componentUT, ...imports], providers: providers, }).compileComponents(); })); @@ -233,8 +232,7 @@ describe('Date control Input Event Tests', () => { let inputElement: HTMLInputElement; beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - declarations: [componentUT], - imports: imports, + imports: [componentUT, ...imports], providers: providers, }).compileComponents(); })); @@ -278,8 +276,7 @@ describe('Date control Error Tests', () => { let component: DateControlRenderer; beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - declarations: [componentUT], - imports: imports, + imports: [componentUT, ...imports], providers: providers, }).compileComponents(); })); diff --git a/packages/angular-material/test/label-renderer.spec.ts b/packages/angular-material/test/label-renderer.spec.ts index 549e59a555..fce6b2e45b 100644 --- a/packages/angular-material/test/label-renderer.spec.ts +++ b/packages/angular-material/test/label-renderer.spec.ts @@ -58,7 +58,7 @@ describe('Label Renderer Base Tests', () => { let labelElement: HTMLLabelElement; beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - declarations: [componentUT], + imports: [componentUT], providers: providers, }).compileComponents(); })); diff --git a/packages/angular-material/test/master-detail.spec.ts b/packages/angular-material/test/master-detail.spec.ts index 7b91e99b06..034587cff3 100644 --- a/packages/angular-material/test/master-detail.spec.ts +++ b/packages/angular-material/test/master-detail.spec.ts @@ -29,11 +29,7 @@ import { MatIconModule } from '@angular/material/icon'; import { MatListItem, MatListModule } from '@angular/material/list'; import { MatSidenavModule } from '@angular/material/sidenav'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { - JsonFormsAngularService, - JsonFormsOutlet, - UnknownRenderer, -} from '@jsonforms/angular'; +import { JsonFormsAngularService, JsonFormsModule } from '@jsonforms/angular'; import { DebugElement } from '@angular/core'; import { MasterListComponent } from '../src/library/other/master-detail/master'; import { JsonFormsDetailComponent } from '../src/library/other/master-detail/detail'; @@ -101,13 +97,10 @@ describe('Master detail', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - declarations: [ - JsonFormsOutlet, + imports: [ MasterListComponent, - UnknownRenderer, JsonFormsDetailComponent, - ], - imports: [ + JsonFormsModule, MatListModule, MatSidenavModule, MatIconModule, diff --git a/packages/angular-material/test/object-control.spec.ts b/packages/angular-material/test/object-control.spec.ts index 26597f79d2..5495118576 100644 --- a/packages/angular-material/test/object-control.spec.ts +++ b/packages/angular-material/test/object-control.spec.ts @@ -93,14 +93,12 @@ describe('Object Control', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - declarations: [ + imports: [ ObjectControlRenderer, TextControlRenderer, VerticalLayoutRenderer, GroupLayoutRenderer, LayoutChildrenRenderPropsPipe, - ], - imports: [ CommonModule, JsonFormsModule, MatCardModule, diff --git a/packages/angular-material/test/table-control.spec.ts b/packages/angular-material/test/table-control.spec.ts index 0d7c23ce95..60b8d90d12 100644 --- a/packages/angular-material/test/table-control.spec.ts +++ b/packages/angular-material/test/table-control.spec.ts @@ -140,8 +140,10 @@ describe('Table', () => { beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ - declarations: [TableRenderer, TextControlRenderer, GetProps], imports: [ + TableRenderer, + TextControlRenderer, + GetProps, CommonModule, JsonFormsModule, MatCardModule, diff --git a/packages/angular/.eslintrc.js b/packages/angular/.eslintrc.js index b0106a07b3..80191b13e9 100644 --- a/packages/angular/.eslintrc.js +++ b/packages/angular/.eslintrc.js @@ -22,8 +22,6 @@ module.exports = { '@angular-eslint/component-class-suffix': 'off', '@angular-eslint/directive-class-suffix': 'off', '@angular-eslint/no-conflicting-lifecycle': 'warn', - // Starting with Angular 19, non-standalone components produce a lint error. Reduce to warning until we migrate. - '@angular-eslint/prefer-standalone': 'warn', '@typescript-eslint/no-explicit-any': 'off', // Base rule must be disabled to avoid incorrect errors 'no-unused-vars': 'off', diff --git a/packages/angular/src/library/abstract-control.ts b/packages/angular/src/library/abstract-control.ts index 0da994a05a..f06233ed3f 100644 --- a/packages/angular/src/library/abstract-control.ts +++ b/packages/angular/src/library/abstract-control.ts @@ -45,7 +45,6 @@ import { JsonFormsAngularService } from './jsonforms.service'; import merge from 'lodash/merge'; @Component({ template: '', - standalone: false, }) export abstract class JsonFormsAbstractControl< Props extends StatePropsOfControl diff --git a/packages/angular/src/library/jsonforms-root.component.ts b/packages/angular/src/library/jsonforms-root.component.ts index e923da9365..c11615cee7 100644 --- a/packages/angular/src/library/jsonforms-root.component.ts +++ b/packages/angular/src/library/jsonforms-root.component.ts @@ -48,6 +48,7 @@ import type Ajv from 'ajv'; import type { ErrorObject } from 'ajv'; import { JsonFormsAngularService, USE_STATE_VALUE } from './jsonforms.service'; import { Subscription } from 'rxjs'; +import { JsonFormsOutlet } from './jsonforms.component'; // TODO Can this be rewritten to not use DoCheck and OnChanges? /* eslint-disable @angular-eslint/no-conflicting-lifecycle */ @@ -55,7 +56,7 @@ import { Subscription } from 'rxjs'; selector: 'jsonforms', template: '', providers: [JsonFormsAngularService], - standalone: false, + imports: [JsonFormsOutlet], }) export class JsonForms implements DoCheck, OnChanges, OnInit, OnDestroy { @Input() uischema: UISchemaElement; diff --git a/packages/angular/src/library/jsonforms.component.ts b/packages/angular/src/library/jsonforms.component.ts index a8720ab079..fd35b81bc3 100644 --- a/packages/angular/src/library/jsonforms.component.ts +++ b/packages/angular/src/library/jsonforms.component.ts @@ -67,7 +67,6 @@ const areEqual = ( @Directive({ selector: 'jsonforms-outlet', - standalone: false, }) export class JsonFormsOutlet extends JsonFormsBaseRenderer diff --git a/packages/angular/src/library/jsonforms.module.ts b/packages/angular/src/library/jsonforms.module.ts index 037af6bc2c..21fc3f3ee3 100644 --- a/packages/angular/src/library/jsonforms.module.ts +++ b/packages/angular/src/library/jsonforms.module.ts @@ -28,7 +28,7 @@ import { JsonForms } from './jsonforms-root.component'; import { JsonFormsOutlet } from './jsonforms.component'; import { UnknownRenderer } from './unknown.component'; @NgModule({ - declarations: [JsonFormsOutlet, UnknownRenderer, JsonForms], + imports: [JsonFormsOutlet, UnknownRenderer, JsonForms], exports: [JsonFormsOutlet, JsonForms], }) export class JsonFormsModule {} diff --git a/packages/angular/src/library/unknown.component.ts b/packages/angular/src/library/unknown.component.ts index cd16d33c52..cb51fbe01f 100644 --- a/packages/angular/src/library/unknown.component.ts +++ b/packages/angular/src/library/unknown.component.ts @@ -26,6 +26,5 @@ import { Component } from '@angular/core'; @Component({ selector: 'unknown.renderer', template: 'No applicable renderer found!', - standalone: false, }) export class UnknownRenderer {}