Skip to content

Commit

Permalink
feat(core): resolve pr comments
Browse files Browse the repository at this point in the history
  • Loading branch information
shiv9604 committed Nov 22, 2024
1 parent 3239faf commit b0c962b
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 92 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import {Directive, inject, Input} from '@angular/core';
import {Directive, EventEmitter, inject, Input, Output} from '@angular/core';
import {EMPTY_CLIENT_RECT} from '@taiga-ui/cdk/constants';
import {tuiAsPositionAccessor, TuiPositionAccessor} from '@taiga-ui/core/classes';
import {TUI_VIEWPORT} from '@taiga-ui/core/tokens';
import type {TuiPoint} from '@taiga-ui/core/types';
import type {TuiPoint, TuiVerticalDirection} from '@taiga-ui/core/types';
import {tuiEmitWhenChanged} from '@taiga-ui/core/utils';

import {TuiDropdownService} from './dropdown.service';
import {TUI_DROPDOWN_OPTIONS} from './dropdown-options.directive';
import {TuiDropdownPosition} from './dropdown-position.directive';

Expand All @@ -17,15 +17,18 @@ export class TuiDropdownPositionSided extends TuiPositionAccessor {
private readonly options = inject(TUI_DROPDOWN_OPTIONS);
private readonly viewport = inject(TUI_VIEWPORT);
private readonly vertical = inject(TuiDropdownPosition);
private readonly dropdownService = inject(TuiDropdownService);
private previous = this.options.direction || 'bottom';
private lastDirection!: TuiVerticalDirection;

@Input()
public tuiDropdownSided: boolean | string = '';

@Input()
public tuiDropdownSidedOffset = 4;

@Output('tuiDropdownDirectionChange')
public readonly directionChange = new EventEmitter<TuiVerticalDirection>();

public readonly type = 'dropdown';

public getPosition(rect: DOMRect): TuiPoint {
Expand Down Expand Up @@ -58,12 +61,22 @@ export class TuiDropdownPositionSided extends TuiPositionAccessor {
(available[this.previous] > minHeight && direction) ||
this.previous === better
) {
this.emitDirection(better);

return [position[this.previous], left];
}

this.previous = better;
this.dropdownService.publishDropdownDirection(better);
this.emitDirection(better);

return [position[better], left];
}

public emitDirection(direction: TuiVerticalDirection): void {
this.lastDirection = tuiEmitWhenChanged<TuiVerticalDirection>(
direction,
this.lastDirection,
this.directionChange,
);
}
}
16 changes: 11 additions & 5 deletions projects/core/directives/dropdown/dropdown-position.directive.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Directive, inject} from '@angular/core';
import {Directive, EventEmitter, inject, Output} from '@angular/core';
import {EMPTY_CLIENT_RECT} from '@taiga-ui/cdk/constants';
import {
tuiFallbackAccessor,
Expand All @@ -7,9 +7,9 @@ import {
} from '@taiga-ui/core/classes';
import {TUI_VIEWPORT} from '@taiga-ui/core/tokens';
import type {TuiPoint, TuiVerticalDirection} from '@taiga-ui/core/types';
import {tuiEmitWhenChanged} from '@taiga-ui/core/utils';

import {TuiDropdownDirective} from './dropdown.directive';
import {TuiDropdownService} from './dropdown.service';
import {TUI_DROPDOWN_OPTIONS} from './dropdown-options.directive';

@Directive({
Expand All @@ -20,9 +20,11 @@ export class TuiDropdownPosition extends TuiPositionAccessor {
private readonly options = inject(TUI_DROPDOWN_OPTIONS);
private readonly viewport = inject(TUI_VIEWPORT);

private readonly dropdownService = inject(TuiDropdownService);

private previous?: TuiVerticalDirection;
private lastDirection!: TuiVerticalDirection;

@Output('tuiDropdownDirectionChange')
public readonly directionChange = new EventEmitter<TuiVerticalDirection>();

public readonly type = 'dropdown';
public readonly accessor: TuiRectAccessor | null =
Expand Down Expand Up @@ -66,7 +68,11 @@ export class TuiDropdownPosition extends TuiPositionAccessor {
const better: TuiVerticalDirection =
available.top > available.bottom ? 'top' : 'bottom';

this.dropdownService.publishDropdownDirection(better);
this.lastDirection = tuiEmitWhenChanged<TuiVerticalDirection>(
better,
this.lastDirection,
this.directionChange,
);

if (
(available[previous] > minHeight && direction) ||
Expand Down
32 changes: 9 additions & 23 deletions projects/core/directives/dropdown/dropdown.directive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,20 @@ import type {AfterViewChecked, ComponentRef, OnChanges, OnDestroy} from '@angula
import {
ChangeDetectorRef,
Directive,
EventEmitter,
inject,
INJECTOR,
Input,
NgZone,
Output,
signal,
TemplateRef,
} from '@angular/core';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
import {tuiZonefree, tuiZonefreeScheduler} from '@taiga-ui/cdk/observables';
import {tuiZonefreeScheduler} from '@taiga-ui/cdk/observables';
import type {TuiContext} from '@taiga-ui/cdk/types';
import {tuiInjectElement} from '@taiga-ui/cdk/utils/dom';
import {tuiPure} from '@taiga-ui/cdk/utils/miscellaneous';
import type {TuiRectAccessor, TuiVehicle} from '@taiga-ui/core/classes';
import {tuiAsRectAccessor, tuiAsVehicle} from '@taiga-ui/core/classes';
import type {TuiPortalItem, TuiVerticalDirection} from '@taiga-ui/core/types';
import type {TuiPortalItem} from '@taiga-ui/core/types';
import {tuiCheckFixedPosition} from '@taiga-ui/core/utils';
import type {PolymorpheusContent} from '@taiga-ui/polymorpheus';
import {PolymorpheusComponent, PolymorpheusTemplate} from '@taiga-ui/polymorpheus';
Expand All @@ -37,7 +34,13 @@ import {TuiDropdownPosition} from './dropdown-position.directive';
tuiAsVehicle(TuiDropdownDirective),
],
exportAs: 'tuiDropdown',
hostDirectives: [TuiDropdownDriverDirective, TuiDropdownPosition],
hostDirectives: [
TuiDropdownDriverDirective,
{
directive: TuiDropdownPosition,
outputs: ['tuiDropdownDirectionChange'],
},
],
})
export class TuiDropdownDirective
implements
Expand All @@ -51,8 +54,6 @@ export class TuiDropdownDirective
private readonly refresh$ = new Subject<void>();
private readonly service = inject(TuiDropdownService);
private readonly cdr = inject(ChangeDetectorRef);
private readonly dropdownService = inject(TuiDropdownService);
private readonly zone = inject(NgZone);

protected readonly sub = this.refresh$
.pipe(throttleTime(0, tuiZonefreeScheduler()), takeUntilDestroyed())
Expand All @@ -61,9 +62,6 @@ export class TuiDropdownDirective
this.ref()?.changeDetectorRef.markForCheck();
});

@Output()
public readonly tuiDropdownDirectionChange = new EventEmitter<TuiVerticalDirection>();

public readonly el = tuiInjectElement();
public readonly type = 'dropdown';
public readonly component = new PolymorpheusComponent(
Expand All @@ -74,10 +72,6 @@ export class TuiDropdownDirective
public ref = signal<ComponentRef<unknown> | null>(null);
public content: PolymorpheusContent<TuiContext<() => void>>;

constructor() {
this.directionChangeObserver();
}

@Input()
public set tuiDropdown(content: PolymorpheusContent<TuiContext<() => void>>) {
this.content =
Expand Down Expand Up @@ -105,14 +99,6 @@ export class TuiDropdownDirective
this.toggle(false);
}

public directionChangeObserver(): void {
this.dropdownService.dropdownDirection$
.pipe(tuiZonefree(this.zone), takeUntilDestroyed())
.subscribe((direction: TuiVerticalDirection) => {
this.tuiDropdownDirectionChange.emit(direction);
});
}

public getClientRect(): DOMRect {
return this.el.getBoundingClientRect();
}
Expand Down
14 changes: 1 addition & 13 deletions projects/core/directives/dropdown/dropdown.service.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,7 @@
import {Injectable} from '@angular/core';
import {TuiPortalService} from '@taiga-ui/cdk/classes';
import type {TuiVerticalDirection} from '@taiga-ui/core/types';
import type {Observable} from 'rxjs';
import {distinctUntilChanged, Subject} from 'rxjs';

@Injectable({
providedIn: 'root',
})
export class TuiDropdownService extends TuiPortalService {
private readonly dropDirectionSubject = new Subject<TuiVerticalDirection>();

public readonly dropdownDirection$: Observable<TuiVerticalDirection> =
this.dropDirectionSubject.asObservable().pipe(distinctUntilChanged());

public publishDropdownDirection(direction: TuiVerticalDirection): void {
this.dropDirectionSubject.next(direction);
}
}
export class TuiDropdownService extends TuiPortalService {}
17 changes: 12 additions & 5 deletions projects/core/directives/hint/hint-position.directive.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Directive, inject, Input} from '@angular/core';
import {Directive, EventEmitter, inject, Input, Output} from '@angular/core';
import {EMPTY_CLIENT_RECT} from '@taiga-ui/cdk/constants';
import {TUI_IS_MOBILE} from '@taiga-ui/cdk/tokens';
import {
Expand All @@ -8,9 +8,9 @@ import {
} from '@taiga-ui/core/classes';
import {TUI_VIEWPORT} from '@taiga-ui/core/tokens';
import type {TuiPoint} from '@taiga-ui/core/types';
import {tuiEmitWhenChanged} from '@taiga-ui/core/utils/miscellaneous';

import {TuiHintDirective} from './hint.directive';
import {TuiHintService} from './hint.service';
import type {TuiHintDirection, TuiHintOptions} from './hint-options.directive';
import {TUI_HINT_DIRECTIONS, TUI_HINT_OPTIONS} from './hint-options.directive';

Expand All @@ -30,17 +30,20 @@ export class TuiHintPosition extends TuiPositionAccessor {
inject(TuiHintDirective),
);

private readonly hintService = inject(TuiHintService);

private readonly points: Record<TuiHintDirection, [number, number]> =
TUI_HINT_DIRECTIONS.reduce(
(acc, direction) => ({...acc, [direction]: [0, 0]}),
{} as Record<TuiHintDirection, [number, number]>,
);

private lastDirection!: TuiHintDirection;

@Input('tuiHintDirection')
public direction: TuiHintOptions['direction'] = inject(TUI_HINT_OPTIONS).direction;

@Output('tuiHintDirectionChange')
public readonly directionChange = new EventEmitter<TuiHintDirection>();

public readonly type = 'hint';

public getPosition(rect: DOMRect, el?: HTMLElement): TuiPoint {
Expand Down Expand Up @@ -87,7 +90,11 @@ export class TuiHintPosition extends TuiPositionAccessor {
this.checkPosition(this.points[direction], width, height),
);

this.hintService.publishHintDirection(direction || this.fallback);
this.lastDirection = tuiEmitWhenChanged<TuiHintDirection>(
direction || this.fallback,
this.lastDirection,
this.directionChange,
);

return this.points[direction || this.fallback];
}
Expand Down
31 changes: 2 additions & 29 deletions projects/core/directives/hint/hint.directive.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,6 @@
import type {OnDestroy} from '@angular/core';
import {
Directive,
EventEmitter,
inject,
INJECTOR,
Input,
NgZone,
Output,
signal,
} from '@angular/core';
import {takeUntilDestroyed} from '@angular/core/rxjs-interop';
import {Directive, inject, INJECTOR, Input, signal} from '@angular/core';
import {TuiActiveZone} from '@taiga-ui/cdk/directives/active-zone';
import {tuiZonefree} from '@taiga-ui/cdk/observables';
import {tuiInjectElement} from '@taiga-ui/cdk/utils/dom';
import type {TuiRectAccessor, TuiVehicle} from '@taiga-ui/core/classes';
import {tuiAsRectAccessor, tuiAsVehicle} from '@taiga-ui/core/classes';
Expand All @@ -23,7 +12,6 @@ import {TUI_HINT_COMPONENT} from './hint.providers';
import {TuiHintService} from './hint.service';
import {TuiHintDriver} from './hint-driver.directive';
import {TuiHintHover} from './hint-hover.directive';
import type {TuiHintDirection} from './hint-options.directive';
import {TUI_HINT_OPTIONS} from './hint-options.directive';
import {TuiHintPosition} from './hint-position.directive';

Expand All @@ -48,34 +36,27 @@ import {TuiHintPosition} from './hint-position.directive';
{
directive: TuiHintPosition,
inputs: ['tuiHintDirection'],
outputs: ['tuiHintDirectionChange'],
},
],
})
export class TuiHintDirective<C>
implements OnDestroy, TuiPortalItem<C>, TuiRectAccessor, TuiVehicle
{
private readonly service = inject(TuiHintService);
private readonly zone: NgZone = inject(NgZone);

@Input('tuiHintContext')
public context?: C;

@Input('tuiHintAppearance')
public appearance = inject(TUI_HINT_OPTIONS).appearance;

@Output('tuiHintDirectionChange')
public readonly directionChange = new EventEmitter<TuiHintDirection>();

public content = signal<PolymorpheusContent<C>>(null);
public component = inject(PolymorpheusComponent<unknown>);
public readonly el = tuiInjectElement();
public readonly activeZone? = inject(TuiActiveZone, {optional: true});
public readonly type = 'hint';

constructor() {
this.hintDirectionObserver();
}

@Input()
public set tuiHint(content: PolymorpheusContent<C>) {
this.content.set(content);
Expand All @@ -100,12 +81,4 @@ export class TuiHintDirective<C>
this.service.remove(this);
}
}

