feat(ui): Added textarea component to ui-libs. (TV-849)

Squashed commit of the following:

commit 61ecaf467c63cdd10f4d66131b105d3b12d60e49
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date:   Wed Nov 3 11:14:19 2021 +0100

    Removed unused input

commit 2254c1dd547cbf3639e5232fe6d8e657491a369c
Author: Erik Tiekstra <erik.tiekstra@arbetsformedlingen.se>
Date:   Wed Nov 3 11:12:38 2021 +0100

    Implemented textarea component inside ui-libs
This commit is contained in:
Erik Tiekstra
2021-11-03 12:04:15 +01:00
parent 37cdf9285a
commit e51e13dfa8
17 changed files with 256 additions and 63 deletions

View File

@@ -24,19 +24,16 @@
</li> </li>
</ol> </ol>
</div> </div>
<digi-ng-form-textarea <ui-textarea
formControlName="emails" formControlName="emails"
afSize="m" uiLabel="E-postadresser"
afDescription="För att skicka inbjudningar till flera e-postadresser samtidigt kan e-postadresser uiDescription="För att skicka inbjudningar till flera e-postadresser samtidigt kan e-postadresser
separeras med bl.a. kommatecken eller mellanslag. Se fler exempel innanför textfältet nedan. separeras med bl.a. kommatecken eller mellanslag. Se fler exempel innanför textfältet nedan.
Antalet mellanslag spelar inte roll och en blandning av tecknen går också bra." Antalet mellanslag spelar inte roll och en blandning av tecknen går också bra."
afPlaceholder="namn@foretag.se namn@foretag.se, namn@foretag.se; namn@foretag.se:namn@foretag.se,namn@foretag.se: namn@foretag.se" [uiRequired]="true"
[afRequired]="true" [uiInvalid]="emailsControl.invalid && emailsControl.dirty"
[afDisableValidStyle]="true" [uiValidationMessage]="emailsControl.errors?.required || emailsControl.errors?.invalid || 'Ogiltig e-postadress'"
[afInvalidMessage]="emailsControl.errors?.required || emailsControl.errors?.invalid || 'Ogiltig e-postadress'" ></ui-textarea>
[afInvalid]="emailsControl.invalid && emailsControl.dirty"
afLabel="E-postadresser"
></digi-ng-form-textarea>
<digi-notification-alert <digi-notification-alert
*ngIf="(lastInvites$ | async) && !emailsControl.dirty" *ngIf="(lastInvites$ | async) && !emailsControl.dirty"

View File

@@ -1,4 +1,3 @@
import { DigiNgFormTextareaModule } from '@af/digi-ng/_form/form-textarea';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms'; import { ReactiveFormsModule } from '@angular/forms';
@@ -6,6 +5,7 @@ import { RouterModule } from '@angular/router';
import { BackLinkModule } from '@msfa-shared/components/back-link/back-link.module'; import { BackLinkModule } from '@msfa-shared/components/back-link/back-link.module';
import { LayoutModule } from '@msfa-shared/components/layout/layout.module'; import { LayoutModule } from '@msfa-shared/components/layout/layout.module';
import { UiLoaderModule } from '@ui/loader/loader.module'; import { UiLoaderModule } from '@ui/loader/loader.module';
import { UiTextareaModule } from '@ui/textarea/textarea.module';
import { EmployeeInviteComponent } from './employee-invite.component'; import { EmployeeInviteComponent } from './employee-invite.component';
@NgModule({ @NgModule({
@@ -17,7 +17,7 @@ import { EmployeeInviteComponent } from './employee-invite.component';
LayoutModule, LayoutModule,
BackLinkModule, BackLinkModule,
ReactiveFormsModule, ReactiveFormsModule,
DigiNgFormTextareaModule, UiTextareaModule,
UiLoaderModule, UiLoaderModule,
], ],
}) })

View File

