@@ -8,6 +8,7 @@ import { Directionality } from '@angular/cdk/bidi';
88import { NgTemplateOutlet } from '@angular/common' ;
99import {
1010 afterNextRender ,
11+ booleanAttribute ,
1112 ChangeDetectionStrategy ,
1213 Component ,
1314 computed ,
@@ -17,6 +18,7 @@ import {
1718 forwardRef ,
1819 inject ,
1920 input ,
21+ output ,
2022 signal ,
2123 ViewEncapsulation
2224} from '@angular/core' ;
@@ -82,6 +84,20 @@ import { NZ_INPUT_WRAPPER } from './tokens';
8284 <ng-template [ngTemplateOutlet]="input" />
8385 @if (hasSuffix()) {
8486 <span class="ant-input-suffix">
87+ @if (nzAllowClear()) {
88+ <span
89+ class="ant-input-clear-icon"
90+ [class.ant-input-clear-icon-has-suffix]="nzSuffix() || suffix() || hasFeedback()"
91+ [class.ant-input-clear-icon-hidden]="!inputDir().value() || disabled() || readOnly()"
92+ role="button"
93+ tabindex="-1"
94+ (click)="clear()"
95+ >
96+ <ng-content select="[nzInputClearIcon]">
97+ <nz-icon nzType="close-circle" nzTheme="fill" />
98+ </ng-content>
99+ </span>
100+ }
85101 <ng-content select="[nzInputSuffix]">{{ nzSuffix() }}</ng-content>
86102 @if (hasFeedback() && status()) {
87103 <nz-form-item-feedback-icon [status]="status()" />
@@ -103,25 +119,29 @@ import { NZ_INPUT_WRAPPER } from './tokens';
103119 hostDirectives : [ NzSpaceCompactItemDirective ] ,
104120 host : {
105121 '[class]' : 'class()' ,
106- '[class.ant-input-disabled]' : 'disabled()'
122+ '[class.ant-input-disabled]' : 'disabled()' ,
123+ '[class.ant-input-affix-wrapper-textarea-with-clear-btn]' : 'nzAllowClear() && isTextarea()'
107124 }
108125} )
109126export class NzInputWrapperComponent {
110127 private readonly focusMonitor = inject ( FocusMonitor ) ;
111128
112- private readonly inputDir = contentChild . required ( NzInputDirective ) ;
113- private readonly inputRef = contentChild . required ( NzInputDirective , { read : ElementRef } ) ;
129+ protected readonly inputRef = contentChild . required ( NzInputDirective , { read : ElementRef } ) ;
130+ protected readonly inputDir = contentChild . required ( NzInputDirective ) ;
114131
115132 protected readonly prefix = contentChild ( NzInputPrefixDirective ) ;
116133 protected readonly suffix = contentChild ( NzInputSuffixDirective ) ;
117134 protected readonly addonBefore = contentChild ( NzInputAddonBeforeDirective ) ;
118135 protected readonly addonAfter = contentChild ( NzInputAddonAfterDirective ) ;
119136
137+ readonly nzAllowClear = input ( false , { transform : booleanAttribute } ) ;
120138 readonly nzPrefix = input < string > ( ) ;
121139 readonly nzSuffix = input < string > ( ) ;
122140 readonly nzAddonBefore = input < string > ( ) ;
123141 readonly nzAddonAfter = input < string > ( ) ;
124142
143+ readonly nzClear = output < void > ( ) ;
144+
125145 readonly size = computed ( ( ) => this . inputDir ( ) . nzSize ( ) ) ;
126146 readonly variant = computed ( ( ) => this . inputDir ( ) . nzVariant ( ) ) ;
127147 readonly disabled = computed ( ( ) => this . inputDir ( ) . finalDisabled ( ) ) ;
@@ -130,7 +150,9 @@ export class NzInputWrapperComponent {
130150 readonly hasFeedback = computed ( ( ) => this . inputDir ( ) . hasFeedback ( ) ) ;
131151
132152 protected readonly hasPrefix = computed ( ( ) => ! ! this . nzPrefix ( ) || ! ! this . prefix ( ) ) ;
133- protected readonly hasSuffix = computed ( ( ) => ! ! this . nzSuffix ( ) || ! ! this . suffix ( ) || this . hasFeedback ( ) ) ;
153+ protected readonly hasSuffix = computed (
154+ ( ) => ! ! this . nzSuffix ( ) || ! ! this . suffix ( ) || this . nzAllowClear ( ) || this . hasFeedback ( )
155+ ) ;
134156 protected readonly hasAffix = computed ( ( ) => this . hasPrefix ( ) || this . hasSuffix ( ) ) ;
135157 protected readonly hasAddonBefore = computed ( ( ) => ! ! this . nzAddonBefore ( ) || ! ! this . addonBefore ( ) ) ;
136158 protected readonly hasAddonAfter = computed ( ( ) => ! ! this . nzAddonAfter ( ) || ! ! this . addonAfter ( ) ) ;
@@ -139,6 +161,7 @@ export class NzInputWrapperComponent {
139161 private readonly compactSize = inject ( NZ_SPACE_COMPACT_SIZE , { optional : true } ) ;
140162 protected readonly dir = inject ( Directionality ) . valueSignal ;
141163 protected readonly focused = signal ( false ) ;
164+ protected readonly isTextarea = computed ( ( ) => this . inputRef ( ) . nativeElement instanceof HTMLTextAreaElement ) ;
142165
143166 protected readonly finalSize = computed ( ( ) => {
144167 if ( this . compactSize ) {
@@ -197,4 +220,9 @@ export class NzInputWrapperComponent {
197220 } ) ;
198221 } ) ;
199222 }
223+
224+ clear ( ) : void {
225+ this . inputDir ( ) . ngControl ?. control ?. setValue ( '' ) ;
226+ this . nzClear . emit ( ) ;
227+ }
200228}
0 commit comments