From 104753cb272106ff1e7b3dee87ba3edcd21960a3 Mon Sep 17 00:00:00 2001 From: "Shivprasad Kounsalye (Remote Angular Dev)" Date: Fri, 6 Dec 2024 16:49:34 +0530 Subject: [PATCH] Feature #3417 - Implement tuiDropdownDirectionChange & tuiHintDirectionChange (New branch with clean git history) (#9822) Co-authored-by: Alex Inkin --- .../dropdown-position-sided.directive.ts | 4 +++- .../dropdown/dropdown-position.directive.ts | 18 +++++++++++++++--- .../directives/dropdown/dropdown.directive.ts | 8 +++++++- .../directives/hint/hint-position.directive.ts | 13 ++++++++++++- .../core/directives/hint/hint.directive.ts | 1 + .../demo/src/components/dropdown/index.html | 7 +++++++ .../abstract/dropdown-documentation/index.html | 7 +++++++ .../inherited-documentation/index.html | 7 +++++++ 8 files changed, 59 insertions(+), 6 deletions(-) diff --git a/projects/core/directives/dropdown/dropdown-position-sided.directive.ts b/projects/core/directives/dropdown/dropdown-position-sided.directive.ts index 6f5e5a029c60..39ba8eb0aab6 100644 --- a/projects/core/directives/dropdown/dropdown-position-sided.directive.ts +++ b/projects/core/directives/dropdown/dropdown-position-sided.directive.ts @@ -16,7 +16,6 @@ export class TuiDropdownPositionSided extends TuiPositionAccessor { private readonly options = inject(TUI_DROPDOWN_OPTIONS); private readonly viewport = inject(TUI_VIEWPORT); private readonly vertical = inject(TuiDropdownPosition); - private previous = this.options.direction || 'bottom'; @Input() @@ -57,10 +56,13 @@ export class TuiDropdownPositionSided extends TuiPositionAccessor { (available[this.previous] > minHeight && direction) || this.previous === better ) { + this.vertical.emitDirection(this.previous); + return [position[this.previous], left]; } this.previous = better; + this.vertical.emitDirection(better); return [position[better], left]; } diff --git a/projects/core/directives/dropdown/dropdown-position.directive.ts b/projects/core/directives/dropdown/dropdown-position.directive.ts index 2f224ad47967..f6f42ef8a3ee 100644 --- a/projects/core/directives/dropdown/dropdown-position.directive.ts +++ b/projects/core/directives/dropdown/dropdown-position.directive.ts @@ -1,5 +1,6 @@ -import {Directive, inject} from '@angular/core'; +import {Directive, EventEmitter, inject, Output} from '@angular/core'; import {EMPTY_CLIENT_RECT} from '@taiga-ui/cdk/constants'; +import {tuiPure} from '@taiga-ui/cdk/utils/miscellaneous'; import { tuiFallbackAccessor, TuiPositionAccessor, @@ -13,7 +14,6 @@ import {TUI_DROPDOWN_OPTIONS} from './dropdown-options.directive'; @Directive({ standalone: true, - selector: '[tuiDropdownPosition]', }) export class TuiDropdownPosition extends TuiPositionAccessor { private readonly options = inject(TUI_DROPDOWN_OPTIONS); @@ -21,6 +21,9 @@ export class TuiDropdownPosition extends TuiPositionAccessor { private previous?: TuiVerticalDirection; + @Output('tuiDropdownDirectionChange') + public readonly directionChange = new EventEmitter(); + public readonly type = 'dropdown'; public readonly accessor: TuiRectAccessor | null = tuiFallbackAccessor('dropdown')( @@ -28,6 +31,11 @@ export class TuiDropdownPosition extends TuiPositionAccessor { inject(TuiDropdownDirective, {optional: true})!, ); + @tuiPure + public emitDirection(direction: TuiVerticalDirection): void { + this.directionChange.emit(direction); + } + public getPosition({width, height}: DOMRect): TuiPoint { if (!width && !height) { this.previous = undefined; @@ -60,16 +68,20 @@ export class TuiDropdownPosition extends TuiPositionAccessor { : right, left: Math.max(viewport.left, left), } as const; - const better = available.top > available.bottom ? 'top' : 'bottom'; + const better: TuiVerticalDirection = + available.top > available.bottom ? 'top' : 'bottom'; if ( (available[previous] > minHeight && direction) || available[previous] > height ) { + this.emitDirection(previous); + return [position[previous], position[align]]; } this.previous = better; + this.emitDirection(better); return [position[better], position[align]]; } diff --git a/projects/core/directives/dropdown/dropdown.directive.ts b/projects/core/directives/dropdown/dropdown.directive.ts index 327e8a5e4e90..3f2c9fdfdffa 100644 --- a/projects/core/directives/dropdown/dropdown.directive.ts +++ b/projects/core/directives/dropdown/dropdown.directive.ts @@ -34,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 diff --git a/projects/core/directives/hint/hint-position.directive.ts b/projects/core/directives/hint/hint-position.directive.ts index b7dd4674d761..dec4374ca745 100644 --- a/projects/core/directives/hint/hint-position.directive.ts +++ b/projects/core/directives/hint/hint-position.directive.ts @@ -1,6 +1,7 @@ -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 {tuiPure} from '@taiga-ui/cdk/utils/miscellaneous'; import { tuiFallbackAccessor, TuiPositionAccessor, @@ -38,8 +39,16 @@ export class TuiHintPosition extends TuiPositionAccessor { @Input('tuiHintDirection') public direction: TuiHintOptions['direction'] = inject(TUI_HINT_OPTIONS).direction; + @Output('tuiHintDirectionChange') + public readonly directionChange = new EventEmitter(); + public readonly type = 'hint'; + @tuiPure + public emitDirection(direction: TuiHintDirection): void { + this.directionChange.emit(direction); + } + public getPosition(rect: DOMRect, el?: HTMLElement): TuiPoint { const width = el?.clientWidth ?? rect.width; const height = el?.clientHeight ?? rect.height; @@ -84,6 +93,8 @@ export class TuiHintPosition extends TuiPositionAccessor { this.checkPosition(this.points[direction], width, height), ); + this.emitDirection(direction || this.fallback); + return this.points[direction || this.fallback]; } diff --git a/projects/core/directives/hint/hint.directive.ts b/projects/core/directives/hint/hint.directive.ts index 70cec341c52a..0e6e2666f300 100644 --- a/projects/core/directives/hint/hint.directive.ts +++ b/projects/core/directives/hint/hint.directive.ts @@ -36,6 +36,7 @@ import {TuiHintPosition} from './hint-position.directive'; { directive: TuiHintPosition, inputs: ['tuiHintDirection'], + outputs: ['tuiHintDirectionChange'], }, ], }) diff --git a/projects/demo/src/components/dropdown/index.html b/projects/demo/src/components/dropdown/index.html index a9227631ae0c..02c260f0201a 100644 --- a/projects/demo/src/components/dropdown/index.html +++ b/projects/demo/src/components/dropdown/index.html @@ -80,3 +80,10 @@ > Dropdown offset + + Dropdown direction change + diff --git a/projects/demo/src/modules/components/abstract/dropdown-documentation/index.html b/projects/demo/src/modules/components/abstract/dropdown-documentation/index.html index ceb68929811d..40a99ee09f5b 100644 --- a/projects/demo/src/modules/components/abstract/dropdown-documentation/index.html +++ b/projects/demo/src/modules/components/abstract/dropdown-documentation/index.html @@ -78,4 +78,11 @@
> Dropdown offset + + Dropdown direction change + diff --git a/projects/demo/src/modules/components/abstract/inherited-documentation/index.html b/projects/demo/src/modules/components/abstract/inherited-documentation/index.html index 43b6bc2997db..662320326635 100644 --- a/projects/demo/src/modules/components/abstract/inherited-documentation/index.html +++ b/projects/demo/src/modules/components/abstract/inherited-documentation/index.html @@ -105,4 +105,11 @@
> Hint mode + + Hint direction change +