@@ -58,16 +58,15 @@
class="avvikelse-report-form__form-item" class="avvikelse-report-form__form-item"
*ngFor="let question of questionsFormArray.controls; let i=index" *ngFor="let question of questionsFormArray.controls; let i=index"
> >
<digi-ng-form-textarea <ui-textarea
[formControlName]="i" [formControlName]="i"
[afLabel]="questions[i]?.name" [uiLabel]="questions[i]?.name"
[afDisableValidStyle]="true" [uiRequired]="questionIsRequired(questions[i])"
[afRequired]="questionIsRequired(questions[i])" [uiValidationMessage]="question.errors?.required || question.errors?.invalid"
[afInvalidMessage]="question.errors?.required || question.errors?.invalid" [uiAnnounceIfOptional]="true"
[afAnnounceIfOptional]="true" [uiMaxLength]="2000"
[afMaxLength]="2000" [uiInvalid]="formControlIsInvalid(question)"
[afInvalid]="formControlIsInvalid(question)" ></ui-textarea>
></digi-ng-form-textarea>
</div> </div>
</div> </div>

View File

@@ -3,7 +3,6 @@ import { DigiNgFormDatepickerModule } from '@af/digi-ng/_form/form-datepicker';
import { DigiNgFormInputModule } from '@af/digi-ng/_form/form-input'; import { DigiNgFormInputModule } from '@af/digi-ng/_form/form-input';
import { DigiNgFormRadiobuttonGroupModule } from '@af/digi-ng/_form/form-radiobutton-group'; import { DigiNgFormRadiobuttonGroupModule } from '@af/digi-ng/_form/form-radiobutton-group';
import { DigiNgFormSelectModule } from '@af/digi-ng/_form/form-select'; import { DigiNgFormSelectModule } from '@af/digi-ng/_form/form-select';
import { DigiNgFormTextareaModule } from '@af/digi-ng/_form/form-textarea';
import { DigiNgProgressProgressbarModule } from '@af/digi-ng/_progress/progressbar'; import { DigiNgProgressProgressbarModule } from '@af/digi-ng/_progress/progressbar';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
@@ -14,6 +13,7 @@ import { ConfirmDialogModule } from '@msfa-shared/components/confirm-dialog/conf
import { LayoutModule } from '@msfa-shared/components/layout/layout.module'; import { LayoutModule } from '@msfa-shared/components/layout/layout.module';
import { UiLoaderModule } from '@ui/loader/loader.module'; import { UiLoaderModule } from '@ui/loader/loader.module';
import { UiSkeletonModule } from '@ui/skeleton/skeleton.module'; import { UiSkeletonModule } from '@ui/skeleton/skeleton.module';
import { UiTextareaModule } from '@ui/textarea/textarea.module';
import { ReportDescriptionListModule } from '../../../components/report-description-list/report-description-list.module'; import { ReportDescriptionListModule } from '../../../components/report-description-list/report-description-list.module';
import { ReportLayoutModule } from '../../../components/report-layout/report-layout.module'; import { ReportLayoutModule } from '../../../components/report-layout/report-layout.module';
import { AvvikelseReportFormComponent } from './avvikelse-report-form.component'; import { AvvikelseReportFormComponent } from './avvikelse-report-form.component';
@@ -29,7 +29,6 @@ import { AvvikelseReportFormService } from './avvikelse-report-form.service';
ReactiveFormsModule, ReactiveFormsModule,
DigiNgFormRadiobuttonGroupModule, DigiNgFormRadiobuttonGroupModule,
DigiNgFormDatepickerModule, DigiNgFormDatepickerModule,
DigiNgFormTextareaModule,
DigiNgProgressProgressbarModule, DigiNgProgressProgressbarModule,
ReportLayoutModule, ReportLayoutModule,
ConfirmDialogModule, ConfirmDialogModule,
@@ -40,6 +39,7 @@ import { AvvikelseReportFormService } from './avvikelse-report-form.service';
ReportDescriptionListModule, ReportDescriptionListModule,
DigiNgFormInputModule, DigiNgFormInputModule,
DigiNgDialogModule, DigiNgDialogModule,
UiTextareaModule,
], ],
providers: [AvvikelseReportFormService], providers: [AvvikelseReportFormService],
exports: [AvvikelseReportFormComponent], exports: [AvvikelseReportFormComponent],

View File

