Skip to content

Commit 87b5270

Browse files
authored
Merge pull request #834 from dxc-technology/fix-833
[Major] Error behaviour when empty string in textarea
2 parents 3883975 + 71d6768 commit 87b5270

File tree

5 files changed

+68
-39
lines changed

5 files changed

+68
-39
lines changed

projects/dxc-ngx-cdk-site/src/app/components/examples/textarea/textarea-properties/textarea-properties.component.html

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
<td>defaultValue: string</td>
2323
<td></td>
2424
<td>
25-
Default value given to the textarea when is uncontrolled and also maintains the uncontrolled behaviour.
25+
Default value given to the textarea when is uncontrolled and also
26+
maintains the uncontrolled behaviour.
2627
</td>
2728
</tr>
2829
<tr>
@@ -59,8 +60,9 @@
5960
</td>
6061
<td>
6162
If true, the input will be optional, showing <code>(Optional)</code>
62-
next to the label. Otherwise, the field will be considered required and an error
63-
will be passed as a parameter to the OnBlur and onChange functions when it has not been filled.
63+
next to the label. Otherwise, the field will be considered required and an
64+
error will be passed as a parameter to the OnBlur and onChange functions
65+
when it has not been filled.
6466
</td>
6567
</tr>
6668
<tr>
@@ -94,9 +96,12 @@
9496
<td>error: string</td>
9597
<td></td>
9698
<td>
97-
If it is defined, the component will change its appearance, showing the
98-
error below the textarea component. If it is not defined, the error
99-
messages will be created and managed internally.
99+
If it is a defined value and also a truthy string, the component will
100+
change its appearance, showing the error below the textarea. If the
101+
defined value is an empty string, it will reserve a space below the
102+
component for a future error, but it would not change its look. In case of
103+
being undefined or null, both the appearance and the space for the error
104+
message would not be modified.
100105
</td>
101106
</tr>
102107
<tr>
@@ -198,4 +203,4 @@
198203
...
199204
</td>
200205
</tr>
201-
</dxc-table>
206+
</dxc-table>

projects/dxc-ngx-cdk-site/src/app/pages/theme-builder/previews/textarea-preview/textarea-preview.component.html

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,24 @@
77
[pattern]="pattern"
88
(onBlur)="onBlur($event)"
99
tabIndexValue="3"
10+
margin="xsmall"
1011
>
1112
</dxc-textarea>
1213
<dxc-textarea
1314
label="default value"
1415
[pattern]="pattern"
1516
defaultValue="Default"
17+
margin="xsmall"
1618
>
1719
</dxc-textarea>
1820
</tbuilder-component-mode>
1921
<tbuilder-component-mode text="Invalid">
20-
<dxc-textarea label="Test" error="error"> </dxc-textarea>
22+
<dxc-textarea label="Test" error="error" margin="xsmall"> </dxc-textarea>
23+
<dxc-textarea label="Test" error="" margin="xsmall"> </dxc-textarea>
2124
</tbuilder-component-mode>
2225
<tbuilder-component-mode text="Disabled">
23-
<dxc-textarea label="Test" value="test" disabled="true"> </dxc-textarea>
26+
<dxc-textarea label="Test" value="test" disabled="true" margin="xsmall">
27+
</dxc-textarea>
2428
</tbuilder-component-mode>
2529
</background-provider>
2630

projects/dxc-ngx-cdk/src/lib/dxc-textarea/dxc-textarea.component.html

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,8 @@
1919
(focus)="handleOnFocus()"
2020
[attr.autocomplete]="autocomplete"
2121
></textarea>
22-
<span *ngIf="error && !disabled" class="textareaErrorMessage">{{ error }}</span>
22+
<span
23+
*ngIf="(error || error === '') && !disabled"
24+
class="textareaErrorMessage"
25+
>{{ error }}</span
26+
>

