Skip to content

Commit be19c50

Browse files
authored
fix(tags): mark tag-list pristine on init (#DS-3669) (#710)
1 parent acd4c60 commit be19c50

File tree

2 files changed

+40
-26
lines changed

2 files changed

+40
-26
lines changed

packages/components/tags/tag-list.component.spec.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import { KbqTagList, KbqTagsModule } from './index';
2222
import { KbqTagInputEvent } from './tag-input';
2323
import { KbqTag, KbqTagEvent, KbqTagRemove } from './tag.component';
2424

25-
describe('KbqTagList', () => {
25+
describe(KbqTagList.name, () => {
2626
let fixture: ComponentFixture<any>;
2727
let tagListDebugElement: DebugElement;
2828
let tagListNativeElement: HTMLElement;
@@ -726,6 +726,13 @@ describe('KbqTagList', () => {
726726
expect(fixture.componentInstance.control.touched).toBe(true);
727727
});
728728

729+
it('should mark as pristine on init', () => {
730+
fixture.componentInstance.control = new UntypedFormControl('pizza-1');
731+
fixture.detectChanges();
732+
733+
expect(fixture.componentInstance.control.pristine).toBeTruthy();
734+
});
735+
729736
it('should not set touched when a disabled tag list is touched', () => {
730737
expect(fixture.componentInstance.control.touched).toBe(false);
731738

packages/components/tags/tag-list.component.ts

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -372,34 +372,40 @@ export class KbqTagList
372372
});
373373

374374
// When the list changes, re-subscribe
375-
this.tags.changes.pipe(startWith(null), takeUntilDestroyed(this.destroyRef)).subscribe(() => {
376-
if (this.disabled) {
377-
// Since this happens after the content has been
378-
// checked, we need to defer it to the next tick.
379-
Promise.resolve().then(() => {
380-
this.syncTagsDisabledState();
381-
});
382-
}
375+
this.tags.changes
376+
.pipe(startWith(null), takeUntilDestroyed(this.destroyRef))
377+
.subscribe((currentTags: QueryList<KbqTag> | null) => {
378+
if (this.disabled) {
379+
// Since this happens after the content has been
380+
// checked, we need to defer it to the next tick.
381+
Promise.resolve().then(() => {
382+
this.syncTagsDisabledState();
383+
});
384+
}
383385

384-
this.resetTags();
386+
this.resetTags();
385387

386-
// Reset tags selected/deselected status
387-
this.initializeSelection();
388+
// Reset tags selected/deselected status
389+
this.initializeSelection();
388390

389-
// Check to see if we need to update our tab index
390-
this.updateTabIndex();
391+
// Check to see if we need to update our tab index
392+
this.updateTabIndex();
391393

392-
// Check to see if we have a destroyed tag and need to refocus
393-
this.updateFocusForDestroyedTags();
394+
// Check to see if we have a destroyed tag and need to refocus
395+
this.updateFocusForDestroyedTags();
394396

395-
// Defer setting the value in order to avoid the "Expression
396-
// has changed after it was checked" errors from Angular.
397-
Promise.resolve().then(() => {
398-
this.tagChanges.emit(this.tags.toArray());
399-
this.stateChanges.next();
400-
this.propagateTagsChanges();
397+
// Defer setting the value in order to avoid the "Expression
398+
// has changed after it was checked" errors from Angular.
399+
Promise.resolve().then(() => {
400+
this.tagChanges.emit(this.tags.toArray());
401+
this.stateChanges.next();
402+
403+
// do not call on initial
404+
if (currentTags) {
405+
this.propagateTagsChanges();
406+
}
407+
});
401408
});
402-
});
403409

404410
this.propagateSelectableToChildren();
405411
}
@@ -445,7 +451,7 @@ export class KbqTagList
445451
registerInput(inputElement: KbqTagTextControl): void {
446452
this.tagInput = inputElement;
447453

448-
// todo need rethink about it
454+
// todo need rethink about it (#DS-3740)
449455
if (this.ngControl && inputElement.ngControl?.statusChanges) {
450456
inputElement.ngControl.statusChanges.subscribe(() =>
451457
this.ngControl.control!.setErrors(inputElement.ngControl!.errors)
@@ -495,7 +501,7 @@ export class KbqTagList
495501
return;
496502
}
497503

498-
// TODO: ARIA says this should focus the first `selected` tag if any are selected.
504+
// TODO: ARIA says this should focus the first `selected` tag if any are selected. (#DS-3740)
499505
// Focus on first element if there's no tagInput inside tag-list
500506
if (this.tagInput && this.tagInput.focused) {
501507
// do nothing
@@ -542,6 +548,7 @@ export class KbqTagList
542548

543549
setSelectionByValue(value: any, isUserInput: boolean = true) {
544550
this.clearSelection();
551+
// @TODO seems like redundant action, need to double check (#DS-3740)
545552
this.tags.forEach((tag) => tag.deselect());
546553

547554
if (Array.isArray(value)) {
@@ -704,7 +711,7 @@ export class KbqTagList
704711
}
705712

706713
/** Emits change event to set the model value. */
707-
// todo need rethink this method and selection logic
714+
// todo need rethink this method and selection logic (#DS-3740)
708715
private propagateChanges(fallbackValue?: any): void {
709716
let valueToEmit: any;
710717

0 commit comments

Comments
 (0)