@@ -87,24 +87,15 @@
</div> </div>
<div class="franvaro-report-form__form-item" *ngIf="showKnownReasonTextArea"> <div class="franvaro-report-form__form-item" *ngIf="showKnownReasonTextArea">
<digi-ng-form-textarea <ui-textarea
[afDisableValidStyle]="true"
[afInvalid]="formControlIsInvalid(['knownReasonComment'])"
[afMaxLength]="2000"
[afAnnounceIfOptional]="true"
[afRequired]="true"
afLabel="Beskriv frånvaro"
afSize="s"
[formControl]="knownReasonCommentFormControl" [formControl]="knownReasonCommentFormControl"
></digi-ng-form-textarea> uiLabel="Beskriv frånvaro"
<div aria-atomic="true" role="alert"> [uiInvalid]="formControlIsInvalid(['knownReasonComment'])"
<digi-ng-form-validation-message [uiValidationMessage]="formErrors?.knownReasonComment"
*ngIf="formControlIsInvalid(['knownReasonComment'])" [uiMaxLength]="2000"
class="franvaro-report-form__validation-message" [uiRequired]="true"
[afPositive]="false" [uiAnnounceIfOptional]="true"
[afValidationText]="formErrors.knownReasonComment" ></ui-textarea>
></digi-ng-form-validation-message>
</div>
</div> </div>
</ng-container> </ng-container>

View File

@@ -3,7 +3,6 @@ import { DigiNgFormDatepickerModule } from '@af/digi-ng/_form/form-datepicker';
import { DigiNgFormInputModule } from '@af/digi-ng/_form/form-input'; import { DigiNgFormInputModule } from '@af/digi-ng/_form/form-input';
import { DigiNgFormRadiobuttonGroupModule } from '@af/digi-ng/_form/form-radiobutton-group'; import { DigiNgFormRadiobuttonGroupModule } from '@af/digi-ng/_form/form-radiobutton-group';
import { DigiNgFormSelectModule } from '@af/digi-ng/_form/form-select'; import { DigiNgFormSelectModule } from '@af/digi-ng/_form/form-select';
import { DigiNgFormTextareaModule } from '@af/digi-ng/_form/form-textarea';
import { DigiNgFormValidationMessageModule } from '@af/digi-ng/_form/form-validation-message'; import { DigiNgFormValidationMessageModule } from '@af/digi-ng/_form/form-validation-message';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
@@ -13,6 +12,7 @@ import { BackLinkModule } from '@msfa-shared/components/back-link/back-link.modu
import { LayoutModule } from '@msfa-shared/components/layout/layout.module'; import { LayoutModule } from '@msfa-shared/components/layout/layout.module';
import { UiLoaderModule } from '@ui/loader/loader.module'; import { UiLoaderModule } from '@ui/loader/loader.module';
import { UiSkeletonModule } from '@ui/skeleton/skeleton.module'; import { UiSkeletonModule } from '@ui/skeleton/skeleton.module';
import { UiTextareaModule } from '@ui/textarea/textarea.module';
import { ReportDescriptionListModule } from '../../../components/report-description-list/report-description-list.module'; import { ReportDescriptionListModule } from '../../../components/report-description-list/report-description-list.module';
import { ReportLayoutModule } from '../../../components/report-layout/report-layout.module'; import { ReportLayoutModule } from '../../../components/report-layout/report-layout.module';
import { FranvaroReportFormComponent } from './franvaro-report-form.component'; import { FranvaroReportFormComponent } from './franvaro-report-form.component';
@@ -34,10 +34,10 @@ import { FranvaroReportFormService } from './franvaro-report-form.service';
DigiNgFormDatepickerModule, DigiNgFormDatepickerModule,
DigiNgFormRadiobuttonGroupModule, DigiNgFormRadiobuttonGroupModule,
UiSkeletonModule, UiSkeletonModule,
DigiNgFormTextareaModule,
DigiNgFormInputModule, DigiNgFormInputModule,
DigiNgFormValidationMessageModule, DigiNgFormValidationMessageModule,
DigiNgDialogModule, DigiNgDialogModule,
UiTextareaModule,
], ],
providers: [FranvaroReportFormService], providers: [FranvaroReportFormService],
exports: [FranvaroReportFormComponent], exports: [FranvaroReportFormComponent],

