diff --git a/.browserslistrc b/.browserslistrc deleted file mode 100644 index 427441d..0000000 --- a/.browserslistrc +++ /dev/null @@ -1,17 +0,0 @@ -# This file is used by the build system to adjust CSS and JS output to support the specified browsers below. -# For additional information regarding the format and rule options, please see: -# https://github.com/browserslist/browserslist#queries - -# For the full list of supported browsers by the Angular framework, please see: -# https://angular.io/guide/browser-support - -# You can see what browsers were selected by your queries by running: -# npx browserslist - -last 1 Chrome version -last 1 Firefox version -last 2 Edge major versions -last 2 Safari major versions -last 2 iOS major versions -Firefox ESR -not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line. diff --git a/.gitignore b/.gitignore index adccbd7..ebf9aef 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,5 @@ testem.log .DS_Store Thumbs.db package-lock.json +.angular +.vscode \ No newline at end of file diff --git a/angular.json b/angular.json index 59a8645..196a268 100644 --- a/angular.json +++ b/angular.json @@ -27,6 +27,7 @@ "src/assets" ], "styles": [ + "@angular/material/prebuilt-themes/indigo-pink.css", "src/styles.css" ], "scripts": [] @@ -94,6 +95,7 @@ "src/assets" ], "styles": [ + "@angular/material/prebuilt-themes/indigo-pink.css", "src/styles.css" ], "scripts": [] @@ -132,6 +134,5 @@ } } } - }, - "defaultProject": "ng-modal" + } } diff --git a/package.json b/package.json index f740771..bcf9515 100644 --- a/package.json +++ b/package.json @@ -13,31 +13,25 @@ }, "private": true, "dependencies": { - "@angular/animations": "~12.0.0", - "@angular/common": "~12.0.0", - "@angular/compiler": "~12.0.0", - "@angular/core": "~12.0.0", - "@angular/forms": "~12.0.0", - "@angular/platform-browser": "~12.0.0", - "@angular/platform-browser-dynamic": "~12.0.0", - "@angular/router": "~12.0.0", - "rxjs": "~6.6.0", - "tslib": "^2.1.0", - "zone.js": "~0.11.4" + "@angular/animations": "16.1.7", + "@angular/cdk": "^16.2.7", + "@angular/common": "16.1.7", + "@angular/compiler": "16.1.7", + "@angular/core": "16.1.7", + "@angular/forms": "16.1.7", + "@angular/material": "^16.2.7", + "@angular/platform-browser": "16.1.7", + "@angular/platform-browser-dynamic": "16.1.7", + "@angular/router": "16.1.7", + "rxjs": ">=6.6.0", + "tslib": ">=2.1.0", + "zone.js": ">=0.13.0" }, "devDependencies": { - "@angular-devkit/build-angular": "~12.0.0", - "@angular/cli": "~12.0.0", - "@angular/compiler-cli": "~12.0.0", - "@types/jasmine": "~3.6.0", - "@types/node": "^12.11.1", - "jasmine-core": "~3.7.0", - "karma": "~6.3.0", - "karma-chrome-launcher": "~3.1.0", - "karma-coverage": "~2.0.3", - "karma-jasmine": "~4.0.0", - "karma-jasmine-html-reporter": "^1.5.0", - "ng-packagr": "^12.0.0", - "typescript": "~4.2.3" + "@angular-devkit/build-angular": "16.1.6", + "@angular/cli": "16.1.6", + "@angular/compiler-cli": "16.1.7", + "ng-packagr": "16.1.0", + "typescript": "4.9.5" } -} +} \ No newline at end of file diff --git a/projects/ng-modal-lib/package.json b/projects/ng-modal-lib/package.json index ca7a9db..3f241a8 100644 --- a/projects/ng-modal-lib/package.json +++ b/projects/ng-modal-lib/package.json @@ -1,11 +1,11 @@ { - "name": "ng-modal-lib", - "version": "0.0.9", + "name": "ng-modal-full-resizable", + "version": "0.0.19", "peerDependencies": { - "@angular/common": "^12.0.0", - "@angular/core": "^12.0.0" + "@angular/common": ">=15.1.0", + "@angular/core": ">=15.1.0" }, "dependencies": { - "tslib": "^2.1.0" + "tslib": ">=2.3.0" } } diff --git a/projects/ng-modal-lib/src/lib/injectable/injectable.directive.ts b/projects/ng-modal-lib/src/lib/injectable/injectable.directive.ts new file mode 100644 index 0000000..99ecfd2 --- /dev/null +++ b/projects/ng-modal-lib/src/lib/injectable/injectable.directive.ts @@ -0,0 +1,94 @@ +import { + ChangeDetectorRef, + Directive, + EmbeddedViewRef, + OnChanges, + OnInit, + Renderer2, + SimpleChanges, + TemplateRef, + ViewContainerRef, +} from '@angular/core'; +import { Observable, Subject, take } from 'rxjs'; +import { ModalComponent } from '../modal/modal.component'; + +@Directive({ + selector: '[modalInject]', + exportAs: 'modalInject' +}) +export class ModalInjectDirective implements OnInit, OnChanges { + templateView?: EmbeddedViewRef; + private _modal?: ModalComponent; + constructor( + private templateRef: TemplateRef, + private renderer: Renderer2, + private viewContainerRef: ViewContainerRef, + private cdr: ChangeDetectorRef + ) {} + ngOnChanges(changes: SimpleChanges): void { + this.templateView?.detectChanges(); + } + + ngOnInit(): void { + } + + private findModalParts(nodes: HTMLElement[]) { + const header = nodes.filter(x => (x?.classList?.contains('app-modal-header') ?? false)); + const footer = nodes.filter(x => (x?.classList?.contains('app-modal-footer') ?? false)); + const body = nodes.filter(x => (!x?.classList?.contains('app-modal-footer') && + !x?.classList?.contains('app-modal-header'))); + return [header, body, footer]; + } + + private _resultRx = new Subject(); + get resultRx(): Observable { + return this._resultRx.asObservable(); + } + get modal(): ModalComponent | undefined { + return this._modal; + } + contentOptions?: {[key: string]: any}; + open(modalOptions?: {[key: string]: any }, contentOptions?: {[key: string]: any}): Observable { + this.templateView = this.viewContainerRef.createEmbeddedView(this.templateRef); + let nodes = this.findModalParts(this.templateView.rootNodes); + if(nodes.some(x => !x || x.length == 0)) { + const childNodes = this.findModalParts(Array.from(this.templateView.rootNodes.flatMap(x => Array.from(x.children)))); + let inChildFound = false; + if(nodes[0].length == 0 && childNodes[0].length > 0) { + nodes[0] = childNodes[0]; + inChildFound = true; + } + if(nodes[2].length == 0 && childNodes[2].length > 0) { + nodes[2] = childNodes[2]; + inChildFound = true; + } + if(childNodes[1].length > 0 && inChildFound) + nodes[1] = childNodes[1]; + } + const wrapped = this.viewContainerRef.createComponent(ModalComponent, { + projectableNodes: nodes + }); + if(modalOptions) { + Object.entries(modalOptions).forEach(x => { wrapped.setInput(x[0], x[1])}); + } + if(contentOptions) { + this.contentOptions = contentOptions; + } + this._modal = wrapped.instance; + this.cdr.detectChanges(); + // this._modal!.open(); + // this._modal!.modalRoot?.calcBodyHeight(); + // this._modal?.onClose.pipe(take(1)).subscribe(x => { + // this.close(); + //}) + this.cdr.detectChanges(); + //wrapped.instance.modalRoot?.moveOnTop(); + return this.resultRx; + } + + close(result: any | boolean | null = null) { + this._resultRx.next(result); + //this._modal?.close(); + this.viewContainerRef.clear(); + } +} \ No newline at end of file diff --git a/projects/ng-modal-lib/src/lib/modal/modal-module.ts b/projects/ng-modal-lib/src/lib/modal/modal-module.ts index d945ae9..b0a9142 100644 --- a/projects/ng-modal-lib/src/lib/modal/modal-module.ts +++ b/projects/ng-modal-lib/src/lib/modal/modal-module.ts @@ -3,6 +3,7 @@ import {CommonModule} from '@angular/common'; import {ModalComponent} from './modal.component'; import {ResizableModule} from '../resizable/resizable-module'; import {DraggableModule} from '../draggable/draggable-module'; +import { ModalInjectDirective } from '../injectable/injectable.directive'; @NgModule({ imports: [ @@ -12,6 +13,7 @@ import {DraggableModule} from '../draggable/draggable-module'; ], declarations: [ ModalComponent, + ModalInjectDirective ], exports: [ ModalComponent, diff --git a/projects/ng-modal-lib/src/lib/modal/modal.component.css b/projects/ng-modal-lib/src/lib/modal/modal.component.css index 7e93780..0656d64 100644 --- a/projects/ng-modal-lib/src/lib/modal/modal.component.css +++ b/projects/ng-modal-lib/src/lib/modal/modal.component.css @@ -21,6 +21,7 @@ .ui-modal { display: none; position: fixed; + flex-flow: column nowrap; left: 0; top: 0; outline: none; @@ -30,6 +31,13 @@ min-width: 16.25rem; min-height: 12.5rem; width: 31.25rem; + animation: fadeIn 0.2s; + animation-fill-mode: forwards; +} + +@keyframes fadeIn { + from { opacity: 0; } + to { opacity: 1; } } .ui-modal-header { @@ -45,6 +53,7 @@ } .ui-modal-body { + flex-grow: 1; position: relative; padding: .625rem 1rem; max-height: calc(100vh - 12.5rem); diff --git a/projects/ng-modal-lib/src/lib/modal/modal.component.html b/projects/ng-modal-lib/src/lib/modal/modal.component.html index a0bada8..cbae830 100644 --- a/projects/ng-modal-lib/src/lib/modal/modal.component.html +++ b/projects/ng-modal-lib/src/lib/modal/modal.component.html @@ -1,44 +1,68 @@
+ \ No newline at end of file diff --git a/projects/ng-modal-lib/src/lib/modal/modal.component.ts b/projects/ng-modal-lib/src/lib/modal/modal.component.ts index 8a1d158..3a3836b 100644 --- a/projects/ng-modal-lib/src/lib/modal/modal.component.ts +++ b/projects/ng-modal-lib/src/lib/modal/modal.component.ts @@ -1,31 +1,47 @@ import { - Component, ElementRef, ViewChild, Input, Output, AfterViewChecked, HostListener, EventEmitter, ViewEncapsulation + Component, ElementRef, ViewChild, Input, Output, AfterViewChecked, HostListener, EventEmitter, ViewEncapsulation, ContentChild, TemplateRef, forwardRef, InjectionToken } from '@angular/core'; import {ResizableEvent} from '../resizable/types'; import {maxZIndex, findAncestor} from '../common/utils'; +export const HOST_MODAL = new InjectionToken('HOST_MODAL'); + @Component({ selector: 'app-modal', templateUrl: 'modal.component.html', styleUrls: ['modal.component.css'], encapsulation: ViewEncapsulation.None, + providers: [{ + provide: HOST_MODAL, + useExisting: forwardRef(() => ModalComponent), + multi: true +}] }) export class ModalComponent implements AfterViewChecked { @Input() scrollTopEnable = true; + @Input() resizeable = true; @Input() maximizable: boolean; @Input() backdrop = true; @Input() inViewport: boolean; - + @Input() dontDestroyOnClose = true; + @Input() minHeight = 0; + @Input() setFocus = true; + @Output() openModal: EventEmitter = new EventEmitter(); @Output() closeModal: EventEmitter = new EventEmitter(); - @ViewChild('modalRoot', {static: false}) modalRoot: ElementRef; @ViewChild('modalBody', {static: false}) modalBody: ElementRef; @ViewChild('modalHeader', {static: false}) modalHeader: ElementRef; @ViewChild('modalFooter', {static: false}) modalFooter: ElementRef; @ViewChild('closeIcon', {static: false}) closeIcon: ElementRef; - + @ViewChild('overlay', {static: false}) overlay: ElementRef; + @ContentChild('appModalBody', { descendants: true, static: true }) bodyTemplateRef: TemplateRef; + @ContentChild('appModalHeader', { descendants: true, static: true }) headerTemplateRef: TemplateRef; + @ContentChild('appModalFooter', { descendants: true, static: true }) footerTemplateRef: TemplateRef; + + clearable = false; visible: boolean; + rendered: boolean; executePostDisplayActions: boolean; maximized: boolean; preMaximizeRootWidth: number; @@ -35,7 +51,8 @@ export class ModalComponent implements AfterViewChecked { preMaximizePageY: number; dragEventTarget: MouseEvent | TouchEvent; - constructor(private element: ElementRef) {} + constructor(private element: ElementRef) { + } ngAfterViewChecked(): void { if (this.executePostDisplayActions) { @@ -57,18 +74,26 @@ export class ModalComponent implements AfterViewChecked { this.center(); } - show(): void { + render() { this.executePostDisplayActions = true; - this.visible = true; + this.rendered = true; setTimeout(() => { - this.modalRoot.nativeElement.focus(); + if(this.setFocus) { + this.modalRoot.nativeElement.focus(); + } if (this.scrollTopEnable) { this.modalBody.nativeElement.scrollTop = 0; } + this.openModal.next(true); }, 1); } + show(): void { + this.render(); + this.visible = true; + } hide(): void { + this.rendered = false; this.visible = false; this.closeModal.emit(true); this.focusLastModal(); @@ -80,7 +105,7 @@ export class ModalComponent implements AfterViewChecked { if (elementWidth === 0 && elementHeight === 0) { this.modalRoot.nativeElement.style.visibility = 'hidden'; - this.modalRoot.nativeElement.style.display = 'block'; + this.modalRoot.nativeElement.style.display = 'flex'; elementWidth = this.modalRoot.nativeElement.offsetWidth; elementHeight = this.modalRoot.nativeElement.offsetHeight; this.modalRoot.nativeElement.style.display = 'none'; @@ -136,6 +161,15 @@ export class ModalComponent implements AfterViewChecked { event.preventDefault(); } + resizeToContentHeight() { + const bodyChildren = this.modalBody.nativeElement.children; + const bodyRect = this.modalBody.nativeElement.getBoundingClientRect(); + if(!bodyChildren || bodyChildren.length == 0) + return; + const height = Math.max(...[...bodyChildren].map(x => x.getBoundingClientRect()).map(x => x.top + x.height - bodyRect.top)); + this.modalBody.nativeElement.style.height = height + 16 + 'px'; + this.modalBody.nativeElement.style.maxHeight = 'none'; + } maximize(): void { this.preMaximizePageX = parseFloat(this.modalRoot.nativeElement.style.top); this.preMaximizePageY = parseFloat(this.modalRoot.nativeElement.style.left); @@ -165,14 +199,16 @@ export class ModalComponent implements AfterViewChecked { } moveOnTop(): void { - if (!this.backdrop) { const maxModalIndex = this.getMaxModalIndex(); let zIndex = parseFloat(window.getComputedStyle(this.modalRoot.nativeElement).zIndex) || 0; if (zIndex <= maxModalIndex) { zIndex = maxModalIndex + 1; - this.modalRoot.nativeElement.style.zIndex = zIndex.toString(); + this.overlay.nativeElement.style.zIndex = zIndex.toString(); + this.modalRoot.nativeElement.style.zIndex = (zIndex + 1).toString(); } - } } + setVisible(visible: boolean = true) { + this.visible = visible; + } } diff --git a/projects/ng-modal-lib/src/lib/resizable/resizable.directive.ts b/projects/ng-modal-lib/src/lib/resizable/resizable.directive.ts index 43dfc61..af29f3e 100644 --- a/projects/ng-modal-lib/src/lib/resizable/resizable.directive.ts +++ b/projects/ng-modal-lib/src/lib/resizable/resizable.directive.ts @@ -10,7 +10,7 @@ import { ResizableEvent } from './types'; selector: '[appResizable]' }) export class ResizableDirective implements OnDestroy, AfterViewInit { - + @Input() appResizable = true; @Input() south: boolean; @Input() east: boolean; @Input() southEast: boolean; @@ -20,6 +20,7 @@ export class ResizableDirective implements OnDestroy, AfterViewInit { @Input() northWest: boolean; @Input() north: boolean; @Input() northEast: boolean; + @Input() restrictHeight: number = 0; @Output() resizeBegin: EventEmitter = new EventEmitter(); @Output() resizing: EventEmitter = new EventEmitter(); @@ -50,6 +51,9 @@ export class ResizableDirective implements OnDestroy, AfterViewInit { } ngAfterViewInit(): void { + if(!this.appResizable) { + return; + } if (this.south) { this.createHandle('resize-handle-s'); } @@ -77,7 +81,7 @@ export class ResizableDirective implements OnDestroy, AfterViewInit { const computedStyle = window.getComputedStyle(this.element); this.minWidth = parseFloat(computedStyle.minWidth); this.maxWidth = parseFloat(computedStyle.maxWidth); - this.minHeight = parseFloat(computedStyle.minHeight); + this.minHeight = this.restrictHeight ?? parseFloat(computedStyle.minHeight); this.maxHeight = parseFloat(computedStyle.maxHeight); } diff --git a/projects/ng-modal-lib/src/test.ts b/projects/ng-modal-lib/src/test.ts index 52e5516..e63a876 100644 --- a/projects/ng-modal-lib/src/test.ts +++ b/projects/ng-modal-lib/src/test.ts @@ -8,19 +8,8 @@ import { platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; -declare const require: { - context(path: string, deep?: boolean, filter?: RegExp): { - keys(): string[]; - (id: string): T; - }; -}; - // First, initialize the Angular testing environment. getTestBed().initTestEnvironment( BrowserDynamicTestingModule, platformBrowserDynamicTesting() ); -// Then we find all the tests. -const context = require.context('./', true, /\.spec\.ts$/); -// And load the modules. -context.keys().map(context); diff --git a/projects/ng-modal-lib/tsconfig.lib.json b/projects/ng-modal-lib/tsconfig.lib.json index 1407202..943115f 100644 --- a/projects/ng-modal-lib/tsconfig.lib.json +++ b/projects/ng-modal-lib/tsconfig.lib.json @@ -3,14 +3,13 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": "../../out-tsc/lib", - "target": "es2015", "declaration": true, "declarationMap": true, "inlineSources": true, "types": [], "lib": [ "dom", - "es2018" + "es2019" ] }, "exclude": [ diff --git a/src/app/app.component.html b/src/app/app.component.html index 33663ba..078dea8 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -12,10 +12,19 @@ Panels demo + + Tabs demo + + Deffered Rendering Demo +
+ +
diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 9709568..0a22fc4 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,11 +1,14 @@ -import { BrowserModule } from '@angular/platform-browser'; +import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { NgModule } from '@angular/core'; import { ModalModule } from 'ng-modal-lib'; - import { AppComponent } from './app.component'; import { ModalDemoComponent } from './modal-demo.component'; -import { NestedModalDemoComponent } from './nested-modal-demo.component'; import { PanelDemoComponent } from './panel-demo.component'; +import { NestedModalDemoComponent } from './nested-modal-demo.component copy'; +import { MatTabsModule } from '@angular/material/tabs'; +import { TabsModalComponent } from './tabs-modal.component'; +import { MatSlideToggleModule } from '@angular/material/slide-toggle'; +import { DeferredRenderingContentComponent, DeferredRenderingDemoModalComponent } from './deferred-rendering-demo.component'; @NgModule({ declarations: [ @@ -13,10 +16,15 @@ import { PanelDemoComponent } from './panel-demo.component'; ModalDemoComponent, NestedModalDemoComponent, PanelDemoComponent, + TabsModalComponent, + DeferredRenderingDemoModalComponent, + DeferredRenderingContentComponent ], imports: [ - BrowserModule, - ModalModule + BrowserAnimationsModule, + ModalModule, + MatTabsModule, + MatSlideToggleModule ], bootstrap: [AppComponent] }) diff --git a/src/app/deferred-rendering-demo.component.ts b/src/app/deferred-rendering-demo.component.ts new file mode 100644 index 0000000..e295ebc --- /dev/null +++ b/src/app/deferred-rendering-demo.component.ts @@ -0,0 +1,59 @@ +import { AfterViewInit, Component, Inject } from "@angular/core"; +import { HOST_MODAL, ModalComponent } from "ng-modal-lib"; + +@Component({ + selector: 'app-deffered-rendering-demo', + template: ` + + + Demo modal + + + + +   + + + + + `, + styles: [``] +}) +export class DeferredRenderingDemoModalComponent { + +} + +@Component({ + selector: 'app-deferred-rendering-content', + template: ` +
+

MODAL DIALOG

+

Lorem Ipsum is simply dummy text of the printing and typesetting industry. + Lorem Ipsum has been the industry’s standard dummy text ever since the 1500s.

+
+
+
+ {{item}}
+
+ Content Goes Here +
+ + `, + styles: [] +}) +export class DeferredRenderingContentComponent implements AfterViewInit { + items = [1]; + + constructor(@Inject(HOST_MODAL) private modal: ModalComponent) { + } + + ngAfterViewInit(): void { + setTimeout(() => { + this.items.push(1, 2, 3); + this.modal[0].setVisible(); + }, 1000) + } +} \ No newline at end of file diff --git a/src/app/modal-demo.component.ts b/src/app/modal-demo.component.ts index f38e312..85891e4 100644 --- a/src/app/modal-demo.component.ts +++ b/src/app/modal-demo.component.ts @@ -1,29 +1,43 @@ -import { Component } from '@angular/core'; +import { Component, ViewChild, ViewChildren } from '@angular/core'; +import { ModalComponent } from 'ng-modal-lib'; @Component({ selector: 'app-modal-demo', template: ` - - - Demo modal - -

MODAL DIALOG

-

Lorem Ipsum is simply dummy text of the printing and typesetting industry. - Lorem Ipsum has been the industry’s standard dummy text ever since the 1500s.

-
- -   - - - -
+ + + Demo modal + +
+

MODAL DIALOG

+

Lorem Ipsum is simply dummy text of the printing and typesetting industry. + Lorem Ipsum has been the industry’s standard dummy text ever since the 1500s.

+
+ +
+ +   + + + +
`, }) export class ModalDemoComponent { + @ViewChild('modalRoot') modalRoot: ModalComponent; + onOpenModal(): void { + console.log('opened'); + this.modalRoot.resizeToContentHeight(); + } + onCloseModal(): void { + } - onCloseModal(): void {} - + resize() { + this.modalRoot.clearable = !this.modalRoot.clearable; + } } diff --git a/src/app/nested-modal-demo.component.ts b/src/app/nested-modal-demo.component copy.ts similarity index 100% rename from src/app/nested-modal-demo.component.ts rename to src/app/nested-modal-demo.component copy.ts diff --git a/src/app/tabs-modal.component.ts b/src/app/tabs-modal.component.ts new file mode 100644 index 0000000..399373a --- /dev/null +++ b/src/app/tabs-modal.component.ts @@ -0,0 +1,36 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-tab-modal', + template: ` + + + + Demo modal + + + +
+

MODAL DIALOG

+

Lorem Ipsum is simply dummy text of the printing and typesetting industry. + Lorem Ipsum has been the industry’s standard dummy text ever since the 1500s.

+
+ +
+ + Content 2 + Toggle me! + + Content 3 +
+
+ +   + + +
+ `, +}) +export class TabsModalComponent { + +} diff --git a/src/index.html b/src/index.html index b93a248..e79d491 100644 --- a/src/index.html +++ b/src/index.html @@ -8,8 +8,11 @@ + + + - + diff --git a/src/styles.css b/src/styles.css index 7780b75..3c5ab0c 100644 --- a/src/styles.css +++ b/src/styles.css @@ -23,3 +23,6 @@ a { .ui-modal-header { background-color: #5b9bd5; } + +html, body { height: 100%; } +body { margin: 0; font-family: Roboto, "Helvetica Neue", sans-serif; } diff --git a/src/test.ts b/src/test.ts index 2042356..7632e27 100644 --- a/src/test.ts +++ b/src/test.ts @@ -7,19 +7,8 @@ import { platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; -declare const require: { - context(path: string, deep?: boolean, filter?: RegExp): { - keys(): string[]; - (id: string): T; - }; -}; - // First, initialize the Angular testing environment. getTestBed().initTestEnvironment( BrowserDynamicTestingModule, platformBrowserDynamicTesting() ); -// Then we find all the tests. -const context = require.context('./', true, /\.spec\.ts$/); -// And load the modules. -context.keys().map(context); diff --git a/tsconfig.json b/tsconfig.json index 337e537..1fdac0f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -20,12 +20,13 @@ "experimentalDecorators": true, "moduleResolution": "node", "importHelpers": true, - "target": "es2017", + "target": "ES2022", "module": "es2020", "lib": [ - "es2018", + "es2019", "dom" - ] + ], + "useDefineForClassFields": false }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false,