Skip to content

Commit

Permalink
fix(core): DropdownHover properly reflect state for HostedDropdown (
Browse files Browse the repository at this point in the history
  • Loading branch information
waterplea authored Jan 31, 2023
1 parent 31231dc commit 78b8e92
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ import {
} from '@taiga-ui/core/directives/dropdown';
import {tuiIsEditingKey} from '@taiga-ui/core/utils/miscellaneous';
import {PolymorpheusContent} from '@tinkoff/ng-polymorpheus';
import {BehaviorSubject, combineLatest, EMPTY, Observable} from 'rxjs';
import {map, startWith} from 'rxjs/operators';
import {BehaviorSubject, EMPTY, merge} from 'rxjs';
import {distinctUntilChanged, skip} from 'rxjs/operators';

import {TuiHostedDropdownConnectorDirective} from './hosted-dropdown-connector.directive';

Expand All @@ -42,6 +42,7 @@ export interface TuiHostedDropdownContext
close(): void;
}

/* eslint-disable @typescript-eslint/member-ordering */
@Component({
selector: 'tui-hosted-dropdown',
templateUrl: './hosted-dropdown.template.html',
Expand All @@ -59,7 +60,8 @@ export class TuiHostedDropdownComponent implements TuiFocusableElementAccessor {
@ViewChild(TuiDropdownDirective)
private readonly dropdownDirective?: TuiDropdownDirective;

private readonly manual$ = new BehaviorSubject(false);
/** TODO: rename in 4.0 */
readonly openChange = new BehaviorSubject(false);

@ViewChild(TuiActiveZoneDirective)
readonly activeZone!: TuiActiveZoneDirective;
Expand All @@ -76,34 +78,32 @@ export class TuiHostedDropdownComponent implements TuiFocusableElementAccessor {
@tuiDefaultProp()
canOpen = true;

@Output()
readonly openChange = new EventEmitter<boolean>();
@Output('openChange')
readonly open$ = merge(this.openChange, this.hover$ || EMPTY).pipe(
skip(1),
distinctUntilChanged(),
);

@Output()
readonly focusedChange = new EventEmitter<boolean>();

readonly context!: TuiContextWithImplicit<TuiActiveZoneDirective>;

readonly open$ = combineLatest([
this.manual$,
(this.hover$ || EMPTY).pipe(startWith(false)),
]).pipe(map(([manual, hover]) => manual || hover));

constructor(
@Optional()
@Inject(TuiDropdownHoverDirective)
private readonly hover$: Observable<boolean> | null,
private readonly hover$: TuiDropdownHoverDirective | null,
@Inject(ElementRef) private readonly elementRef: ElementRef,
) {}

@Input()
@tuiDefaultProp()
set open(open: boolean) {
this.manual$.next(open);
this.openChange.next(open);
}

get open(): boolean {
return this.manual$.value;
return this.openChange.value;
}

get host(): HTMLElement {
Expand Down Expand Up @@ -150,7 +150,11 @@ export class TuiHostedDropdownComponent implements TuiFocusableElementAccessor {

@HostListener('click', ['$event.target'])
onClick(target: HTMLElement): void {
if (!this.hostEditable && this.computedHost.contains(target)) {
if (
!this.hostEditable &&
this.computedHost.contains(target) &&
!this.hover$?.hovered
) {
this.updateOpen(!this.open);
}
}
Expand Down Expand Up @@ -198,12 +202,9 @@ export class TuiHostedDropdownComponent implements TuiFocusableElementAccessor {
}

updateOpen(open: boolean): void {
if (open && !this.canOpen) {
return;
if (!open || this.canOpen) {
this.open = open;
}

this.open = open;
this.openChange.emit(open);
}

readonly close = (): void => this.updateOpen(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {Directive, Inject, Input} from '@angular/core';
import {tuiDefaultProp, TuiHoveredService} from '@taiga-ui/cdk';
import {tuiAsDriver, TuiDriver} from '@taiga-ui/core/abstract';
import {merge, Observable, of, Subject} from 'rxjs';
import {delay, switchMap} from 'rxjs/operators';
import {delay, share, switchMap, tap} from 'rxjs/operators';

@Directive({
selector: '[tuiDropdownHover]:not(ng-container)',
Expand All @@ -14,6 +14,10 @@ export class TuiDropdownHoverDirective extends TuiDriver {
switchMap(visible =>
of(visible).pipe(delay(visible ? this.showDelay : this.hideDelay)),
),
tap(visible => {
this.hovered = visible;
}),
share(),
);

@Input('tuiDropdownShowDelay')
Expand All @@ -24,6 +28,8 @@ export class TuiDropdownHoverDirective extends TuiDriver {
@tuiDefaultProp()
hideDelay = 500;

hovered = false;

constructor(
@Inject(TuiHoveredService) private readonly hovered$: Observable<boolean>,
) {
Expand Down
7 changes: 6 additions & 1 deletion projects/core/directives/dropdown/dropdown.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
ElementRef,
HostBinding,
Inject,
OnDestroy,
Optional,
Self,
} from '@angular/core';
Expand Down Expand Up @@ -42,7 +43,7 @@ import {TUI_DROPDOWN_OPTIONS, TuiDropdownOptions} from './dropdown-options.direc
providers: [TuiDestroyService, TuiPositionService],
animations: [tuiDropdownAnimation],
})
export class TuiDropdownComponent {
export class TuiDropdownComponent implements OnDestroy {
@HostBinding('@tuiDropdownAnimation')
readonly dropdownAnimation = {
value: TuiDropdownAnimation.FadeInTop,
Expand Down Expand Up @@ -70,6 +71,10 @@ export class TuiDropdownComponent {
});
}

ngOnDestroy(): void {
this.onHoveredChange(false);
}

onHoveredChange(hovered: boolean): void {
if (this.hoverDirective) {
this.hoverDirective.toggle(hovered);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,4 @@
</ng-template>
</tui-hosted-dropdown>
</nav>
<p>Current state: {{ open ? 'open' : 'closed' }}</p>

0 comments on commit 78b8e92

Please sign in to comment.