diff --git a/projects/ng-select2-component/src/lib/select2-interfaces.ts b/projects/ng-select2-component/src/lib/select2-interfaces.ts index ec2e6c1..07a6d30 100644 --- a/projects/ng-select2-component/src/lib/select2-interfaces.ts +++ b/projects/ng-select2-component/src/lib/select2-interfaces.ts @@ -1,3 +1,5 @@ +import { TemplateRef } from '@angular/core'; + import { Select2 } from './select2.component'; export interface Select2Group { @@ -92,3 +94,5 @@ export interface Select2ScrollEvent { } export type Select2SelectionOverride = string | ((params: { size: number; options: Select2Option[] | null }) => string); + +export type Select2Template = TemplateRef | { [key: string]: TemplateRef }; diff --git a/projects/ng-select2-component/src/lib/select2.component.ts b/projects/ng-select2-component/src/lib/select2.component.ts index 16a6e8b..a8a36c5 100644 --- a/projects/ng-select2-component/src/lib/select2.component.ts +++ b/projects/ng-select2-component/src/lib/select2.component.ts @@ -7,27 +7,27 @@ import { } from '@angular/cdk/overlay'; import { ViewportRuler } from '@angular/cdk/scrolling'; import { NgTemplateOutlet } from '@angular/common'; -import type { ElementRef, QueryList } from '@angular/core'; +import type { ElementRef } from '@angular/core'; import { - AfterViewInit, - Attribute, - ChangeDetectorRef, - Component, - DoCheck, - HostBinding, - HostListener, - Input, - OnInit, - Optional, - Self, - TemplateRef, - ViewChild, - ViewChildren, - booleanAttribute, - numberAttribute, - signal, - input, - output + AfterViewInit, + Attribute, + ChangeDetectorRef, + Component, + DoCheck, + HostBinding, + HostListener, + Input, + OnInit, + Optional, + Self, + TemplateRef, + booleanAttribute, + input, + numberAttribute, + output, + signal, + viewChild, + viewChildren, } from '@angular/core'; import { ControlValueAccessor, FormGroupDirective, NgControl, NgForm } from '@angular/forms'; @@ -43,6 +43,7 @@ import { Select2ScrollEvent, Select2SearchEvent, Select2SelectionOverride, + Select2Template, Select2UpdateEvent, Select2UpdateValue, Select2Value, @@ -117,9 +118,7 @@ export class Select2 implements ControlValueAccessor, OnInit, DoCheck, AfterView readonly editPattern = input<(str: string) => string>(undefined); /** template(s) for formatting */ - readonly templates = input | { - [key: string]: TemplateRef; -}>(undefined); + readonly templates = input(undefined); /** template for formatting selected option */ readonly templateSelection = input>(undefined); @@ -300,12 +299,12 @@ export class Select2 implements ControlValueAccessor, OnInit, DoCheck, AfterView private _minCountForSearch?: number; - @ViewChild(CdkConnectedOverlay) private cdkConnectedOverlay: CdkConnectedOverlay; - @ViewChild('selection', { static: true }) private selection: ElementRef; - @ViewChild('results') private resultContainer: ElementRef; - @ViewChildren('result') private results: QueryList; - @ViewChild('searchInput') private searchInput: ElementRef; - @ViewChild('dropdown') private dropdown: ElementRef; + readonly cdkConnectedOverlay = viewChild(CdkConnectedOverlay); + readonly selection = viewChild>('selection'); + readonly resultContainer = viewChild>('results'); + readonly results = viewChildren('result'); + readonly searchInput = viewChild>('searchInput'); + readonly dropdown = viewChild>('dropdown'); private hoveringValue: Select2Value | null | undefined = null; private innerSearchText = ''; @@ -314,7 +313,7 @@ export class Select2 implements ControlValueAccessor, OnInit, DoCheck, AfterView private selectionElement: HTMLElement; private get resultsElement(): HTMLElement { - return this.resultContainer?.nativeElement; + return this.resultContainer()?.nativeElement; } private _stateChanges = new Subject(); @@ -400,7 +399,7 @@ export class Select2 implements ControlValueAccessor, OnInit, DoCheck, AfterView } ngAfterViewInit() { - this.cdkConnectedOverlay.positionChange.subscribe((posChange: ConnectedOverlayPositionChange) => { + this.cdkConnectedOverlay().positionChange.subscribe((posChange: ConnectedOverlayPositionChange) => { if ( this.listPosition() === 'auto' && posChange.connectionPair?.originY && @@ -412,7 +411,7 @@ export class Select2 implements ControlValueAccessor, OnInit, DoCheck, AfterView } }); - this.selectionElement = this.selection.nativeElement; + this.selectionElement = this.selection().nativeElement; this.triggerRect(); } @@ -517,7 +516,7 @@ export class Select2 implements ControlValueAccessor, OnInit, DoCheck, AfterView } setTimeout(() => { this.triggerRect(); - this.cdkConnectedOverlay?.overlayRef?.updatePosition(); + this.cdkConnectedOverlay()?.overlayRef?.updatePosition(); }, 100); }); } @@ -568,9 +567,8 @@ export class Select2 implements ControlValueAccessor, OnInit, DoCheck, AfterView triggerRect() { this._triggerRect = this.selectionElement.getBoundingClientRect(); - this._dropdownRect = this.dropdown?.nativeElement - ? this.dropdown.nativeElement.getBoundingClientRect() - : undefined; + const dropdown = this.dropdown(); + this._dropdownRect = dropdown?.nativeElement ? dropdown.nativeElement.getBoundingClientRect() : undefined; } isNumber(o: any): boolean { @@ -629,11 +627,7 @@ export class Select2 implements ControlValueAccessor, OnInit, DoCheck, AfterView } const limitSelection = this.limitSelection(); - return ( - !this.multiple || - !limitSelection || - (Array.isArray(this._value) && this._value.length < limitSelection) - ); + return !this.multiple || !limitSelection || (Array.isArray(this._value) && this._value.length < limitSelection); } private testValueChange(value1: Select2UpdateValue, value2: Select2UpdateValue) { @@ -1073,7 +1067,7 @@ export class Select2 implements ControlValueAccessor, OnInit, DoCheck, AfterView private updateScrollFromOption(option: Select2Option) { if (option) { this.hoveringValue = option.value; - const domElement = this.results.find(r => r.nativeElement.innerText.trim() === option.label); + const domElement = this.results().find(r => r.nativeElement.innerText.trim() === option.label); if (domElement && this.resultsElement) { this.resultsElement.scrollTop = 0; const listClientRect = this.resultsElement.getBoundingClientRect(); @@ -1179,8 +1173,9 @@ export class Select2 implements ControlValueAccessor, OnInit, DoCheck, AfterView private _focusSearchboxOrResultsElement(focus = true) { if (!this.isSearchboxHidden) { setTimeout(() => { - if (this.searchInput && this.searchInput.nativeElement && focus) { - this.searchInput.nativeElement.focus(); + const searchInput = this.searchInput(); + if (searchInput && searchInput.nativeElement && focus) { + searchInput.nativeElement.focus(); } }); if (this.resultsElement && focus) { @@ -1205,4 +1200,4 @@ export class Select2 implements ControlValueAccessor, OnInit, DoCheck, AfterView ? this._overlayPosition === 'top' : listPosition === 'above'; } -} +} \ No newline at end of file diff --git a/src/app/app.routing.ts b/src/app/app.routing.ts index 6295c9f..5c60c73 100644 --- a/src/app/app.routing.ts +++ b/src/app/app.routing.ts @@ -1,17 +1,15 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; -import { AppExamplesComponent } from './app-examples.component'; -import { AppGenComponent } from './app-gen.component'; const routes: Routes = [ - { path: 'examples', component: AppExamplesComponent }, - { path: 'generator', component: AppGenComponent }, - { path: '**', component: AppExamplesComponent }, + { path: 'examples', loadComponent: () => import('./app-examples.component').then(m => m.AppExamplesComponent) }, + { path: 'generator', loadComponent: () => import('./app-gen.component').then(m => m.AppGenComponent) }, + { path: '**', loadComponent: () => import('./app-examples.component').then(m => m.AppExamplesComponent) }, ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule], }) -export class AppRoutingModule {} +export class AppRoutingModule {} \ No newline at end of file