projects/dxc-ngx-cdk/src/lib/dxc-textarea/dxc-textarea.component.spec.ts

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,15 @@ describe("DxcTextareaComponent", () => {
131131
expect(textarea).toHaveFocus();
132132
fireEvent.click(textarea);
133133
fireEvent.input(textarea, { target: { value: "pattern4&" } });
134-
expect(onChange).toHaveBeenCalledWith({ error: null, value: "pattern4&" });
134+
expect(onChange).toHaveBeenCalledWith({
135+
error: undefined,
136+
value: "pattern4&",
137+
});
135138
fireEvent.blur(textarea);
136-
expect(onBlur).toHaveBeenCalledWith({ error: null, value: "pattern4&" });
139+
expect(onBlur).toHaveBeenCalledWith({
140+
error: undefined,
141+
value: "pattern4&",
142+
});
137143
expect(screen.getByDisplayValue("pattern4&"));
138144
});
139145
test("Strict mode - Length constraint", async () => {
@@ -176,7 +182,10 @@ describe("DxcTextareaComponent", () => {
176182
fireEvent.input(textarea, { target: { value: "test 2" } });
177183
fireEvent.blur(textarea);
178184
await waitFor(() => {
179-
expect(onBlur).toHaveBeenCalledWith({ error: null, value: "test 2" });
185+
expect(onBlur).toHaveBeenCalledWith({
186+
error: undefined,
187+
value: "test 2",
188+
});
180189
});
181190
});
182191
test("Strict mode - Pattern and length constraints", async () => {
@@ -227,7 +236,7 @@ describe("DxcTextareaComponent", () => {
227236
fireEvent.click(textarea);
228237
fireEvent.input(textarea, { target: { value: "test 4" } });
229238
fireEvent.blur(textarea);
230-
expect(onBlur).toHaveBeenCalledWith({ error: null, value: "test 4" });
239+
expect(onBlur).toHaveBeenCalledWith({ error: undefined, value: "test 4" });
231240
});
232241
test("Non Strict mode - Pattern constraint", async () => {
233242
const onChange = jest.fn((value) => {
@@ -351,7 +360,10 @@ describe("DxcTextareaComponent", () => {
351360
fireEvent.input(textarea, { target: { value: "Blur test" } });
352361
fireEvent.blur(textarea);
353362
expect(onBlur).toHaveBeenCalled();
354-
expect(onBlur).toHaveBeenCalledWith({ value: "Blur test", error: null });
363+
expect(onBlur).toHaveBeenCalledWith({
364+
value: "Blur test",
365+
error: undefined,
366+
});
355367
});
356368
test("Controlled textarea", async () => {
357369
const onChange = jest.fn();
@@ -382,13 +394,13 @@ describe("DxcTextareaComponent", () => {
382394
expect(screen.getByDisplayValue("test"));
383395
expect(onChange).toHaveBeenCalledWith({
384396
value: "Controlled test",
385-
error: null,
397+
error: undefined,
386398
});
387399
});
388400
fireEvent.blur(textarea);
389401
await waitFor(() => {
390402
expect(onBlur).toHaveBeenCalled();
391-
expect(onBlur).toHaveBeenCalledWith({ value: "test", error: null });
403+
expect(onBlur).toHaveBeenCalledWith({ value: "test", error: undefined });
392404
});
393405
});
394406
test("Uncontrolled input", async () => {
@@ -415,7 +427,7 @@ describe("DxcTextareaComponent", () => {
415427
expect(onChange).toHaveBeenCalled();
416428
expect(onChange).toHaveBeenCalledWith({
417429
value: "Uncontrolled test",
418-
error: null,
430+
error: undefined,
419431
});
420432
expect(textarea.value).toBe("Uncontrolled test");
421433
});

projects/dxc-ngx-cdk/src/lib/dxc-textarea/dxc-textarea.component.ts

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export class DxcTextareaComponent implements OnInit {
6868
}
6969
private _disabled = false;
7070
/**
71-
* If true, the textarea will be optional, showing (Optional) next to the label.
71+
* If true, the textarea will be optional, showing (Optional) next to the label.
7272
* Otherwise, the field will be considered required and an error will be passed as a parameter to the OnBlur and onChange functions when it has not been filled.
7373
*/
7474
@Input()
@@ -99,8 +99,12 @@ export class DxcTextareaComponent implements OnInit {
9999
@Input()
100100
verticalGrow: "auto" | "manual" | "none" = "auto";
101101
/**
102-
* If it is defined, the component will change its appearance, showing the error below the textarea component.
103-
* If it is not defined, the error messages will be created and managed internally.
102+
* If it is a defined value and also a truthy string, the component will
103+
* change its appearance, showing the error below the textarea. If the defined
104+
* value is an empty string, it will reserve a space below the component for a
105+
* future error, but it would not change its look. In case of being undefined
106+
* or null, both the appearance and the space for the error message would not
107+
* be modified.
104108
*/
105109
@Input()
106110
error = undefined;
@@ -110,34 +114,34 @@ export class DxcTextareaComponent implements OnInit {
110114
@Input()
111115
placeholder = "";
112116
/**
113-
* Regular expression that defines the valid format allowed by the textarea.
114-
* This will be checked when the textarea loses the focus.
115-
* If the value entered does not match the pattern, the onBlur function will be called with the value
116-
* entered and the error informing that the value does not match the pattern as parameters. If the pattern is accomplished,
117+
* Regular expression that defines the valid format allowed by the textarea.
118+
* This will be checked when the textarea loses the focus.
119+
* If the value entered does not match the pattern, the onBlur function will be called with the value
120+
* entered and the error informing that the value does not match the pattern as parameters. If the pattern is accomplished,
117121
* the error parameter will be null.
118122
*/
119123
@Input()
120124
pattern = "";
121125
/**
122-
* Specifies the minimun length allowed by the textarea.
123-
* This will be checked both when the input element loses the focus and while typing within it.
124-
* If the string entered does not comply the minimum length, the onBlur and onChange functions will be called
125-
* with the current value and an internal error informing that the value length does not comply the specified range.
126+
* Specifies the minimun length allowed by the textarea.
127+
* This will be checked both when the input element loses the focus and while typing within it.
128+
* If the string entered does not comply the minimum length, the onBlur and onChange functions will be called
129+
* with the current value and an internal error informing that the value length does not comply the specified range.
126130
* If a valid length is reached, the error parameter of both events will be null.
127131
*/
128132
@Input()
129133
minLength: number;
130134
/**
131-
* Specifies the maximum length allowed by the textarea.
132-
* This will be checked both when the input element loses the focus and while typing within it.
133-
* If the string entered does not comply the maximum length, the onBlur and onChange functions will be called
134-
* with the current value and an internal error informing that the value length does not comply the specified range.
135+
* Specifies the maximum length allowed by the textarea.
136+
* This will be checked both when the input element loses the focus and while typing within it.
137+
* If the string entered does not comply the maximum length, the onBlur and onChange functions will be called
138+
* with the current value and an internal error informing that the value length does not comply the specified range.
135139
* If a valid length is reached, the error parameter of both events will be null.
136140
*/
137141
@Input()
138142
maxLength: number;
139143
/**
140-
* Size of the margin to be applied to the component ('xxsmall' | 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge' | 'xxlarge').
144+
* Size of the margin to be applied to the component ('xxsmall' | 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge' | 'xxlarge').
141145
* You can pass an object with 'top', 'bottom', 'left' and 'right' properties in order to specify different margin sizes.
142146
*/
143147
@Input()
@@ -161,7 +165,7 @@ export class DxcTextareaComponent implements OnInit {
161165
private controlled: boolean;
162166
defaultInputs = new BehaviorSubject<TextareaProperties>({
163167
placeholder: "",
164-
error: "",
168+
error: undefined,
165169
optional: false,
166170
disabled: false,
167171
helperText: "",
@@ -175,13 +179,13 @@ export class DxcTextareaComponent implements OnInit {
175179
verticalGrow: "auto",
176180
});
177181
/**
178-
* This event will emit when the user types within the textarea. An object including the new value and the error will be passed to this function.
182+
* This event will emit when the user types within the textarea. An object including the new value and the error will be passed to this function.
179183
* An example of this object is: { value: value, error: error }. If there is no error, error will be null.
180184
*/
181185
@Output()
182186
onChange = new EventEmitter<EmittedValue>();
183187
/**
184-
* This event will emit when the textarea loses the focus. An object including the textarea value and the error will be passed to this function.
188+
* This event will emit when the textarea loses the focus. An object including the textarea value and the error will be passed to this function.
185189
* An example of this object is: { value: value, error: error }. If there is no error, error will be null.
186190
*/
187191
@Output()
@@ -275,7 +279,7 @@ export class DxcTextareaComponent implements OnInit {
275279
return `Min length ${this.minLength}, Max length ${this.maxLength}`;
276280
if (value && !this.patternMatch(this.pattern, value))
277281
return `Please use a valid pattern`;
278-
return null;
282+
return undefined;
279283
}
280284
private handleValidationError() {
281285
const validationError = this.validateValue(this.value);
@@ -315,4 +319,4 @@ export class DxcTextareaComponent implements OnInit {
315319
}
316320
}
317321
}
318-
}
322+
}

0 commit comments

Comments
 (0)