public hintDirectionObserver(): void {
this.service.hintDirection$
.pipe(tuiZonefree(this.zone), takeUntilDestroyed())
.subscribe((direction: TuiHintDirection) => {
this.directionChange.emit(direction);
});
}
}
13 changes: 1 addition & 12 deletions projects/core/directives/hint/hint.service.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import {Injectable} from '@angular/core';
import type {TuiPortalItem} from '@taiga-ui/core/types';
import type {Observable} from 'rxjs';
import {BehaviorSubject, distinctUntilChanged, Subject} from 'rxjs';

import type {TuiHintDirection} from './hint-options.directive';
import {BehaviorSubject} from 'rxjs';

/**
* Service for displaying hints/tooltips
Expand All @@ -12,10 +9,6 @@ import type {TuiHintDirection} from './hint-options.directive';
providedIn: 'root',
})
export class TuiHintService extends BehaviorSubject<readonly TuiPortalItem[]> {
private readonly hintDirectionSubject = new Subject<TuiHintDirection>();
public readonly hintDirection$: Observable<TuiHintDirection> =
this.hintDirectionSubject.asObservable().pipe(distinctUntilChanged());

constructor() {
super([]);
}
Expand All @@ -29,8 +22,4 @@ export class TuiHintService extends BehaviorSubject<readonly TuiPortalItem[]> {
this.next(this.value.filter((hint) => hint !== directive));
}
}

public publishHintDirection(direction: TuiHintDirection): void {
this.hintDirectionSubject.next(direction);
}
}
15 changes: 15 additions & 0 deletions projects/core/utils/miscellaneous/emit-when-changed.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type {EventEmitter} from '@angular/core';

export function tuiEmitWhenChanged<T>(
newValue: T,
lastEmittedValue: T,
emitter: EventEmitter<T>,
): T {
if (lastEmittedValue !== newValue) {
emitter.emit(newValue);

return newValue;
}

return lastEmittedValue;
}
1 change: 1 addition & 0 deletions projects/core/utils/miscellaneous/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './emit-when-changed';
export * from './is-editing-key';
export * from './is-obscured';
export * from './override-options';
Expand Down

0 comments on commit b0c962b

Please sign in to comment.