View File

@@ -61,17 +61,16 @@
></digi-ng-form-select> ></digi-ng-form-select>
</div> </div>
<div class="informativ-rapport-form__form-item"> <div class="informativ-rapport-form__form-item">
<digi-ng-form-textarea <ui-textarea
[formControl]="commentFormControl" [formControl]="commentFormControl"
afLabel="Kompletterande information" uiLabel="Kompletterande information"
afDescription="Undvik att skriva in information som känsliga personuppgifter, skyddad identitet eller deltagarens mående. Skriv i sådant fall in det telefonnummer du vill bli kontaktad på, vi bedömer om återkoppling är relevant." uiDescription="Undvik att skriva in information som känsliga personuppgifter, skyddad identitet eller deltagarens mående. Skriv i sådant fall in det telefonnummer du vill bli kontaktad på, vi bedömer om återkoppling är relevant."
[afDisableValidStyle]="true" [uiRequired]="true"
[afRequired]="true" [uiInvalid]="formControlIsInvalid('comment')"
[afInvalidMessage]="commentFormControl.errors?.required" [uiValidationMessage]="commentFormControl.errors?.required"
[afAnnounceIfOptional]="true" [uiAnnounceIfOptional]="true"
[afMaxLength]="2000" [uiMaxLength]="2000"
[afInvalid]="formControlIsInvalid('comment')" ></ui-textarea>
></digi-ng-form-textarea>
</div> </div>
<footer class="informativ-rapport-form__footer"> <footer class="informativ-rapport-form__footer">

View File

@@ -1,7 +1,5 @@
import { DigiNgDialogModule } from '@af/digi-ng/_dialog/dialog'; import { DigiNgDialogModule } from '@af/digi-ng/_dialog/dialog';
import { DigiNgFormSelectModule } from '@af/digi-ng/_form/form-select'; import { DigiNgFormSelectModule } from '@af/digi-ng/_form/form-select';
import { DigiNgFormTextareaModule } from '@af/digi-ng/_form/form-textarea';
import { UiSkeletonModule } from '@ui/skeleton/skeleton.module';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms'; import { ReactiveFormsModule } from '@angular/forms';
@@ -9,6 +7,8 @@ import { RouterModule } from '@angular/router';
import { BackLinkModule } from '@msfa-shared/components/back-link/back-link.module'; import { BackLinkModule } from '@msfa-shared/components/back-link/back-link.module';
import { ConfirmDialogModule } from '@msfa-shared/components/confirm-dialog/confirm-dialog.module'; import { ConfirmDialogModule } from '@msfa-shared/components/confirm-dialog/confirm-dialog.module';
import { LayoutModule } from '@msfa-shared/components/layout/layout.module'; import { LayoutModule } from '@msfa-shared/components/layout/layout.module';
import { UiSkeletonModule } from '@ui/skeleton/skeleton.module';
import { UiTextareaModule } from '@ui/textarea/textarea.module';
import { ReportDescriptionListModule } from '../../../components/report-description-list/report-description-list.module'; import { ReportDescriptionListModule } from '../../../components/report-description-list/report-description-list.module';
import { ReportLayoutModule } from '../../../components/report-layout/report-layout.module'; import { ReportLayoutModule } from '../../../components/report-layout/report-layout.module';
import { InformativRapportFormComponent } from './informativ-rapport-form.component'; import { InformativRapportFormComponent } from './informativ-rapport-form.component';
@@ -29,7 +29,7 @@ import { InformativRapportFormService } from './informativ-rapport-form.service'
UiSkeletonModule, UiSkeletonModule,
DigiNgDialogModule, DigiNgDialogModule,
DigiNgFormSelectModule, DigiNgFormSelectModule,
DigiNgFormTextareaModule, UiTextareaModule,
], ],
providers: [InformativRapportFormService], providers: [InformativRapportFormService],
exports: [InformativRapportFormComponent], exports: [InformativRapportFormComponent],

View File

