Skip to content

Commit

Permalink
fix(kit): MultiSelect fix dropdown for various updateOn options (#…
Browse files Browse the repository at this point in the history
…3479)

Co-authored-by: tinkoff-bot <[email protected]>
  • Loading branch information
waterplea and tinkoff-bot authored Jan 23, 2023
1 parent 3cdbb1f commit 554c519
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 31 deletions.
9 changes: 2 additions & 7 deletions projects/core/interfaces/data-list-host.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import {
AbstractTuiControl,
AbstractTuiInteractive,
TuiIdentityMatcher,
} from '@taiga-ui/cdk';
import {TuiIdentityMatcher} from '@taiga-ui/cdk';

// TODO: Consider refactoring checkOption, it is only needed in ComboBox
export interface TuiDataListHost<T, K = AbstractTuiControl<T> | AbstractTuiInteractive> {
hostControl?: K;
export interface TuiDataListHost<T> {
handleOption(option: T): void;
checkOption?(option: T): void;
readonly identityMatcher?: TuiIdentityMatcher<T>;
Expand Down
4 changes: 2 additions & 2 deletions projects/kit/components/combo-box/combo-box.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export class TuiComboBoxComponent<T>
private readonly hostedDropdown?: TuiHostedDropdownComponent;

@ViewChild(TuiPrimitiveTextfieldComponent)
readonly hostControl?: TuiPrimitiveTextfieldComponent;
private readonly textfield?: TuiPrimitiveTextfieldComponent;

@Input()
@tuiDefaultProp()
Expand Down Expand Up @@ -128,7 +128,7 @@ export class TuiComboBoxComponent<T>
}

get nativeFocusableElement(): HTMLInputElement | null {
return this.hostControl?.nativeFocusableElement ?? null;
return this.textfield?.nativeFocusableElement ?? null;
}

get focused(): boolean {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {ChangeDetectionStrategy, Component} from '@angular/core';
import {tuiIsPresent} from '@taiga-ui/cdk';
import {TuiSizeL} from '@taiga-ui/core';
import type {TuiStringifiableItem} from '@taiga-ui/kit/classes';
import {TuiSelectOptionComponent} from '@taiga-ui/kit/components/select-option';

@Component({
Expand All @@ -10,7 +9,9 @@ import {TuiSelectOptionComponent} from '@taiga-ui/kit/components/select-option';
styleUrls: ['./multi-select-option.style.less'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TuiMultiSelectOptionComponent<T> extends TuiSelectOptionComponent<T> {
export class TuiMultiSelectOptionComponent<
T extends any[],
> extends TuiSelectOptionComponent<T> {
get size(): TuiSizeL {
return this.option.size === 'l' ||
(this.dataList?.size === 'l' && !this.option.size)
Expand All @@ -23,15 +24,8 @@ export class TuiMultiSelectOptionComponent<T> extends TuiSelectOptionComponent<T

return (
tuiIsPresent(value) &&
((this.control.value ?? []).some((item: T) => this.matcher(item, value)) ||
/**
* @description:
* if host has updateOn type in form by values as 'blur' | 'submit'
* then we can't listen changes directly in this.control.value
*/
(this.host.hostControl?.control?.value ?? []).some(
({item}: TuiStringifiableItem<T>) => this.matcher(item, value),
))
tuiIsPresent(this.value) &&
this.value.some(item => this.matcher(item, value))
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export class TuiMultiSelectComponent<T>
private readonly hostedDropdown?: TuiHostedDropdownComponent;

@ViewChild(TuiInputTagComponent)
readonly hostControl?: TuiInputTagComponent;
private readonly input?: TuiInputTagComponent;

@Input()
@tuiDefaultProp()
Expand Down Expand Up @@ -158,11 +158,11 @@ export class TuiMultiSelectComponent<T>
}

get nativeFocusableElement(): HTMLInputElement | null {
return this.hostControl?.nativeFocusableElement ?? null;
return this.input?.nativeFocusableElement ?? null;
}

get focused(): boolean {
return !!this.hostControl?.focused || !!this.hostedDropdown?.focused;
return !!this.input?.focused || !!this.hostedDropdown?.focused;
}

get computedValue(): readonly T[] {
Expand Down
30 changes: 22 additions & 8 deletions projects/kit/components/select-option/select-option.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
ChangeDetectionStrategy,
Component,
DoCheck,
ElementRef,
Inject,
OnInit,
Expand All @@ -9,7 +10,7 @@ import {
} from '@angular/core';
import {NgControl} from '@angular/forms';
import {
AbstractTuiMultipleControl,
AbstractTuiControl,
TUI_DEFAULT_IDENTITY_MATCHER,
TuiContextWithImplicit,
TuiIdentityMatcher,
Expand All @@ -23,7 +24,7 @@ import {
TuiOptionComponent,
} from '@taiga-ui/core';
import {POLYMORPHEUS_CONTEXT, PolymorpheusComponent} from '@tinkoff/ng-polymorpheus';
import {EMPTY, merge} from 'rxjs';
import {EMPTY, merge, Subject} from 'rxjs';
import {distinctUntilChanged, map, startWith} from 'rxjs/operators';

@Component({
Expand All @@ -32,10 +33,12 @@ import {distinctUntilChanged, map, startWith} from 'rxjs/operators';
styleUrls: ['./select-option.style.less'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TuiSelectOptionComponent<T> implements OnInit {
export class TuiSelectOptionComponent<T> implements OnInit, DoCheck {
private readonly changeDetection$ = new Subject();

readonly selected$ = merge(
this.control.valueChanges ?? EMPTY,
this.host?.hostControl?.control?.valueChanges ?? EMPTY,
this.changeDetection$,
this.control.valueChanges || EMPTY,
tuiTypedFromEvent(this.elementRef.nativeElement, 'animationstart'),
).pipe(
startWith(null),
Expand All @@ -47,19 +50,26 @@ export class TuiSelectOptionComponent<T> implements OnInit {
@Inject(POLYMORPHEUS_CONTEXT)
readonly context: TuiContextWithImplicit<TemplateRef<Record<string, unknown>>>,
@Inject(TUI_DATA_LIST_HOST)
protected readonly host: TuiDataListHost<T, AbstractTuiMultipleControl<string>>,
private readonly host: TuiDataListHost<T>,
@Inject(ElementRef) private readonly elementRef: ElementRef<HTMLElement>,
@Inject(TuiOptionComponent) protected readonly option: TuiOptionComponent<T>,
@Optional()
@Inject(TuiDataListComponent)
protected readonly dataList: TuiDataListComponent<T> | null,
@Inject(NgControl) protected readonly control: NgControl,
@Optional()
@Inject(AbstractTuiControl)
protected readonly abstractControl: AbstractTuiControl<T> | null,
) {}

get matcher(): TuiIdentityMatcher<T> {
return this.host.identityMatcher || TUI_DEFAULT_IDENTITY_MATCHER;
}

ngDoCheck(): void {
this.changeDetection$.next();
}

ngOnInit(): void {
/**
* This would cause changes inside already checked parent component (during the same change detection cycle),
Expand All @@ -75,11 +85,15 @@ export class TuiSelectOptionComponent<T> implements OnInit {
});
}

protected get value(): T | null {
return this.abstractControl?.value ?? this.control.value;
}

protected get selected(): boolean {
return (
tuiIsPresent(this.option.value) &&
tuiIsPresent(this.control.value) &&
this.matcher(this.control.value, this.option.value)
tuiIsPresent(this.value) &&
this.matcher(this.value, this.option.value)
);
}
}
Expand Down

0 comments on commit 554c519

Please sign in to comment.