From 7efbf49c0564dd096c4dec136bef58ed6ba8b7e0 Mon Sep 17 00:00:00 2001 From: splincode Date: Tue, 17 Sep 2024 13:20:27 +0300 Subject: [PATCH] feat(cdk): support provide custom query selector for auto focus directive --- .../directives/auto-focus/autofocus.options.ts | 17 ++++++++++++++--- .../auto-focus/handlers/abstract.handler.ts | 9 ++++++--- .../auto-focus/handlers/default.handler.ts | 6 ++++-- .../auto-focus/handlers/ios.handler.ts | 4 +++- .../test/auto-focus.directive.spec.ts | 13 +++++++++++-- 5 files changed, 38 insertions(+), 11 deletions(-) diff --git a/projects/cdk/directives/auto-focus/autofocus.options.ts b/projects/cdk/directives/auto-focus/autofocus.options.ts index 3631ae9ad2926..e587e64dc18f8 100644 --- a/projects/cdk/directives/auto-focus/autofocus.options.ts +++ b/projects/cdk/directives/auto-focus/autofocus.options.ts @@ -14,10 +14,12 @@ export interface TuiAutofocusHandler { export interface TuiAutofocusOptions { readonly delay: number; + readonly query: string; } export const TUI_AUTOFOCUS_DEFAULT_OPTIONS: TuiAutofocusOptions = { delay: NaN, // NaN = no delay/sync + query: 'input,textarea', }; export const TUI_AUTOFOCUS_OPTIONS = tuiCreateToken(TUI_AUTOFOCUS_DEFAULT_OPTIONS); @@ -46,10 +48,19 @@ export const TUI_AUTOFOCUS_PROVIDERS = [ zone: NgZone, win: Window, isIos: boolean, + options: TuiAutofocusOptions, ) => isIos - ? new TuiIosAutofocusHandler(el, renderer, zone, win) - : new TuiDefaultAutofocusHandler(el, animationFrame$, zone), - deps: [ElementRef, WA_ANIMATION_FRAME, Renderer2, NgZone, WA_WINDOW, TUI_IS_IOS], + ? new TuiIosAutofocusHandler(el, renderer, zone, win, options) + : new TuiDefaultAutofocusHandler(el, animationFrame$, zone, options), + deps: [ + ElementRef, + WA_ANIMATION_FRAME, + Renderer2, + NgZone, + WA_WINDOW, + TUI_IS_IOS, + TUI_AUTOFOCUS_OPTIONS, + ], }, ]; diff --git a/projects/cdk/directives/auto-focus/handlers/abstract.handler.ts b/projects/cdk/directives/auto-focus/handlers/abstract.handler.ts index f6ff0e75c84fe..f5c5c4995c90e 100644 --- a/projects/cdk/directives/auto-focus/handlers/abstract.handler.ts +++ b/projects/cdk/directives/auto-focus/handlers/abstract.handler.ts @@ -1,16 +1,19 @@ import type {ElementRef} from '@angular/core'; -import type {TuiAutofocusHandler} from '../autofocus.options'; +import type {TuiAutofocusHandler, TuiAutofocusOptions} from '../autofocus.options'; export abstract class AbstractTuiAutofocusHandler implements TuiAutofocusHandler { - constructor(protected readonly el: ElementRef) {} + constructor( + protected readonly el: ElementRef, + protected readonly options: TuiAutofocusOptions, + ) {} public abstract setFocus(): void; protected get element(): HTMLElement { // TODO: Remove when legacy controls are dropped const el = this.el.nativeElement.tagName.includes('-') - ? this.el.nativeElement.querySelector('input,textarea') + ? this.el.nativeElement.querySelector(this.options.query) : this.el.nativeElement; return el || this.el.nativeElement; diff --git a/projects/cdk/directives/auto-focus/handlers/default.handler.ts b/projects/cdk/directives/auto-focus/handlers/default.handler.ts index 505a4825a829a..81ee57b71c98e 100644 --- a/projects/cdk/directives/auto-focus/handlers/default.handler.ts +++ b/projects/cdk/directives/auto-focus/handlers/default.handler.ts @@ -3,6 +3,7 @@ import {tuiZonefreeScheduler} from '@taiga-ui/cdk/observables'; import type {Observable} from 'rxjs'; import {map, race, skipWhile, take, throttleTime, timer} from 'rxjs'; +import type {TuiAutofocusOptions} from '../autofocus.options'; import {AbstractTuiAutofocusHandler} from './abstract.handler'; const TIMEOUT = 1000; @@ -13,14 +14,15 @@ export class TuiDefaultAutofocusHandler extends AbstractTuiAutofocusHandler { el: ElementRef, private readonly animationFrame$: Observable, private readonly zone: NgZone, + options: TuiAutofocusOptions, ) { - super(el); + super(el, options); } public setFocus(): void { if (this.isTextFieldElement) { race( - timer(TIMEOUT), + timer(this.options.delay || TIMEOUT), this.animationFrame$.pipe( throttleTime(100, tuiZonefreeScheduler(this.zone)), map(() => this.element.closest(NG_ANIMATION_SELECTOR)), diff --git a/projects/cdk/directives/auto-focus/handlers/ios.handler.ts b/projects/cdk/directives/auto-focus/handlers/ios.handler.ts index b53523be68b47..6c4e0f80dd43e 100644 --- a/projects/cdk/directives/auto-focus/handlers/ios.handler.ts +++ b/projects/cdk/directives/auto-focus/handlers/ios.handler.ts @@ -1,6 +1,7 @@ import type {ElementRef, NgZone, Renderer2} from '@angular/core'; import {tuiIsPresent, tuiPx} from '@taiga-ui/cdk/utils'; +import type {TuiAutofocusOptions} from '../autofocus.options'; import {AbstractTuiAutofocusHandler} from './abstract.handler'; const TEXTFIELD_ATTRS = [ @@ -22,8 +23,9 @@ export class TuiIosAutofocusHandler extends AbstractTuiAutofocusHandler { private readonly renderer: Renderer2, private readonly zone: NgZone, private readonly win: Window, + options: TuiAutofocusOptions, ) { - super(el); + super(el, options); this.patchCssStyles(); } diff --git a/projects/cdk/directives/auto-focus/test/auto-focus.directive.spec.ts b/projects/cdk/directives/auto-focus/test/auto-focus.directive.spec.ts index 36e3044a971a6..44e5e5dff271a 100644 --- a/projects/cdk/directives/auto-focus/test/auto-focus.directive.spec.ts +++ b/projects/cdk/directives/auto-focus/test/auto-focus.directive.spec.ts @@ -9,8 +9,10 @@ import { import type {ComponentFixture} from '@angular/core/testing'; import {fakeAsync, TestBed, tick} from '@angular/core/testing'; import {WA_WINDOW} from '@ng-web-apis/common'; +import type {TuiAutofocusOptions} from '@taiga-ui/cdk'; import { TUI_AUTOFOCUS_HANDLER, + TUI_AUTOFOCUS_OPTIONS, TuiAutoFocus, TuiIosAutofocusHandler, tuiIsNativeFocused, @@ -86,8 +88,15 @@ describe('TuiAutoFocus directive', () => { renderer: Renderer2, zone: NgZone, win: Window, - ) => new TuiIosAutofocusHandler(el, renderer, zone, win), - deps: [ElementRef, Renderer2, NgZone, WA_WINDOW], + options: TuiAutofocusOptions, + ) => new TuiIosAutofocusHandler(el, renderer, zone, win, options), + deps: [ + ElementRef, + Renderer2, + NgZone, + WA_WINDOW, + TUI_AUTOFOCUS_OPTIONS, + ], }, ], });