@@ -1,5 +1,5 @@
/* tslint:disable:no-unused-variable */ /* tslint:disable:no-unused-variable */
import { FormCheckboxComponent } from './form-checkbox.component'; import { CheckboxComponent } from './checkbox.component';
export class MockInjector { export class MockInjector {
get = jest.fn(); get = jest.fn();
@@ -14,10 +14,10 @@ export class MockChangeDetectorRef {
checkNoChanges = jest.fn(); checkNoChanges = jest.fn();
} }
describe('FormCheckboxComponent', () => { describe('CheckboxComponent', () => {
let component: FormCheckboxComponent; let component: CheckboxComponent;
it('should create', () => { it('should create', () => {
component = new FormCheckboxComponent(new MockInjector(), new MockChangeDetectorRef()); component = new CheckboxComponent(new MockInjector(), new MockChangeDetectorRef());
expect(component).toBeTruthy(); expect(component).toBeTruthy();
}); });
}); });

View File

@@ -8,7 +8,6 @@ import {
Input, Input,
OnChanges, OnChanges,
Output, Output,
SimpleChanges,
} from '@angular/core'; } from '@angular/core';
import { ControlValueAccessor, NgControl, NG_VALUE_ACCESSOR } from '@angular/forms'; import { ControlValueAccessor, NgControl, NG_VALUE_ACCESSOR } from '@angular/forms';
import { uuid } from '@utils/uuid.util'; import { uuid } from '@utils/uuid.util';
@@ -42,7 +41,7 @@ export class CheckboxComponent implements AfterViewInit, ControlValueAccessor, O
@Input() uiId: string = uuid(); @Input() uiId: string = uuid();
@Input() uiName: string; @Input() uiName: string;
@Input() uiAnnounceIfOptional: boolean = false; @Input() uiAnnounceIfOptional: boolean = false;
@Output() uiOnChange: EventEmitter<any> = new EventEmitter(); @Output() uiOnChange: EventEmitter<boolean> = new EventEmitter();
name: string | number; name: string | number;
@@ -79,7 +78,7 @@ export class CheckboxComponent implements AfterViewInit, ControlValueAccessor, O
} }
} }
ngOnChanges(changes: SimpleChanges): void { ngOnChanges(): void {
const ngControl: NgControl = this.injector.get(NgControl, null); const ngControl: NgControl = this.injector.get(NgControl, null);
if (ngControl) { if (ngControl) {
this.name = ngControl.name; this.name = ngControl.name;
@@ -96,7 +95,7 @@ export class CheckboxComponent implements AfterViewInit, ControlValueAccessor, O
} }
} }
writeValue(value: any): void { writeValue(value: boolean): void {
this._value = value; this._value = value;
this.changeDetectorRef.detectChanges(); this.changeDetectorRef.detectChanges();
} }

View File

@@ -0,0 +1,6 @@
export enum UiTextAreaVariation {
AUTO = 'auto',
S = 's',
M = 'm',
L = 'l',
}

View File

@@ -0,0 +1,26 @@
<div
class="ui-textarea"
[ngClass]="{'ui-textarea--invalid': uiInvalid && uiValidationMessage, 'ui-textarea--with-counter': uiMaxLength}"
>
<digi-form-textarea
class="ui-textarea__textarea"
[afId]="uiId"
[afName]="uiName"
[afLabel]="uiLabel"
[afLabelDescription]="uiDescription"
[afVariation]="uiVariation"
[afRequired]="uiRequired"
[afAnnounceIfOptional]="uiAnnounceIfOptional"
[afMaxlength]="uiMaxLength"
[afMinlength]="uiMinLength"
[afValue]="currentValue"
[afValidation]="uiInvalid ? 'error' : 'neutral'"
(afOnInput)="checkForChange($event.detail.target.value)"
></digi-form-textarea>
<span class="ui-textarea__counter" *ngIf="uiMaxLength">{{charactersLeft}} tecken kvar</span>
<div class="ui-textarea__validation" aria-atomic="true" role="alert">
<digi-form-validation-message *ngIf="uiInvalid && uiValidationMessage" af-variation="error"
>{{uiValidationMessage}}</digi-form-validation-message
>
</div>
</div>

View File

