Skip to content

Commit 763f69e

Browse files
feat(module:input): add affix and addon inputs to nz-input-wrapper (#9450)
1 parent b334da4 commit 763f69e

File tree

6 files changed

+127
-71
lines changed

6 files changed

+127
-71
lines changed

components/input/demo/addon.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,8 @@ import { NzSelectModule } from 'ng-zorro-antd/select';
1010
selector: 'nz-demo-input-addon',
1111
imports: [NzInputModule, NzIconModule, NzSelectModule, NzCascaderModule, FormsModule],
1212
template: `
13-
<nz-input-wrapper>
14-
<span nzInputAddonBefore>http://</span>
13+
<nz-input-wrapper nzAddonBefore="http://" nzAddonAfter=".com">
1514
<input nz-input [(ngModel)]="value" />
16-
<span nzInputAddonAfter>.com</span>
1715
</nz-input-wrapper>
1816
<br />
1917
<br />
@@ -38,10 +36,8 @@ import { NzSelectModule } from 'ng-zorro-antd/select';
3836
</nz-input-wrapper>
3937
<br />
4038
<br />
41-
<nz-input-wrapper>
42-
<span nzInputAddonBefore>http://</span>
39+
<nz-input-wrapper nzAddonBefore="http://" nzSuffix=".com">
4340
<input nz-input [(ngModel)]="value" />
44-
<span nzInputSuffix>.com</span>
4541
</nz-input-wrapper>
4642
<br />
4743
<br />

components/input/demo/presuffix.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,17 @@ import { NzSelectModule } from 'ng-zorro-antd/select';
1313
<nz-input-wrapper>
1414
<nz-icon nzInputPrefix nzType="user" />
1515
<input nz-input placeholder="Enter your username" />
16-
<nz-icon nzInputSuffix nzType="info" />
16+
<nz-icon nzInputSuffix nzType="info-circle" />
1717
</nz-input-wrapper>
1818
<br />
1919
<br />
20-
<nz-input-wrapper>
21-
<span nzInputPrefix>¥</span>
20+
<nz-input-wrapper nzPrefix="¥" nzSuffix="RMB">
2221
<input nz-input />
23-
<span nzInputSuffix>RMB</span>
2422
</nz-input-wrapper>
2523
<br />
2624
<br />
27-
<nz-input-wrapper>
28-
<span nzInputPrefix>¥</span>
25+
<nz-input-wrapper nzPrefix="¥" nzSuffix="RMB">
2926
<input nz-input disabled />
30-
<span nzInputSuffix>RMB</span>
3127
</nz-input-wrapper>
3228
<br />
3329
<br />

components/input/doc/index.en-US.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ All props of input supported by [w3c standards](https://www.w3schools.com/tags/t
3030

3131
Used when you need to add prefixes and suffixes or pre- and post-tabs to `[nz-input]`.
3232

33+
| Property | Description | Type | Default |
34+
| ----------------- | --------------------------------------------------------------------- | -------- | ------- |
35+
| `[nzAddonBefore]` | The label text displayed before (on the left side of) the input field | `string` | - |
36+
| `[nzAddonAfter]` | The label text displayed after (on the right side of) the input field | `string` | - |
37+
| `[nzPrefix]` | The prefix icon for the Input | `string` | - |
38+
| `[nzSuffix]` | The suffix icon for the Input | `string` | - |
39+
3340
### nz-input-group
3441

3542
> ⚠️ `nz-input-group` has been deprecated in `v20.0.0` and will be removed in `v22.0.0`. Please use the `nz-input-wrapper` component instead.

components/input/doc/index.zh-CN.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ description: 通过鼠标或键盘输入内容,是最基础的表单域的包
3030

3131
当需要为 `[nz-input]` 添加前/后缀或前/后置标签时使用。
3232

33+
| 参数 | 说明 | 类型 | 默认值 |
34+
| ----------------- | ---------------------------- | -------- | ------ |
35+
| `[nzAddonBefore]` | 带标签的 input,设置前置标签 | `string` | - |
36+
| `[nzAddonAfter]` | 带标签的 input,设置后置标签 | `string` | - |
37+
| `[nzPrefix]` | 带有前缀图标的 input | `string` | - |
38+
| `[nzSuffix]` | 带有后缀图标的 input | `string` | - |
39+
3340
### nz-input-group
3441

3542
> ⚠️ `nz-input-group` 已在 `v20.0.0` 中废弃,将在 `v22.0.0` 中移除,请使用 `nz-input-wrapper` 组件。

components/input/input-wrapper.component.spec.ts

Lines changed: 87 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
import { Component, ElementRef, viewChild } from '@angular/core';
77
import { ComponentFixture, TestBed } from '@angular/core/testing';
88

9-
import { NzVariant } from 'ng-zorro-antd/core/types';
9+
import { NzSizeLDSType, NzVariant } from 'ng-zorro-antd/core/types';
1010

1111
import { NzInputModule } from './input.module';
1212

13-
describe('input-wrapper with affixes or addons', () => {
13+
describe('input-wrapper', () => {
1414
let component: InputWithAffixesAndAddonsTestComponent;
1515
let fixture: ComponentFixture<InputWithAffixesAndAddonsTestComponent>;
1616

@@ -21,129 +21,168 @@ describe('input-wrapper with affixes or addons', () => {
2121
});
2222

2323
it('should be apply affix classes', () => {
24-
expect(component.withAffixes().nativeElement.classList).toContain('ant-input-affix-wrapper');
24+
expect(component.withPropAffixes().nativeElement.classList).toContain('ant-input-affix-wrapper');
25+
expect(component.withContentAffixes().nativeElement.classList).toContain('ant-input-affix-wrapper');
2526
});
2627

2728
it('should be apply addon classes', () => {
28-
expect(component.withAddons().nativeElement.classList).toContain('ant-input-group-wrapper');
29+
expect(component.withPropAddons().nativeElement.classList).toContain('ant-input-group-wrapper');
30+
expect(component.withContentAddons().nativeElement.classList).toContain('ant-input-group-wrapper');
2931
});
3032

3133
it('should be apply mix classes', () => {
32-
expect(component.withMix().nativeElement.classList).toContain('ant-input-group-wrapper');
33-
expect(component.withMix().nativeElement.querySelector('.ant-input-affix-wrapper')).toBeTruthy();
34+
expect(component.withPropMix().nativeElement.classList).toContain('ant-input-group-wrapper');
35+
expect(component.withPropMix().nativeElement.classList).toContain('ant-input-group-wrapper');
36+
expect(component.withContentMix().nativeElement.classList).toContain('ant-input-group-wrapper');
37+
expect(component.withContentMix().nativeElement.querySelector('.ant-input-affix-wrapper')).toBeTruthy();
3438
});
3539

3640
it('should be not apply affix or addon classes when only input is present', () => {
3741
expect(component.onlyInput().nativeElement.classList).not.toContain('ant-input-group-wrapper');
3842
expect(component.onlyInput().nativeElement.classList).not.toContain('ant-input-affix-wrapper');
3943
});
4044

45+
it('should be apply size class', () => {
46+
component.size = 'large';
47+
fixture.detectChanges();
48+
expect(component.withPropAffixes().nativeElement.classList).toContain('ant-input-affix-wrapper-lg');
49+
expect(component.withPropAddons().nativeElement.classList).toContain('ant-input-group-wrapper-lg');
50+
component.size = 'small';
51+
fixture.detectChanges();
52+
expect(component.withPropAffixes().nativeElement.classList).toContain('ant-input-affix-wrapper-sm');
53+
expect(component.withPropAddons().nativeElement.classList).toContain('ant-input-group-wrapper-sm');
54+
});
55+
4156
it('should be apply disabled class', () => {
4257
component.disabled = true;
4358
fixture.detectChanges();
44-
expect(component.withAffixes().nativeElement.classList).toContain('ant-input-affix-wrapper-disabled');
59+
expect(component.withContentAffixes().nativeElement.classList).toContain('ant-input-affix-wrapper-disabled');
4560
});
4661

4762
it('should be apply readonly class', () => {
4863
component.readonly = true;
4964
fixture.detectChanges();
50-
expect(component.withAffixes().nativeElement.classList).toContain('ant-input-affix-wrapper-readonly');
65+
expect(component.withContentAffixes().nativeElement.classList).toContain('ant-input-affix-wrapper-readonly');
5166
});
5267

5368
describe('should be apply variant class', () => {
5469
it('filled', () => {
5570
fixture.detectChanges();
56-
expect(component.withAffixes().nativeElement.classList).not.toContain('ant-input-affix-wrapper-filled');
57-
expect(component.withAddons().nativeElement.classList).not.toContain('ant-input-group-wrapper-filled');
58-
expect(component.withMix().nativeElement.classList).not.toContain('ant-input-group-wrapper-filled');
59-
expect(component.withMix().nativeElement.querySelector('.ant-input-affix-wrapper-filled')).toBeFalsy();
71+
expect(component.withContentAffixes().nativeElement.classList).not.toContain('ant-input-affix-wrapper-filled');
72+
expect(component.withContentAddons().nativeElement.classList).not.toContain('ant-input-group-wrapper-filled');
73+
expect(component.withContentMix().nativeElement.classList).not.toContain('ant-input-group-wrapper-filled');
74+
expect(component.withContentMix().nativeElement.querySelector('.ant-input-affix-wrapper-filled')).toBeFalsy();
6075
component.variant = 'filled';
6176
fixture.detectChanges();
62-
expect(component.withAffixes().nativeElement.classList).toContain('ant-input-affix-wrapper-filled');
63-
expect(component.withAddons().nativeElement.classList).toContain('ant-input-group-wrapper-filled');
64-
expect(component.withMix().nativeElement.classList).toContain('ant-input-group-wrapper-filled');
65-
expect(component.withMix().nativeElement.querySelector('.ant-input-affix-wrapper-filled')).toBeTruthy();
77+
expect(component.withContentAffixes().nativeElement.classList).toContain('ant-input-affix-wrapper-filled');
78+
expect(component.withContentAddons().nativeElement.classList).toContain('ant-input-group-wrapper-filled');
79+
expect(component.withContentMix().nativeElement.classList).toContain('ant-input-group-wrapper-filled');
80+
expect(component.withContentMix().nativeElement.querySelector('.ant-input-affix-wrapper-filled')).toBeTruthy();
6681
});
6782

6883
it('borderless', () => {
6984
fixture.detectChanges();
70-
expect(component.withAffixes().nativeElement.classList).not.toContain('ant-input-affix-wrapper-borderless');
71-
expect(component.withAddons().nativeElement.classList).not.toContain('ant-input-group-wrapper-borderless');
72-
expect(component.withMix().nativeElement.classList).not.toContain('ant-input-group-wrapper-borderless');
73-
expect(component.withMix().nativeElement.querySelector('.ant-input-affix-wrapper-borderless')).toBeFalsy();
85+
expect(component.withContentAffixes().nativeElement.classList).not.toContain(
86+
'ant-input-affix-wrapper-borderless'
87+
);
88+
expect(component.withContentAddons().nativeElement.classList).not.toContain('ant-input-group-wrapper-borderless');
89+
expect(component.withContentMix().nativeElement.classList).not.toContain('ant-input-group-wrapper-borderless');
90+
expect(component.withContentMix().nativeElement.querySelector('.ant-input-affix-wrapper-borderless')).toBeFalsy();
7491
component.variant = 'borderless';
7592
fixture.detectChanges();
76-
expect(component.withAffixes().nativeElement.classList).toContain('ant-input-affix-wrapper-borderless');
77-
expect(component.withAddons().nativeElement.classList).toContain('ant-input-group-wrapper-borderless');
78-
expect(component.withMix().nativeElement.classList).toContain('ant-input-group-wrapper-borderless');
79-
expect(component.withMix().nativeElement.querySelector('.ant-input-affix-wrapper-borderless')).toBeTruthy();
93+
expect(component.withContentAffixes().nativeElement.classList).toContain('ant-input-affix-wrapper-borderless');
94+
expect(component.withContentAddons().nativeElement.classList).toContain('ant-input-group-wrapper-borderless');
95+
expect(component.withContentMix().nativeElement.classList).toContain('ant-input-group-wrapper-borderless');
96+
expect(
97+
component.withContentMix().nativeElement.querySelector('.ant-input-affix-wrapper-borderless')
98+
).toBeTruthy();
8099
});
81100

82101
it('underlined', () => {
83102
fixture.detectChanges();
84-
expect(component.withAffixes().nativeElement.classList).not.toContain('ant-input-affix-wrapper-underlined');
85-
expect(component.withAddons().nativeElement.classList).not.toContain('ant-input-group-wrapper-underlined');
86-
expect(component.withMix().nativeElement.classList).not.toContain('ant-input-group-wrapper-underlined');
87-
expect(component.withMix().nativeElement.querySelector('.ant-input-affix-wrapper-underlined')).toBeFalsy();
103+
expect(component.withContentAffixes().nativeElement.classList).not.toContain(
104+
'ant-input-affix-wrapper-underlined'
105+
);
106+
expect(component.withContentAddons().nativeElement.classList).not.toContain('ant-input-group-wrapper-underlined');
107+
expect(component.withContentMix().nativeElement.classList).not.toContain('ant-input-group-wrapper-underlined');
108+
expect(component.withContentMix().nativeElement.querySelector('.ant-input-affix-wrapper-underlined')).toBeFalsy();
88109
component.variant = 'underlined';
89110
fixture.detectChanges();
90-
expect(component.withAffixes().nativeElement.classList).toContain('ant-input-affix-wrapper-underlined');
91-
expect(component.withAddons().nativeElement.classList).toContain('ant-input-group-wrapper-underlined');
92-
expect(component.withMix().nativeElement.classList).toContain('ant-input-group-wrapper-underlined');
93-
expect(component.withMix().nativeElement.querySelector('.ant-input-affix-wrapper-underlined')).toBeTruthy();
111+
expect(component.withContentAffixes().nativeElement.classList).toContain('ant-input-affix-wrapper-underlined');
112+
expect(component.withContentAddons().nativeElement.classList).toContain('ant-input-group-wrapper-underlined');
113+
expect(component.withContentMix().nativeElement.classList).toContain('ant-input-group-wrapper-underlined');
114+
expect(
115+
component.withContentMix().nativeElement.querySelector('.ant-input-affix-wrapper-underlined')
116+
).toBeTruthy();
94117
});
95118
});
96119

97120
it('should be handle focus / blur', () => {
98-
let inputElement = component.withAffixes().nativeElement.querySelector('input')!;
121+
let inputElement = component.withContentAffixes().nativeElement.querySelector('input')!;
99122
inputElement.focus();
100-
expect(component.withAffixes().nativeElement.classList).toContain('ant-input-affix-wrapper-focused');
123+
expect(component.withContentAffixes().nativeElement.classList).toContain('ant-input-affix-wrapper-focused');
101124
inputElement.blur();
102-
expect(component.withAffixes().nativeElement.classList).not.toContain('ant-input-affix-wrapper-focused');
125+
expect(component.withContentAffixes().nativeElement.classList).not.toContain('ant-input-affix-wrapper-focused');
103126

104-
inputElement = component.withMix().nativeElement.querySelector('input')!;
127+
inputElement = component.withContentMix().nativeElement.querySelector('input')!;
105128
inputElement.focus();
106-
expect(component.withMix().nativeElement.querySelector('.ant-input-affix-wrapper-focused')).toBeTruthy();
129+
expect(component.withContentMix().nativeElement.querySelector('.ant-input-affix-wrapper-focused')).toBeTruthy();
107130
inputElement.blur();
108-
expect(component.withMix().nativeElement.querySelector('.ant-input-affix-wrapper-focused')).toBeFalsy();
131+
expect(component.withContentMix().nativeElement.querySelector('.ant-input-affix-wrapper-focused')).toBeFalsy();
109132
});
110133
});
111134

112135
@Component({
113136
imports: [NzInputModule],
114137
template: `
115-
<nz-input-wrapper #withAffixes>
138+
<nz-input-wrapper #withPropAffixes nzPrefix="Prefix" nzSuffix="Suffix">
139+
<input nz-input [nzSize]="size" [nzVariant]="variant" [disabled]="disabled" [readonly]="readonly" />
140+
</nz-input-wrapper>
141+
142+
<nz-input-wrapper #withContentAffixes>
116143
<span nzInputPrefix>Prefix</span>
117-
<input nz-input [nzVariant]="variant" [disabled]="disabled" [readonly]="readonly" />
144+
<input nz-input [nzSize]="size" [nzVariant]="variant" [disabled]="disabled" [readonly]="readonly" />
118145
<span nzInputSuffix>Suffix</span>
119146
</nz-input-wrapper>
120147
121-
<nz-input-wrapper #withAddons>
148+
<nz-input-wrapper #withPropAddons nzAddonBefore="Before" nzAddonAfter="After">
149+
<input nz-input [nzSize]="size" [nzVariant]="variant" [disabled]="disabled" [readonly]="readonly" />
150+
</nz-input-wrapper>
151+
152+
<nz-input-wrapper #withContentAddons>
122153
<span nzInputAddonBefore>Before</span>
123-
<input nz-input [nzVariant]="variant" [disabled]="disabled" [readonly]="readonly" />
154+
<input nz-input [nzSize]="size" [nzVariant]="variant" [disabled]="disabled" [readonly]="readonly" />
124155
<span nzInputAddonAfter>After</span>
125156
</nz-input-wrapper>
126157
127-
<nz-input-wrapper #withMix>
158+
<nz-input-wrapper #withPropMix nzAddonBefore="Before" nzAddonAfter="After" nzPrefix="Prefix" nzSuffix="Suffix">
159+
<input nz-input [nzSize]="size" [nzVariant]="variant" [disabled]="disabled" [readonly]="readonly" />
160+
</nz-input-wrapper>
161+
162+
<nz-input-wrapper #withContentMix>
128163
<span nzInputAddonBefore>Before</span>
129164
<span nzInputPrefix>Prefix</span>
130-
<input nz-input [nzVariant]="variant" [disabled]="disabled" [readonly]="readonly" />
165+
<input nz-input [nzSize]="size" [nzVariant]="variant" [disabled]="disabled" [readonly]="readonly" />
131166
<span nzInputSuffix>Suffix</span>
132167
<span nzInputAddonAfter>After</span>
133168
</nz-input-wrapper>
134169
135170
<nz-input-wrapper #onlyInput>
136-
<input nz-input [nzVariant]="variant" [disabled]="disabled" [readonly]="readonly" />
171+
<input nz-input [nzSize]="size" [nzVariant]="variant" [disabled]="disabled" [readonly]="readonly" />
137172
</nz-input-wrapper>
138173
`
139174
})
140175
class InputWithAffixesAndAddonsTestComponent {
176+
size: NzSizeLDSType = 'default';
141177
disabled = false;
142178
readonly = false;
143179
variant: NzVariant = 'outlined';
144180

145-
readonly withAffixes = viewChild.required('withAffixes', { read: ElementRef });
146-
readonly withAddons = viewChild.required('withAddons', { read: ElementRef });
147-
readonly withMix = viewChild.required('withMix', { read: ElementRef });
181+
readonly withPropAffixes = viewChild.required('withPropAffixes', { read: ElementRef });
182+
readonly withContentAffixes = viewChild.required('withContentAffixes', { read: ElementRef });
183+
readonly withPropAddons = viewChild.required('withPropAddons', { read: ElementRef });
184+
readonly withContentAddons = viewChild.required('withContentAddons', { read: ElementRef });
185+
readonly withPropMix = viewChild.required('withPropMix', { read: ElementRef });
186+
readonly withContentMix = viewChild.required('withContentMix', { read: ElementRef });
148187
readonly onlyInput = viewChild.required('onlyInput', { read: ElementRef });
149188
}

0 commit comments

Comments
 (0)