Skip to content

Commit e8ab1a7

Browse files
jcorrea97alinelariguet
authored andcommitted
feat(disclaimer-group): reutiliza po-tag no componente
Reutiliza `po-tag` no componente `disclaimer-group` com nova definição de acessibilidade fixes DTHFUI-7945
1 parent 36cf24c commit e8ab1a7

File tree

5 files changed

+386
-70
lines changed

5 files changed

+386
-70
lines changed

projects/ui/src/lib/components/po-disclaimer-group/po-disclaimer-group-base.component.spec.ts

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -225,32 +225,6 @@ describe('PoDisclaimerGroupBaseComponent:', () => {
225225
expect(component.removeAll.emit).toHaveBeenCalledWith(validDisclaimers);
226226
});
227227

228-
it('onCloseAction: should remove disclaimer and emit current disclaimers', fakeAsync(() => {
229-
spyOn(component.change, <any>'emit');
230-
231-
const disclaimerToRemove = { value: 'north', label: 'Region', property: 'region', hideClose: false };
232-
const currentDisclaimers = [component.disclaimers[0], component.disclaimers[1]];
233-
234-
component.onCloseAction(disclaimerToRemove);
235-
236-
tick();
237-
238-
expect(component.disclaimers).toEqual(currentDisclaimers);
239-
expect(component.change.emit).toHaveBeenCalledWith(component.disclaimers);
240-
}));
241-
242-
it('onCloseAction: should emit removedDisclaimer and currentDisclaimers in remove action', () => {
243-
spyOn(component.remove, <any>'emit');
244-
245-
const removedDisclaimer = { value: 'north', label: 'Region', property: 'region', hideClose: false };
246-
const currentDisclaimers = [component.disclaimers[0], component.disclaimers[1]];
247-
248-
component.onCloseAction(removedDisclaimer);
249-
250-
expect(component.disclaimers).toEqual(currentDisclaimers);
251-
expect(component.remove.emit).toHaveBeenCalledWith({ currentDisclaimers, removedDisclaimer });
252-
});
253-
254228
it('checkDisclaimers: should return only valid disclaimers.', () => {
255229
const checkedDisclaimers = component['checkDisclaimers']([...validDisclaimers]);
256230

projects/ui/src/lib/components/po-disclaimer-group/po-disclaimer-group-base.component.ts

Lines changed: 12 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { DoCheck, EventEmitter, Input, IterableDiffers, Output, Directive, ChangeDetectorRef } from '@angular/core';
1+
import { ChangeDetectorRef, Directive, DoCheck, EventEmitter, Input, IterableDiffers, Output } from '@angular/core';
22

3-
import { convertToBoolean, isKeyCodeEnter, uuid } from '../../utils/util';
4-
import { PoLanguageService } from '../../services/po-language/po-language.service';
53
import { poLocaleDefault } from '../../services/po-language/po-language.constant';
4+
import { PoLanguageService } from '../../services/po-language/po-language.service';
5+
import { convertToBoolean, isKeyCodeEnter, uuid } from '../../utils/util';
66

77
import { PoDisclaimer } from '../po-disclaimer/po-disclaimer.interface';
88

@@ -140,16 +140,6 @@ export class PoDisclaimerGroupBaseComponent implements DoCheck {
140140
this.checkChanges();
141141
}
142142

143-
onCloseAction(disclaimer) {
144-
this.removeDisclaimer(disclaimer);
145-
146-
this.emitChangeDisclaimers();
147-
this.remove.emit({
148-
removedDisclaimer: { ...disclaimer },
149-
currentDisclaimers: [...this.disclaimers]
150-
});
151-
}
152-
153143
isRemoveAll() {
154144
return !this.hideRemoveAll && this.disclaimers.filter(c => !c.hideClose).length > 1;
155145
}
@@ -175,11 +165,19 @@ export class PoDisclaimerGroupBaseComponent implements DoCheck {
175165
this.removeAll.emit([...removeItems]);
176166
}
177167

178-
private removeDisclaimer(disclaimer: any) {
168+
protected removeDisclaimer(disclaimer: any) {
179169
const itemIndex = this.disclaimers.findIndex(d => d['$id'] === disclaimer['$id']);
180170
this.disclaimers.splice(itemIndex, 1);
181171
}
182172

173+
protected emitChangeDisclaimers() {
174+
setTimeout(() => {
175+
this.change.emit(this.disclaimers);
176+
});
177+
this.previousDisclaimers = [...this._disclaimers];
178+
this.changeDetector?.detectChanges();
179+
}
180+
183181
private checkChanges() {
184182
if (this.differ) {
185183
const changes = this.differ.diff(this.disclaimers);
@@ -224,12 +222,4 @@ export class PoDisclaimerGroupBaseComponent implements DoCheck {
224222
disclaimer.property !== this.previousDisclaimers[index].property
225223
);
226224
}
227-
228-
private emitChangeDisclaimers() {
229-
setTimeout(() => {
230-
this.change.emit(this.disclaimers);
231-
});
232-
this.previousDisclaimers = [...this._disclaimers];
233-
this.changeDetector?.detectChanges();
234-
}
235225
}

projects/ui/src/lib/components/po-disclaimer-group/po-disclaimer-group.component.html

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,12 @@
1010
>
1111
</po-disclaimer-remove>
1212

13-
<po-disclaimer
13+
<po-tag
1414
*ngFor="let disclaimer of disclaimers"
1515
class="po-disclaimer-group-disclaimer-align"
16-
[p-hide-close]="disclaimer.hideClose"
17-
[p-label]="disclaimer.label"
18-
[p-property]="disclaimer.property"
19-
[p-value]="disclaimer.value"
20-
(p-close-action)="onCloseAction(disclaimer)"
16+
[p-value]="disclaimer.label || disclaimer.value"
17+
[p-removable]="!disclaimer.hideClose"
18+
(p-close)="onCloseAction(disclaimer, $event)"
2119
>
22-
</po-disclaimer>
20+
</po-tag>
2321
</div>

projects/ui/src/lib/components/po-disclaimer-group/po-disclaimer-group.component.spec.ts

Lines changed: 233 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
1+
import { ComponentFixture, fakeAsync, flush, TestBed, tick } from '@angular/core/testing';
22
import { NO_ERRORS_SCHEMA } from '@angular/core';
33

44
import { configureTestSuite } from './../../util-test/util-expect.spec';
@@ -51,16 +51,8 @@ describe('PoDisclaimerGroupComponent:', () => {
5151
});
5252
});
5353

54-
it('should be created with 3 disclaimers and default removeAll', () => {
55-
expect(nativeElement.querySelectorAll('po-disclaimer').length).toBe(3);
56-
expect(nativeElement.querySelectorAll('po-tag').length).toBe(1);
57-
});
58-
59-
it('should be created with 3 disclaimers and without removeAll disclaimer', () => {
60-
component.hideRemoveAll = true;
61-
fixture.detectChanges();
62-
expect(nativeElement.querySelectorAll('po-disclaimer').length).toBe(3);
63-
expect(nativeElement.querySelector('.po-disclaimer-danger')).toBeFalsy();
54+
it('should be created with 3 tags plus tag default removeAll', () => {
55+
expect(nativeElement.querySelectorAll('po-tag').length).toBe(4);
6456
});
6557

6658
it('should hide disclaimer-group if there are no disclaimers', () => {
@@ -82,7 +74,7 @@ describe('PoDisclaimerGroupComponent:', () => {
8274
component.onCloseAction(disclaimers[0]);
8375
fixture.detectChanges();
8476

85-
expect(nativeElement.querySelectorAll('po-disclaimer').length).toBe(2);
77+
expect(nativeElement.querySelectorAll('po-tag').length).toBe(2);
8678
});
8779

8880
it('should remove all disclaimers', () => {
@@ -92,13 +84,241 @@ describe('PoDisclaimerGroupComponent:', () => {
9284
expect(nativeElement.querySelectorAll('po-disclaimer').length).toBe(0);
9385
});
9486

87+
it('should call handleKeyboardNavigationTag after changes', fakeAsync(() => {
88+
const changes: any = {
89+
disclaimers: ['test']
90+
};
91+
spyOn(component, 'handleKeyboardNavigationTag');
92+
93+
component.ngOnChanges(changes);
94+
tick();
95+
96+
expect(component.handleKeyboardNavigationTag).toHaveBeenCalled();
97+
}));
98+
99+
it('onCloseAction: should remove disclaimer and emit current disclaimers', fakeAsync(() => {
100+
spyOn(component.change, <any>'emit');
101+
spyOn(component, <any>'focusOnNextTag');
102+
103+
const disclaimerToRemove = { value: 'north', label: 'Region', property: 'region', hideClose: false };
104+
const currentDisclaimers = [component.disclaimers[0], component.disclaimers[1]];
105+
106+
component.onCloseAction(disclaimerToRemove);
107+
108+
tick();
109+
110+
expect(component.disclaimers).toEqual(currentDisclaimers);
111+
expect(component.change.emit).toHaveBeenCalledWith(component.disclaimers);
112+
113+
tick(301);
114+
115+
expect(component.focusOnNextTag).toHaveBeenCalled();
116+
}));
117+
118+
it('onCloseAction: should emit removedDisclaimer and currentDisclaimers in remove action', () => {
119+
spyOn(component.remove, <any>'emit');
120+
121+
const removedDisclaimer = { value: 'north', label: 'Region', property: 'region', hideClose: false };
122+
const currentDisclaimers = [component.disclaimers[0], component.disclaimers[1]];
123+
124+
component.onCloseAction(removedDisclaimer);
125+
126+
expect(component.disclaimers).toEqual(currentDisclaimers);
127+
expect(component.remove.emit).toHaveBeenCalledWith({ currentDisclaimers, removedDisclaimer });
128+
});
129+
130+
it('should handleKeyDown correctly for Space key', () => {
131+
const event = new KeyboardEvent('keydown', { code: 'Space' });
132+
133+
spyOn(event, 'preventDefault');
134+
spyOn(event, 'stopPropagation');
135+
136+
component['handleKeyDown'](event, [], 0);
137+
138+
expect(event.preventDefault).toHaveBeenCalled();
139+
expect(event.stopPropagation).toHaveBeenCalled();
140+
});
141+
142+
it('should handleKeyDown correctly for ArrowLeft key', () => {
143+
const event = new KeyboardEvent('keydown', { key: 'ArrowLeft' });
144+
spyOn(component as any, 'handleArrowLeft');
145+
146+
component['handleKeyDown'](event, [], 0);
147+
148+
expect(component['handleArrowLeft']).toHaveBeenCalled();
149+
});
150+
151+
it('should handleKeyDown correctly for ArrowRight key', () => {
152+
const event = new KeyboardEvent('keydown', { key: 'ArrowRight' });
153+
spyOn(component as any, 'handleArrowRight');
154+
155+
component['handleKeyDown'](event, [], 0);
156+
157+
expect(component['handleArrowRight']).toHaveBeenCalled();
158+
});
159+
160+
it('should call setTabIndex in next tag if index is 1', () => {
161+
const tagRemoveElements = [
162+
document.createElement('div'),
163+
document.createElement('div'),
164+
document.createElement('div')
165+
];
166+
167+
const indexArrow = 1;
168+
169+
spyOn(component, 'setTabIndex' as any);
170+
spyOn(tagRemoveElements[indexArrow + 1], 'focus');
171+
172+
component['handleArrowRight'](tagRemoveElements, indexArrow);
173+
174+
expect(component['setTabIndex']).toHaveBeenCalledWith(tagRemoveElements[indexArrow], -1);
175+
expect(tagRemoveElements[indexArrow + 1].focus).toHaveBeenCalled();
176+
expect(component['setTabIndex']).toHaveBeenCalledWith(tagRemoveElements[indexArrow + 1], 0);
177+
});
178+
179+
it('should call setTabIndex in previous tag if index is 1', () => {
180+
const tagRemoveElements = [
181+
document.createElement('div'),
182+
document.createElement('div'),
183+
document.createElement('div')
184+
];
185+
186+
const indexArrow = 1;
187+
188+
spyOn(component, 'setTabIndex' as any);
189+
spyOn(tagRemoveElements[indexArrow - 1], 'focus');
190+
191+
component['handleArrowLeft'](tagRemoveElements, indexArrow);
192+
193+
expect(component['setTabIndex']).toHaveBeenCalledWith(tagRemoveElements[indexArrow], -1);
194+
expect(tagRemoveElements[indexArrow - 1].focus).toHaveBeenCalled();
195+
expect(component['setTabIndex']).toHaveBeenCalledWith(tagRemoveElements[indexArrow - 1], 0);
196+
});
197+
198+
it('should focus on the previous element if the tag length is equal to the closed index', () => {
199+
const tagRemoveElements = [
200+
document.createElement('div'),
201+
document.createElement('div'),
202+
document.createElement('div')
203+
];
204+
const indexClosed = 3;
205+
spyOn(tagRemoveElements[indexClosed - 1], 'focus');
206+
207+
component['focusOnRemoveTag'](tagRemoveElements, indexClosed);
208+
209+
expect(tagRemoveElements[indexClosed - 1].focus).toHaveBeenCalled();
210+
});
211+
212+
it('should focus on the current element if the tag length is not equal to the closed index', () => {
213+
const tagRemoveElements = [
214+
document.createElement('div'),
215+
document.createElement('div'),
216+
document.createElement('div')
217+
];
218+
const indexClosed = 1;
219+
spyOn(tagRemoveElements[indexClosed], 'focus');
220+
221+
component['focusOnRemoveTag'](tagRemoveElements, indexClosed);
222+
223+
expect(tagRemoveElements[indexClosed].focus).toHaveBeenCalled();
224+
});
225+
226+
it('should focus in previous tag if remove next tag ', () => {
227+
const tagRemoveElements = [
228+
document.createElement('div'),
229+
document.createElement('div'),
230+
document.createElement('div')
231+
];
232+
233+
const initialIndex = 3;
234+
235+
spyOn(component, 'setTabIndex' as any);
236+
237+
component['initializeTagRemoveElements'](tagRemoveElements, initialIndex);
238+
239+
expect(component['setTabIndex']).toHaveBeenCalledWith(tagRemoveElements[initialIndex - 1], 0);
240+
});
241+
242+
it('should add keydown event listeners', () => {
243+
const tagRemoveElements = [document.createElement('div')];
244+
const initialIndex = 0;
245+
const fakeKeyboardEvent = new KeyboardEvent('keydown');
246+
247+
spyOn(component as any, 'setTabIndex');
248+
spyOn(component as any, 'handleKeyDown');
249+
250+
component['initializeTagRemoveElements'](tagRemoveElements, initialIndex);
251+
252+
expect(component['setTabIndex']).toHaveBeenCalledWith(tagRemoveElements[0], 0);
253+
254+
tagRemoveElements[0].dispatchEvent(fakeKeyboardEvent);
255+
256+
expect(component['handleKeyDown']).toHaveBeenCalled();
257+
});
258+
259+
it('should add blur event listeners and call setTabIndex', () => {
260+
const tagRemoveElements = [document.createElement('div'), document.createElement('div')];
261+
const initialIndex = 0;
262+
263+
spyOn(component as any, 'setTabIndex');
264+
265+
component['initializeTagRemoveElements'](tagRemoveElements, initialIndex);
266+
267+
tagRemoveElements[0].focus();
268+
tagRemoveElements[0].dispatchEvent(new Event('blur'));
269+
270+
expect(component['setTabIndex']).toHaveBeenCalledWith(tagRemoveElements[0], -1);
271+
expect(component['setTabIndex']).toHaveBeenCalledWith(tagRemoveElements[1], 0);
272+
});
273+
274+
it('should set tab index to 0 for the previous element when initialIndex is not 0', () => {
275+
const tagRemoveElements = [document.createElement('div'), document.createElement('div')];
276+
const initialIndex = 1;
277+
278+
spyOn(component as any, 'setTabIndex');
279+
280+
component['initializeTagRemoveElements'](tagRemoveElements, initialIndex);
281+
282+
expect(component['setTabIndex']).toHaveBeenCalledWith(tagRemoveElements[0], 0);
283+
});
284+
285+
it('focusOnNextTag: should select attribute unselected with index 0', () => {
286+
const tagsFake = document.createElement('div');
287+
tagsFake.innerHTML = `
288+
<div class="po-tag-remove"></div>
289+
<div class="po-tag-remove"></div>
290+
<div class="po-tag-remove"></div>
291+
`;
292+
293+
spyOn(component, <any>'focusOnRemoveTag');
294+
295+
component['focusOnNextTag'](0, 'enter');
296+
297+
expect(component['focusOnRemoveTag']).toHaveBeenCalled();
298+
});
299+
300+
it('focusOnNextTag: should select attribute unselected whitout index', () => {
301+
const tagsFake = document.createElement('div');
302+
tagsFake.innerHTML = `
303+
<div class="po-tag-remove"></div>
304+
<div class="po-tag-remove"></div>
305+
<div class="po-tag-remove"></div>
306+
`;
307+
308+
spyOn(component, <any>'focusOnRemoveTag');
309+
310+
component['focusOnNextTag'](null, 'enter');
311+
312+
expect(component['focusOnRemoveTag']).toHaveBeenCalled();
313+
});
314+
95315
describe('Templates:', () => {
96316
it(`should set tabindex to 0 if have a disclaimer with 'hideClose'.`, () => {
97317
component.disclaimers = [{ value: 'po', hideClose: false }];
98318

99319
fixture.detectChanges();
100320

101-
expect(nativeElement.querySelector('.po-disclaimer-remove[tabindex="0"]')).toBeTruthy();
321+
expect(nativeElement.querySelector('.po-tag-remove[tabindex="0"]')).toBeTruthy();
102322
});
103323

104324
it(`shouldn't set tabindex if disclaimer doesn't have 'hideClose'.`, () => {

0 commit comments

Comments
 (0)