Skip to content

Commit 9b013f9

Browse files
fix(components/forms): allow character count indicator and limit to be set in either order (#826)
1 parent 095509a commit 9b013f9

File tree

4 files changed

+66
-11
lines changed

4 files changed

+66
-11
lines changed

libs/components/forms/src/lib/modules/character-counter/character-counter.component.spec.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ describe('Character Counter component', () => {
3535
let nativeElement: HTMLElement;
3636
let characterCountComponent: SkyCharacterCounterIndicatorComponent;
3737
let characterCountLabel: HTMLLabelElement;
38+
let characterCountLabelLastName: HTMLLabelElement;
3839

3940
beforeEach(() => {
4041
fixture = TestBed.createComponent(CharacterCountTestComponent);
@@ -43,10 +44,13 @@ describe('Character Counter component', () => {
4344

4445
fixture.detectChanges();
4546

46-
characterCountComponent =
47-
component.inputDirective!.skyCharacterCounterIndicator!;
47+
characterCountComponent = component.inputDirective
48+
?.skyCharacterCounterIndicator as SkyCharacterCounterIndicatorComponent;
4849
characterCountLabel = nativeElement.querySelector(
49-
'.sky-character-count-label'
50+
'.input-count-example-wrapper .sky-character-count-label'
51+
) as HTMLLabelElement;
52+
characterCountLabelLastName = nativeElement.querySelector(
53+
'.input-count-example-wrapper-last-name .sky-character-count-label'
5054
) as HTMLLabelElement;
5155
});
5256

@@ -146,6 +150,11 @@ describe('Character Counter component', () => {
146150
expect(characterCountComponent.characterCountLimit).toEqual(0);
147151
}));
148152

153+
it('should allow character limit and indicator to be set in any order', () => {
154+
expect(characterCountComponent.characterCount).toBe(4);
155+
expect(characterCountLabelLastName.innerText.trim()).toBe('4/5');
156+
});
157+
149158
it('should pass accessibility', async () => {
150159
fixture.detectChanges();
151160
await fixture.whenStable();

libs/components/forms/src/lib/modules/character-counter/character-counter.directive.ts

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,17 @@ export class SkyCharacterCounterInputDirective implements Validator {
3131
* `textarea` element.
3232
*/
3333
@Input()
34-
public skyCharacterCounterIndicator:
34+
public get skyCharacterCounterIndicator():
3535
| SkyCharacterCounterIndicatorComponent
36-
| undefined;
36+
| undefined {
37+
return this.#_skyCharacterCounterIndicator;
38+
}
39+
public set skyCharacterCounterIndicator(
40+
value: SkyCharacterCounterIndicatorComponent | undefined
41+
) {
42+
this.#_skyCharacterCounterIndicator = value;
43+
this.#updateIndicatorLimit();
44+
}
3745

3846
/**
3947
* Specifies the maximum number of characters allowed in the input field. Place this directive
@@ -43,10 +51,13 @@ export class SkyCharacterCounterInputDirective implements Validator {
4351
@Input()
4452
public set skyCharacterCounterLimit(value: number | undefined) {
4553
this.#skyCharacterCounterLimitOrDefault = value ?? 0;
46-
this.#updateIndicatorLimit(this.#skyCharacterCounterLimitOrDefault);
47-
this.#validatorChange();
54+
this.#updateIndicatorLimit();
4855
}
4956

57+
#_skyCharacterCounterIndicator:
58+
| SkyCharacterCounterIndicatorComponent
59+
| undefined;
60+
5061
#skyCharacterCounterLimitOrDefault = 0;
5162

5263
public validate(control: AbstractControl): ValidationErrors | null {
@@ -82,12 +93,15 @@ export class SkyCharacterCounterInputDirective implements Validator {
8293
}
8394
}
8495

85-
#updateIndicatorLimit(limit: number): void {
96+
#updateIndicatorLimit(): void {
8697
if (this.skyCharacterCounterIndicator) {
87-
this.skyCharacterCounterIndicator.characterCountLimit = limit;
98+
this.skyCharacterCounterIndicator.characterCountLimit =
99+
this.#skyCharacterCounterLimitOrDefault;
88100
}
101+
102+
this.#validatorChange();
89103
}
90104

91105
// eslint-disable-next-line @typescript-eslint/no-empty-function
92-
#validatorChange = () => {};
106+
#validatorChange = (): void => {};
93107
}

libs/components/forms/src/lib/modules/character-counter/fixtures/character-count.component.fixture.html

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<div>
22
<form [formGroup]="testForm">
3-
<div style="display: flex">
3+
<div style="display: flex" class="input-count-example-wrapper">
44
<label
55
for="input-count-example"
66
class="sky-control-label"
@@ -26,5 +26,32 @@
2626
<div *ngIf="firstName.errors?.skyCharacterCounter" class="sky-error-label">
2727
Limit First name to {{maxCharacterCount}} characters.
2828
</div>
29+
30+
<div style="display: flex" class="input-count-example-wrapper-last-name">
31+
<label
32+
for="input-count-example-last-name"
33+
class="sky-control-label"
34+
style="flex-grow: 1"
35+
>
36+
Last name
37+
</label>
38+
39+
<sky-character-counter-indicator #indicatorLastName>
40+
</sky-character-counter-indicator>
41+
</div>
42+
43+
<input
44+
aria-label="Input"
45+
class="sky-form-control"
46+
formControlName="lastName"
47+
type="text"
48+
skyCharacterCounter
49+
[skyCharacterCounterLimit]="maxCharacterCountLastName"
50+
[skyCharacterCounterIndicator]="indicatorLastName"
51+
/>
52+
53+
<div *ngIf="lastName.errors?.skyCharacterCounter" class="sky-error-label">
54+
Limit Last name to {{maxCharacterCount}} characters.
55+
</div>
2956
</form>
3057
</div>

libs/components/forms/src/lib/modules/character-counter/fixtures/character-count.component.fixture.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ export class CharacterCountTestComponent {
2121
public testForm: UntypedFormGroup;
2222
public firstName: UntypedFormControl;
2323
public firstNameLabel = 'Field label';
24+
public lastName: UntypedFormControl;
2425
public maxCharacterCount: number | undefined = 5;
26+
public maxCharacterCountLastName: number | undefined = 5;
2527

2628
@ViewChild(SkyCharacterCounterInputDirective)
2729
public inputDirective: SkyCharacterCounterInputDirective | undefined;
@@ -37,14 +39,17 @@ export class CharacterCountTestComponent {
3739
this.#changeDetector = changeDetector;
3840

3941
this.firstName = this.#formBuilder.control('test');
42+
this.lastName = this.#formBuilder.control('last');
4043

4144
this.testForm = this.#formBuilder.group({
4245
firstName: this.firstName,
46+
lastName: this.lastName,
4347
});
4448
}
4549

4650
public setCharacterCountLimit(limit: number | undefined): void {
4751
this.maxCharacterCount = limit;
52+
this.maxCharacterCountLastName = limit;
4853
this.#changeDetector.markForCheck();
4954
}
5055
}

0 commit comments

Comments
 (0)