@@ -0,0 +1,25 @@
.ui-textarea {
display: grid;
grid-template-columns: 1fr max-content;
grid-template-areas:
'textarea textarea'
'validation counter';
&--invalid,
&--with-counter {
gap: var(--digi--layout--gutter--s);
}
&__textarea {
grid-area: textarea;
}
&__counter {
grid-area: counter;
color: var(--digi--typography--color--text--dimmed);
font-size: var(--digi--typography--font-size--s);
}
&__validation {
grid-area: validation;
}
}

View File

@@ -0,0 +1,23 @@
/* tslint:disable:no-unused-variable */
import { TextareaComponent } from './textarea.component';
export class MockInjector {
get = jest.fn();
}
// tslint:disable-next-line: max-classes-per-file
export class MockChangeDetectorRef {
markForCheck = jest.fn();
detach = jest.fn();
detectChanges = jest.fn();
reattach = jest.fn();
checkNoChanges = jest.fn();
}
describe('TextareaComponent', () => {
let component: TextareaComponent;
it('should create', () => {
component = new TextareaComponent(new MockInjector(), new MockChangeDetectorRef());
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,16 @@
import { ReactiveFormsModule } from '@angular/forms';
import { TextareaComponent } from './textarea.component';
import { UiTextareaModule } from './textarea.module';
export default { title: 'Textarea', component: TextareaComponent };
const componentModule = {
moduleMetadata: {
imports: [ReactiveFormsModule, UiTextareaModule],
},
};
export const standard = () => ({
...componentModule,
template: '<ui-textarea></ui-textarea>',
});

View File

@@ -0,0 +1,101 @@
import {
AfterViewInit,
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
EventEmitter,
Injector,
Input,
OnChanges,
Output,
} from '@angular/core';
import { ControlValueAccessor, NgControl, NG_VALUE_ACCESSOR } from '@angular/forms';
import { uuid } from '@utils/uuid.util';
import { UiTextAreaVariation } from './textarea-variation.enum';
/**
* A textarea input. Implemented with control value accessor
*
* ## Usage
* ``import {UiTextareaModule} from '@ui/textarea/textarea.module';``
*/
@Component({
selector: 'ui-textarea',
templateUrl: './textarea.component.html',
styleUrls: ['./textarea.component.scss'],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: TextareaComponent,
multi: true,
},
],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TextareaComponent implements AfterViewInit, ControlValueAccessor, OnChanges {
@Input() uiId: string = uuid();
@Input() uiName: string;
@Input() uiLabel: string = '';
@Input() uiDescription: string;
@Input() uiVariation: UiTextAreaVariation = UiTextAreaVariation.M;
@Input() uiRequired: boolean;
@Input() uiAnnounceIfOptional: boolean = false;
@Input() uiMaxLength: number;
@Input() uiMinLength: number;
@Input() uiInvalid: boolean;
@Input() uiValidationMessage: string;
@Output() uiOnChange: EventEmitter<string> = new EventEmitter();
name: string | number;
onTouched: () => {};
private onChange: (value: any) => {};
private _value: string = '';
constructor(private injector: Injector, private changeDetectorRef: ChangeDetectorRef) {}
get currentValue(): string {
return this._value;
}
get charactersLeft(): number {
return this.uiMaxLength - this.currentValue.length;
}
ngAfterViewInit(): void {
const ngControl: NgControl = this.injector.get(NgControl, null);
if (ngControl) {
this.name = ngControl.name;
}
}
ngOnChanges(): void {
const ngControl: NgControl = this.injector.get(NgControl, null);
if (ngControl) {
this.name = ngControl.name;
}
}
checkForChange(value: string): void {
if (this._value !== value) {
if (this.onChange) {
this.onChange(value);
}
this._value = value;
this.uiOnChange.emit(value);
}
}
writeValue(value: string): void {
this._value = value;
this.changeDetectorRef.detectChanges();
}
registerOnChange(fn: (value: string) => {}) {
this.onChange = fn;
}
registerOnTouched(fn: () => {}) {
this.onTouched = fn;
}
}

View File

@@ -0,0 +1,11 @@
import { CommonModule } from '@angular/common';
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import { TextareaComponent } from './textarea.component';
@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
imports: [CommonModule],
declarations: [TextareaComponent],
exports: [TextareaComponent],
})
export class UiTextareaModule {}