diff --git a/projects/addon-commerce/components/input-card-grouped/input-card-grouped.component.ts b/projects/addon-commerce/components/input-card-grouped/input-card-grouped.component.ts index 1c21fbcc2ef7..ae5eed52a571 100644 --- a/projects/addon-commerce/components/input-card-grouped/input-card-grouped.component.ts +++ b/projects/addon-commerce/components/input-card-grouped/input-card-grouped.component.ts @@ -28,7 +28,7 @@ import { AbstractTuiNullableControl, isNativeFocusedIn, TUI_FOCUSABLE_ITEM_ACCESSOR, - tuiAssertIsHTMLElement, + tuiAssertIsElement, TuiBooleanHandler, TuiCreditCardAutofillName, tuiDefaultProp, @@ -385,7 +385,7 @@ export class TuiInputCardGroupedComponent } onMouseDown(event: MouseEvent): void { - tuiAssertIsHTMLElement(event.target); + tuiAssertIsElement(event.target); if (event.target.matches(`input`)) { return; @@ -396,7 +396,7 @@ export class TuiInputCardGroupedComponent } onScroll({currentTarget}: Event): void { - tuiAssertIsHTMLElement(currentTarget); + tuiAssertIsElement(currentTarget); currentTarget.scrollLeft = 0; } diff --git a/projects/addon-editor/components/editor/editor.component.ts b/projects/addon-editor/components/editor/editor.component.ts index d7d1b42b143a..31c15f4ae575 100644 --- a/projects/addon-editor/components/editor/editor.component.ts +++ b/projects/addon-editor/components/editor/editor.component.ts @@ -28,7 +28,7 @@ import { setNativeFocused, TUI_FOCUSABLE_ITEM_ACCESSOR, tuiAssert, - tuiAssertIsHTMLElement, + tuiAssertIsElement, TuiBooleanHandler, tuiDefaultProp, TuiDestroyService, @@ -290,7 +290,7 @@ export class TuiEditorComponent extends AbstractTuiControl implements On return; } - tuiAssertIsHTMLElement(suitableNode); + tuiAssertIsElement(suitableNode); const element = suitableNode.closest(selector); diff --git a/projects/cdk/classes/assert.ts b/projects/cdk/classes/assert.ts index 47eae291b85c..804ca1fa3cf4 100644 --- a/projects/cdk/classes/assert.ts +++ b/projects/cdk/classes/assert.ts @@ -11,19 +11,8 @@ export const tuiAssert = { type PossibleNode = Node | Element | EventTarget | null; -// TODO: remove `DefaultView` in v3.0 -// TS 3.8 Property 'Element' does not exist on type 'Window'. -interface DefaultView { - Element: typeof Node; - HTMLElement: typeof Node; - HTMLDocument: typeof Node; -} - -// TODO: replace `HTMLElement` to `Element` in v3.0 -// TS 3.8 Argument of type Argument of type 'TuiNativeFocusableElement | HTMLElement' is not assignable to parameter of type 'HTMLElement'. -export function tuiAssertIsHTMLElement(node?: PossibleNode): asserts node is HTMLElement { - const defaultView = (node as Node)?.ownerDocument - ?.defaultView as unknown as DefaultView; +export function tuiAssertIsElement(node?: PossibleNode): asserts node is Element { + const defaultView = (node as Node)?.ownerDocument?.defaultView; const isElement = !!defaultView && (node instanceof defaultView.Element || node instanceof defaultView.HTMLDocument); diff --git a/projects/cdk/directives/hovered/hovered.directive.ts b/projects/cdk/directives/hovered/hovered.directive.ts index 83689fdffc43..0b3a9288a43c 100644 --- a/projects/cdk/directives/hovered/hovered.directive.ts +++ b/projects/cdk/directives/hovered/hovered.directive.ts @@ -1,35 +1,15 @@ -import {Directive, EventEmitter, HostListener, Output} from '@angular/core'; -import {tuiAssertIsHTMLElement} from '@taiga-ui/cdk/classes'; -import {shouldCall} from '@tinkoff/ng-event-plugins'; +import {Directive, Inject} from '@angular/core'; +import {Observable} from 'rxjs'; -// eslint-disable-next-line @typescript-eslint/naming-convention -export function movedOut({currentTarget, relatedTarget}: MouseEvent): boolean { - if (!relatedTarget) { - return true; - } - - tuiAssertIsHTMLElement(currentTarget); - tuiAssertIsHTMLElement(relatedTarget); - - return !currentTarget.contains(relatedTarget); -} +import {TuiHoveredService} from './hovered.service'; @Directive({ - selector: `[tuiHoveredChange]`, + selector: '[tuiHoveredChange]', + outputs: ['tuiHoveredChange'], + providers: [TuiHoveredService], }) export class TuiHoveredDirective { - @Output() - readonly tuiHoveredChange = new EventEmitter(); - - @HostListener(`mouseenter`) - onHover(): void { - this.tuiHoveredChange.emit(true); - } - - @shouldCall(movedOut) - @HostListener(`mouseout.init`, [`$event`]) - @HostListener(`mouseout.silent`, [`$event`]) - onOut(_: MouseEvent): void { - this.tuiHoveredChange.emit(false); - } + constructor( + @Inject(TuiHoveredService) readonly tuiHoveredChange: Observable, + ) {} } diff --git a/projects/cdk/directives/hovered/hovered.service.ts b/projects/cdk/directives/hovered/hovered.service.ts new file mode 100644 index 000000000000..10022172771a --- /dev/null +++ b/projects/cdk/directives/hovered/hovered.service.ts @@ -0,0 +1,32 @@ +import {ElementRef, Inject, Injectable, NgZone} from '@angular/core'; +import {tuiAssertIsElement} from '@taiga-ui/cdk/classes'; +import {tuiTypedFromEvent, tuiZoneOptimized} from '@taiga-ui/cdk/observables'; +import {merge, Observable} from 'rxjs'; +import {distinctUntilChanged, filter, mapTo} from 'rxjs/operators'; + +function movedOut({currentTarget, relatedTarget}: MouseEvent): boolean { + tuiAssertIsElement(currentTarget); + tuiAssertIsElement(relatedTarget); + + return !currentTarget.contains(relatedTarget); +} + +@Injectable() +export class TuiHoveredService extends Observable { + private readonly stream$ = merge( + tuiTypedFromEvent(this.elementRef.nativeElement, 'mouseenter').pipe(mapTo(true)), + tuiTypedFromEvent(this.elementRef.nativeElement, 'mouseleave').pipe(mapTo(false)), + // Hello, Safari + tuiTypedFromEvent(this.elementRef.nativeElement, 'mouseout').pipe( + filter(movedOut), + mapTo(false), + ), + ).pipe(distinctUntilChanged(), tuiZoneOptimized(this.ngZone)); + + constructor( + @Inject(ElementRef) private readonly elementRef: ElementRef, + @Inject(NgZone) private readonly ngZone: NgZone, + ) { + super(subscriber => this.stream$.subscribe(subscriber)); + } +} diff --git a/projects/cdk/directives/hovered/index.ts b/projects/cdk/directives/hovered/index.ts index 4263d6a78a8a..498b9b463123 100644 --- a/projects/cdk/directives/hovered/index.ts +++ b/projects/cdk/directives/hovered/index.ts @@ -1,2 +1,3 @@ export * from './hovered.directive'; export * from './hovered.module'; +export * from './hovered.service'; diff --git a/projects/cdk/services/hovered.service.ts b/projects/cdk/services/hovered.service.ts deleted file mode 100644 index 6d64cc89d564..000000000000 --- a/projects/cdk/services/hovered.service.ts +++ /dev/null @@ -1,54 +0,0 @@ -import {DOCUMENT} from '@angular/common'; -import {Inject, Injectable, NgZone} from '@angular/core'; -import {tuiZoneOptimized, typedFromEvent} from '@taiga-ui/cdk/observables'; -import {getActualTarget} from '@taiga-ui/cdk/utils/dom'; -import {merge, Observable} from 'rxjs'; -import { - distinctUntilChanged, - filter, - mapTo, - startWith, - switchMap, - take, -} from 'rxjs/operators'; - -/** @deprecated TODO remove in v3.0 */ -// @dynamic -@Injectable({ - providedIn: `root`, -}) -export class TuiHoveredService { - private readonly documentEvents$: Observable; - - constructor( - @Inject(DOCUMENT) documentRef: Document, - @Inject(NgZone) private readonly ngZone: NgZone, - ) { - this.documentEvents$ = merge( - typedFromEvent(documentRef, `mousemove`), - typedFromEvent(documentRef, `touchstart`, {capture: true}), - ); - } - - createHovered$( - target: Element, - options: AddEventListenerOptions = {passive: true}, - ): Observable { - return merge( - typedFromEvent(target, `mouseenter`, options), - typedFromEvent(target, `touchstart`, options), - ).pipe( - switchMap(() => - merge( - typedFromEvent(target, `mouseleave`, options), - this.documentEvents$.pipe( - filter(event => !target.contains(getActualTarget(event))), - tuiZoneOptimized(this.ngZone), - take(1), - ), - ).pipe(mapTo(false), startWith(true)), - ), - distinctUntilChanged(), - ); - } -} diff --git a/projects/cdk/services/index.ts b/projects/cdk/services/index.ts index fb70d457f40f..fcc458e03a9a 100644 --- a/projects/cdk/services/index.ts +++ b/projects/cdk/services/index.ts @@ -1,7 +1,6 @@ export * from './destroy.service'; export * from './directive-styles.service'; export * from './focus-visible.service'; -export * from './hovered.service'; export * from './id.service'; export * from './obscured.service'; export * from './pan.service'; diff --git a/projects/cdk/utils/focus/get-closest-keyboard-focusable.ts b/projects/cdk/utils/focus/get-closest-keyboard-focusable.ts index 292aab830868..78f1487db5ea 100644 --- a/projects/cdk/utils/focus/get-closest-keyboard-focusable.ts +++ b/projects/cdk/utils/focus/get-closest-keyboard-focusable.ts @@ -15,7 +15,7 @@ import {isNativeMouseFocusable} from './is-native-mouse-focusable'; */ // eslint-disable-next-line @typescript-eslint/naming-convention export function getClosestFocusable( - initial: HTMLElement, + initial: Element, prev: boolean = false, root: Node, keyboard: boolean = true, @@ -43,7 +43,8 @@ export function getClosestFocusable( initial = treeWalker.currentNode; } - if (check(initial)) { + // TODO: iframe warning + if (check(initial) && initial instanceof HTMLElement) { return initial; } } diff --git a/projects/core/components/button/button.component.ts b/projects/core/components/button/button.component.ts index bbfe1133b5ec..d75d615236ce 100644 --- a/projects/core/components/button/button.component.ts +++ b/projects/core/components/button/button.component.ts @@ -40,6 +40,7 @@ import {TUI_BUTTON_OPTIONS, TuiButtonOptions} from './button-options'; useExisting: forwardRef(() => TuiButtonComponent), }, TuiDestroyService, + TuiHoveredService, TuiFocusVisibleService, ], }) @@ -92,7 +93,6 @@ export class TuiButtonComponent super(); hoveredService - .createHovered$(elementRef.nativeElement) .pipe(watch(changeDetectorRef), takeUntil(destroy$)) .subscribe(hovered => { this.updateHovered(hovered); diff --git a/projects/core/components/data-list/data-list.component.ts b/projects/core/components/data-list/data-list.component.ts index 9e73bb1e0579..b095179f74f1 100644 --- a/projects/core/components/data-list/data-list.component.ts +++ b/projects/core/components/data-list/data-list.component.ts @@ -17,7 +17,7 @@ import { isPresent, itemsQueryListObservable, setNativeMouseFocused, - tuiAssertIsHTMLElement, + tuiAssertIsElement, tuiDefaultProp, tuiMoveFocus, tuiPure, @@ -34,9 +34,9 @@ import {TuiOptionComponent} from './option/option.component'; // TODO: Consider aria-activedescendant for proper accessibility implementation // @dynamic @Component({ - selector: `tui-data-list`, - templateUrl: `./data-list.template.html`, - styleUrls: [`./data-list.style.less`], + selector: 'tui-data-list', + templateUrl: './data-list.template.html', + styleUrls: ['./data-list.style.less'], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [ @@ -53,13 +53,13 @@ export class TuiDataListComponent implements TuiDataListAccessor { private origin?: HTMLElement; @Input() - @HostBinding(`attr.role`) + @HostBinding('attr.role') @tuiDefaultProp() - role: TuiDataListRole = `listbox`; + role: TuiDataListRole = 'listbox'; @Input() @tuiDefaultProp() - emptyContent: PolymorpheusContent = ``; + emptyContent: PolymorpheusContent = ''; constructor( @Inject(ElementRef) private readonly elementRef: ElementRef, @@ -72,18 +72,18 @@ export class TuiDataListComponent implements TuiDataListAccessor { return itemsQueryListObservable(this.options).pipe(map(({length}) => !length)); } - @HostListener(`focusin`, [`$event.relatedTarget`, `$event.currentTarget`]) + @HostListener('focusin', ['$event.relatedTarget', '$event.currentTarget']) onFocusIn(relatedTarget: HTMLElement, currentTarget: HTMLElement): void { if (!currentTarget.contains(relatedTarget) && !this.origin) { this.origin = relatedTarget; } } - @HostListener(`mousedown.prevent`) + @HostListener('mousedown.prevent') noop(): void {} - @HostListener(`keydown.arrowDown.prevent`, [`$event.target`, `1`]) - @HostListener(`keydown.arrowUp.prevent`, [`$event.target`, `-1`]) + @HostListener('keydown.arrowDown.prevent', ['$event.target', '1']) + @HostListener('keydown.arrowUp.prevent', ['$event.target', '-1']) onKeyDownArrow(current: HTMLElement, step: number): void { const {elements} = this; @@ -91,11 +91,9 @@ export class TuiDataListComponent implements TuiDataListAccessor { } // TODO: Consider aria-activedescendant for proper accessibility implementation - @HostListener(`wheel.silent.passive`) - @HostListener(`mouseleave`, [`$event.target`]) - handleFocusLossIfNecessary( - element: HTMLElement = this.elementRef.nativeElement, - ): void { + @HostListener('wheel.silent.passive') + @HostListener('mouseleave', ['$event.target']) + handleFocusLossIfNecessary(element: Element = this.elementRef.nativeElement): void { if (this.origin && isNativeFocusedIn(element)) { setNativeMouseFocused(this.origin, true, true); } @@ -110,7 +108,7 @@ export class TuiDataListComponent implements TuiDataListAccessor { } onFocus({target}: Event, top: boolean): void { - tuiAssertIsHTMLElement(target); + tuiAssertIsElement(target); const {elements} = this; @@ -119,6 +117,6 @@ export class TuiDataListComponent implements TuiDataListAccessor { } private get elements(): readonly HTMLElement[] { - return Array.from(this.elementRef.nativeElement.querySelectorAll(`[tuiOption]`)); + return Array.from(this.elementRef.nativeElement.querySelectorAll('[tuiOption]')); } } diff --git a/projects/core/components/dropdown-box/dropdown-box.component.ts b/projects/core/components/dropdown-box/dropdown-box.component.ts index d5c8595c7f4e..3b38bcbec875 100644 --- a/projects/core/components/dropdown-box/dropdown-box.component.ts +++ b/projects/core/components/dropdown-box/dropdown-box.component.ts @@ -16,7 +16,7 @@ import { inRange, POLLING_TIME, TuiActiveZoneDirective, - tuiAssertIsHTMLElement, + tuiAssertIsElement, TuiDestroyService, TuiDropdownHostComponent, TuiOverscrollMode, @@ -380,7 +380,7 @@ export class TuiDropdownBoxComponent implements AfterViewChecked { const {ownerDocument} = host; const root = ownerDocument ? ownerDocument.body : host; - tuiAssertIsHTMLElement(host); + tuiAssertIsElement(host); let focusable = getClosestFocusable(host, previous, root); diff --git a/projects/core/components/hints-host/hints-host.style.less b/projects/core/components/hints-host/hints-host.style.less index 112f02a45db5..ded1f69cb0fa 100644 --- a/projects/core/components/hints-host/hints-host.style.less +++ b/projects/core/components/hints-host/hints-host.style.less @@ -2,7 +2,7 @@ :host { position: fixed; - bottom: 0; + top: 0; left: 0; width: 100%; height: 0; diff --git a/projects/core/components/hosted-dropdown/test/hosted-dropdown.component.spec.ts b/projects/core/components/hosted-dropdown/test/hosted-dropdown.component.spec.ts index 1d334e989226..4fe39d46b6ea 100644 --- a/projects/core/components/hosted-dropdown/test/hosted-dropdown.component.spec.ts +++ b/projects/core/components/hosted-dropdown/test/hosted-dropdown.component.spec.ts @@ -1,7 +1,7 @@ import {Component, DebugElement, ViewChild} from '@angular/core'; import {ComponentFixture, TestBed} from '@angular/core/testing'; import {NoopAnimationsModule} from '@angular/platform-browser/animations'; -import {tuiAssertIsHTMLElement} from '@taiga-ui/cdk'; +import {tuiAssertIsElement} from '@taiga-ui/cdk'; import {configureTestSuite, tuiDispatchOnActive, TuiPageObject} from '@taiga-ui/testing'; import {TuiTextfieldControllerModule} from '../../../directives'; @@ -13,7 +13,7 @@ import {TuiPrimitiveTextfieldModule} from '../../primitive-textfield/primitive-t import {TuiRootModule} from '../../root/root.module'; import {TuiHostedDropdownModule} from '../hosted-dropdown.module'; -describe(`TuiHostedDropdown`, () => { +describe('TuiHostedDropdown', () => { @Component({ template: ` @@ -77,30 +77,30 @@ describe(`TuiHostedDropdown`, () => { @ViewChild(TuiButtonComponent) tuiButton!: TuiButtonComponent; - @ViewChild(`host`, {read: TuiButtonComponent}) + @ViewChild('host', {read: TuiButtonComponent}) target!: TuiButtonComponent; open = false; - items = [`Item 1`, `Item 2`]; - mode: 'default' | 'input' | 'targeted' | 'can-not-open' = `default`; + items = ['Item 1', 'Item 2']; + mode: 'default' | 'input' | 'targeted' | 'can-not-open' = 'default'; canOpen = true; escCatched = false; get input(): boolean { - return this.mode === `input`; + return this.mode === 'input'; } get default(): boolean { - return this.mode === `default`; + return this.mode === 'default'; } get targeted(): boolean { - return this.mode === `targeted`; + return this.mode === 'targeted'; } get canNotOpen(): boolean { - return this.mode === `can-not-open`; + return this.mode === 'can-not-open'; } onEsc(): void { @@ -134,25 +134,21 @@ describe(`TuiHostedDropdown`, () => { pageObject = new TuiPageObject(fixture); fixture.detectChanges(); - const element = document.querySelector(`#native-button`); - - tuiAssertIsHTMLElement(element); - - nativeButton = element; + nativeButton = document.querySelector('#native-button') as HTMLElement; }); - describe(`Buttons`, () => { - it(`The first element to be focused is the host, clicking on it opens a dropdown`, () => { + describe('Buttons', () => { + it('The first element to be focused is the host, clicking on it opens a dropdown', () => { nativeButton.click(); fixture.detectChanges(); expect(getItems().length).toBe(2); }); - it(`Clicking on another button does not open the dropdown`, () => { + it('Clicking on another button does not open the dropdown', () => { const element = testComponent.tuiButton.nativeFocusableElement; - tuiAssertIsHTMLElement(element); + tuiAssertIsElement(element); element.click(); fixture.detectChanges(); @@ -160,66 +156,66 @@ describe(`TuiHostedDropdown`, () => { expect(getItems().length).toBe(0); }); - it(`Down arrow opens a dropdown`, () => { + it('Down arrow opens a dropdown', () => { nativeButton.focus(); - tuiDispatchOnActive(`arrowDown`, fixture); + tuiDispatchOnActive('arrowDown', fixture); expect(getItems().length).toBe(2); }); - it(`Down arrow on another button does not open the dropdown`, () => { + it('Down arrow on another button does not open the dropdown', () => { testComponent.tuiButton.nativeFocusableElement!.focus(); - tuiDispatchOnActive(`arrowDown`, fixture); + tuiDispatchOnActive('arrowDown', fixture); expect(getItems().length).toBe(0); }); - it(`Down arrow moves focus to dropdown`, () => { + it('Down arrow moves focus to dropdown', () => { nativeButton.focus(); - tuiDispatchOnActive(`arrowDown`, fixture); - tuiDispatchOnActive(`arrowDown`, fixture); + tuiDispatchOnActive('arrowDown', fixture); + tuiDispatchOnActive('arrowDown', fixture); expect(document.activeElement).toBe(getItems()[0].nativeElement); }); - it(`Escape closes the dropdown`, () => { + it('Escape closes the dropdown', () => { nativeButton.focus(); - tuiDispatchOnActive(`arrowDown`, fixture); - tuiDispatchOnActive(`escape`, fixture); + tuiDispatchOnActive('arrowDown', fixture); + tuiDispatchOnActive('escape', fixture); expect(getItems().length).toBe(0); }); - it(`Escape in the dropdown closes it and brings focus to the host`, () => { + it('Escape in the dropdown closes it and brings focus to the host', () => { nativeButton.focus(); - tuiDispatchOnActive(`arrowDown`, fixture); - tuiDispatchOnActive(`arrowDown`, fixture); - tuiDispatchOnActive(`escape`, fixture); + tuiDispatchOnActive('arrowDown', fixture); + tuiDispatchOnActive('arrowDown', fixture); + tuiDispatchOnActive('escape', fixture); expect(getItems().length).toBe(0); expect(document.activeElement).toBe(nativeButton); }); - it(`Loss of focus closes the dropdown`, () => { + it('Loss of focus closes the dropdown', () => { nativeButton.focus(); - tuiDispatchOnActive(`arrowDown`, fixture); - tuiDispatchOnActive(`arrowDown`, fixture); + tuiDispatchOnActive('arrowDown', fixture); + tuiDispatchOnActive('arrowDown', fixture); testComponent.tuiButton.nativeFocusableElement!.focus(); fixture.detectChanges(); expect(getItems().length).toBe(0); }); - it(`Down arrow does not open dropdown if canOpen === false`, () => { + it('Down arrow does not open dropdown if canOpen === false', () => { testComponent.canOpen = false; fixture.detectChanges(); nativeButton.focus(); - tuiDispatchOnActive(`arrowDown`, fixture); + tuiDispatchOnActive('arrowDown', fixture); expect(getItems().length).toBe(0); }); - it(`Click does not open the dropdown if canOpen === false`, () => { + it('Click does not open the dropdown if canOpen === false', () => { testComponent.canOpen = false; fixture.detectChanges(); nativeButton.click(); @@ -229,16 +225,16 @@ describe(`TuiHostedDropdown`, () => { }); }); - describe(`Entry field`, () => { + describe('Entry field', () => { beforeEach(() => { - testComponent.mode = `input`; + testComponent.mode = 'input'; fixture.detectChanges(); }); - it(`Clicking on the host does not open the dropdown`, () => { + it('Clicking on the host does not open the dropdown', () => { const element = testComponent.tuiTextfield.nativeFocusableElement; - tuiAssertIsHTMLElement(element); + tuiAssertIsElement(element); element.click(); fixture.detectChanges(); @@ -246,18 +242,18 @@ describe(`TuiHostedDropdown`, () => { expect(getItems().length).toBe(0); }); - it(`Down arrow opens a dropdown`, () => { + it('Down arrow opens a dropdown', () => { testComponent.tuiTextfield.nativeFocusableElement!.focus(); - tuiDispatchOnActive(`arrowDown`, fixture); + tuiDispatchOnActive('arrowDown', fixture); expect(getItems().length).toBe(2); }); - it(`Updating items brings focus to input`, () => { + it('Updating items brings focus to input', () => { testComponent.tuiTextfield.nativeFocusableElement!.focus(); - tuiDispatchOnActive(`arrowDown`, fixture); + tuiDispatchOnActive('arrowDown', fixture); - testComponent.items = [`Item 3`, `Item 4`]; + testComponent.items = ['Item 3', 'Item 4']; expect(document.activeElement).toBe( testComponent.tuiTextfield.nativeFocusableElement, @@ -265,34 +261,34 @@ describe(`TuiHostedDropdown`, () => { }); }); - describe(`Can not open`, () => { + describe('Can not open', () => { beforeEach(() => { - testComponent.mode = `can-not-open`; + testComponent.mode = 'can-not-open'; fixture.detectChanges(); }); - it(`Esc event should bubble up if content is empty`, () => { + it('Esc event should bubble up if content is empty', () => { testComponent.open = true; testComponent.canOpen = false; fixture.detectChanges(); testComponent.tuiTextfield.nativeFocusableElement!.focus(); - tuiDispatchOnActive(`escape`, fixture); + tuiDispatchOnActive('escape', fixture); expect(testComponent.escCatched).toBe(true); }); }); - describe(`Direct Host Specification`, () => { + describe('Direct Host Specification', () => { beforeEach(() => { - testComponent.mode = `targeted`; + testComponent.mode = 'targeted'; fixture.detectChanges(); }); - it(`Clicking on the first focused element does not open the dropdown`, () => { + it('Clicking on the first focused element does not open the dropdown', () => { const element = testComponent.tuiButton.nativeFocusableElement; - tuiAssertIsHTMLElement(element); + tuiAssertIsElement(element); element.click(); fixture.detectChanges(); @@ -300,10 +296,10 @@ describe(`TuiHostedDropdown`, () => { expect(getItems().length).toBe(0); }); - it(`An element with tuiHostedDropdownHost is used as a host, clicking on it opens a dropdown`, () => { + it('An element with tuiHostedDropdownHost is used as a host, clicking on it opens a dropdown', () => { const element = testComponent.target.nativeFocusableElement; - tuiAssertIsHTMLElement(element); + tuiAssertIsElement(element); element.click(); fixture.detectChanges(); @@ -313,6 +309,6 @@ describe(`TuiHostedDropdown`, () => { }); function getItems(): DebugElement[] { - return pageObject.getAllByAutomationId(`tui-menu-items__item`); + return pageObject.getAllByAutomationId('tui-menu-items__item'); } }); diff --git a/projects/core/constants/described-by.ts b/projects/core/constants/described-by.ts new file mode 100644 index 000000000000..7aef6c14ee2f --- /dev/null +++ b/projects/core/constants/described-by.ts @@ -0,0 +1 @@ +export const DESCRIBED_BY = '_described-by'; diff --git a/projects/core/constants/index.ts b/projects/core/constants/index.ts index 364bccd0d98a..2cd7f50bcb18 100644 --- a/projects/core/constants/index.ts +++ b/projects/core/constants/index.ts @@ -2,6 +2,7 @@ export * from './absolute-box-sizes'; export * from './decimal-symbols'; export * from './default-icons-path'; export * from './default-marker-handler'; +export * from './described-by'; export * from './editing-keys'; export * from './events'; export * from './mask-caret-trap'; diff --git a/projects/core/directives/described-by/described-by.directive.ts b/projects/core/directives/described-by/described-by.directive.ts index 77f401a63e58..62a880e5e59c 100644 --- a/projects/core/directives/described-by/described-by.directive.ts +++ b/projects/core/directives/described-by/described-by.directive.ts @@ -1,5 +1,6 @@ import {Directive, HostBinding, Inject, Input} from '@angular/core'; import {tuiDefaultProp} from '@taiga-ui/cdk'; +import {DESCRIBED_BY} from '@taiga-ui/core/constants'; import {TuiHintService} from '@taiga-ui/core/services'; import {Observable} from 'rxjs'; @@ -8,19 +9,17 @@ import { TUI_DESCRIBED_BY_SHOW, } from './described-by.providers'; -export const DESCRIBED_BY = `_described-by`; - /** * A directive linking focusable elements and hints for accessibility */ @Directive({ - selector: `[tuiDescribedBy]:not(ng-container)`, + selector: '[tuiDescribedBy]:not(ng-container)', providers: TUI_DESCRIBED_BY_PROVIDERS, }) export class TuiDescribedByDirective { @Input() @tuiDefaultProp() - tuiDescribedBy = ``; + tuiDescribedBy = ''; constructor( @Inject(TuiHintService) hintService: TuiHintService, @@ -39,7 +38,7 @@ export class TuiDescribedByDirective { }); } - @HostBinding(`attr.aria-describedby`) + @HostBinding('attr.aria-describedby') get computedDescribedBy(): string | null { return this.tuiDescribedBy ? this.tuiDescribedBy + DESCRIBED_BY : null; } diff --git a/projects/core/directives/hint/hint.directive.ts b/projects/core/directives/hint/hint.directive.ts index 5a13712f7c03..c618778b3d44 100644 --- a/projects/core/directives/hint/hint.directive.ts +++ b/projects/core/directives/hint/hint.directive.ts @@ -18,7 +18,7 @@ import { tuiRequiredSetter, } from '@taiga-ui/cdk'; import {AbstractTuiHint} from '@taiga-ui/core/abstract'; -import {DESCRIBED_BY} from '@taiga-ui/core/directives/described-by'; +import {DESCRIBED_BY} from '@taiga-ui/core/constants'; import {TuiHintService} from '@taiga-ui/core/services'; import {PolymorpheusContent} from '@tinkoff/ng-polymorpheus'; import {combineLatest, of, Subject} from 'rxjs'; @@ -34,11 +34,16 @@ import { import {TUI_HINT_OPTIONS, TuiHintOptions} from './hint-options'; -export const HINT_HOVERED_CLASS = `_hint_hovered`; +export const HINT_HOVERED_CLASS = '_hint_hovered'; @Directive({ - selector: `[tuiHint]:not(ng-container)`, - providers: [TuiObscuredService, TuiParentsScrollService, TuiDestroyService], + selector: '[tuiHint]:not(ng-container)', + providers: [ + TuiObscuredService, + TuiParentsScrollService, + TuiDestroyService, + TuiHoveredService, + ], }) export class TuiHintDirective extends AbstractTuiHint implements OnDestroy { @Input() @@ -62,7 +67,7 @@ export class TuiHintDirective extends AbstractTuiHint implements OnDestroy { set tuiHint(value: PolymorpheusContent | null) { if (!value) { this.hideTooltip(); - this.content = ``; + this.content = ''; return; } @@ -90,10 +95,7 @@ export class TuiHintDirective extends AbstractTuiHint implements OnDestroy { super(elementRef, hintService, activeZone, options); // @bad TODO: Use private provider - combineLatest( - hoveredService.createHovered$(elementRef.nativeElement), - this.componentHovered$.pipe(startWith(false)), - ) + combineLatest(hoveredService, this.componentHovered$.pipe(startWith(false))) .pipe( map( ([directiveHovered, componentHovered]) => @@ -107,7 +109,7 @@ export class TuiHintDirective extends AbstractTuiHint implements OnDestroy { ); }), switchMap(visible => - visible && this.mode !== `overflow` + visible && this.mode !== 'overflow' ? obscured$.pipe( map(obscured => !obscured), take(2), @@ -145,7 +147,7 @@ export class TuiHintDirective extends AbstractTuiHint implements OnDestroy { } protected showTooltip(): void { - if (this.content === ``) { + if (this.content === '') { return; } diff --git a/projects/core/directives/hint/test/hint.directive.spec.ts b/projects/core/directives/hint/test/hint.directive.spec.ts index 2d01d0965327..7cbc70b4fcfe 100644 --- a/projects/core/directives/hint/test/hint.directive.spec.ts +++ b/projects/core/directives/hint/test/hint.directive.spec.ts @@ -7,7 +7,7 @@ import { tick, } from '@angular/core/testing'; import {NoopAnimationsModule} from '@angular/platform-browser/animations'; -import {tuiAssertIsHTMLElement} from '@taiga-ui/cdk'; +import {tuiAssertIsElement} from '@taiga-ui/cdk'; import {TuiRootModule} from '@taiga-ui/core'; import {configureTestSuite} from '@taiga-ui/testing'; @@ -15,7 +15,7 @@ import {TuiHintModule} from '../hint.module'; type Hint = string | TemplateRef> | undefined | null; -describe(`Hint`, () => { +describe('Hint', () => { @Component({ template: ` @@ -41,7 +41,7 @@ describe(`Hint`, () => { ], }) class TestComponent { - hint: Hint = `Tooltip text`; + hint: Hint = 'Tooltip text'; } let fixture: ComponentFixture; @@ -60,42 +60,42 @@ describe(`Hint`, () => { }); beforeEach(() => { - document.body.style.margin = `0`; + document.body.style.margin = '0'; fixture = TestBed.createComponent(TestComponent); component = fixture.componentInstance; fixture.detectChanges(); }); - it(`Hint is not shown immediately`, () => { - getHost().dispatchEvent(new Event(`mouseenter`)); + it('Hint is not shown immediately', () => { + getHost().dispatchEvent(new Event('mouseenter')); fixture.detectChanges(); expect(getTooltip()).toBe(null); }); - describe(`Hint`, () => { + describe('Hint', () => { beforeEach(fakeAsync(() => { - getHost().dispatchEvent(new Event(`mouseenter`)); + getHost().dispatchEvent(new Event('mouseenter')); fixture.detectChanges(); tick(500); fixture.detectChanges(); discardPeriodicTasks(); })); - it(`is shown after 500ms`, async () => { + it('is shown after 500ms', async () => { await fixture.whenStable(); fixture.detectChanges(); - expect(getTooltip()!.textContent!.trim()).toBe(`Tooltip text`); + expect(getTooltip()!.textContent!.trim()).toBe('Tooltip text'); }); - it(`is hidden immediately if null is passed as content`, async () => { + it('is hidden immediately if null is passed as content', async () => { setHint(null); await fixture.whenStable(); expect(getTooltip()).toBeNull(); }); - it(`is hidden after pointer left host with 200ms delay`, fakeAsync(async () => { - getHost().dispatchEvent(new Event(`mouseleave`)); + it('is hidden after pointer left host with 200ms delay', fakeAsync(async () => { + getHost().dispatchEvent(new Event('mouseout')); fixture.detectChanges(); tick(200); fixture.detectChanges(); @@ -106,9 +106,9 @@ describe(`Hint`, () => { })); }); - describe(`Hint is not shown`, () => { - it(`when content is empty string`, fakeAsync(() => { - setHintThenEnterMouse(``); + describe('Hint is not shown', () => { + it('when content is empty string', fakeAsync(() => { + setHintThenEnterMouse(''); tick(500); fixture.detectChanges(); discardPeriodicTasks(); @@ -116,7 +116,7 @@ describe(`Hint`, () => { expect(getTooltip()).toBeNull(); })); - it(`when content is null`, fakeAsync(() => { + it('when content is null', fakeAsync(() => { setHintThenEnterMouse(null); tick(500); fixture.detectChanges(); @@ -128,21 +128,21 @@ describe(`Hint`, () => { function setHintThenEnterMouse(hint: Hint): void { setHint(hint); - getHost().dispatchEvent(new Event(`mouseenter`)); + getHost().dispatchEvent(new Event('mouseenter')); fixture.detectChanges(); } }); - function getHost(): HTMLElement { - const element = document.querySelector(`#hint-host`); + function getHost(): Element { + const element = document.querySelector('#hint-host'); - tuiAssertIsHTMLElement(element); + tuiAssertIsElement(element); return element; } function getTooltip(): Element | null { - return document.querySelector(`[automation-id=tui-hint-box__tooltip]`); + return document.querySelector('[automation-id=tui-hint-box__tooltip]'); } function setHint(hint: Hint): void { diff --git a/projects/core/directives/pointer-hint/pointer-hint.directive.ts b/projects/core/directives/pointer-hint/pointer-hint.directive.ts index c4b00fe82c7b..a73282239b92 100644 --- a/projects/core/directives/pointer-hint/pointer-hint.directive.ts +++ b/projects/core/directives/pointer-hint/pointer-hint.directive.ts @@ -22,8 +22,8 @@ import { import {TUI_POINTER_HINT_OPTIONS, TuiPointerHintOptions} from './pointer-hint-options'; @Directive({ - selector: `[tuiPointerHint]:not(ng-container)`, - providers: [TuiDestroyService], + selector: '[tuiPointerHint]:not(ng-container)', + providers: [TuiDestroyService, TuiHoveredService], }) export class TuiPointerHintDirective extends AbstractTuiHint { private currentMouseRect = this.mousePositionToClientRect(); @@ -44,7 +44,7 @@ export class TuiPointerHintDirective extends AbstractTuiHint { set tuiPointerHint(value: PolymorpheusContent | null) { if (!value) { this.hideTooltip(); - this.content = ``; + this.content = ''; return; } @@ -52,7 +52,7 @@ export class TuiPointerHintDirective extends AbstractTuiHint { this.content = value; } - content: PolymorpheusContent = ``; + content: PolymorpheusContent = ''; constructor( @Inject(ElementRef) elementRef: ElementRef, @@ -65,7 +65,7 @@ export class TuiPointerHintDirective extends AbstractTuiHint { ) { super(elementRef, hintService, null, options); - const hint$ = hoveredService.createHovered$(this.elementRef.nativeElement).pipe( + const hint$ = hoveredService.pipe( filter(() => !!this.content), startWith(false), distinctUntilChanged(), @@ -103,7 +103,7 @@ export class TuiPointerHintDirective extends AbstractTuiHint { private initMouseMoveSubscription(): void { const mouseMove$: Observable = typedFromEvent( this.elementRef.nativeElement, - `mousemove`, + 'mousemove', ); mouseMove$.pipe(takeUntil(this.destroy$)).subscribe(({clientX, clientY}) => { diff --git a/projects/core/interfaces/hint.ts b/projects/core/interfaces/hint.ts index 9e2996e729f0..0aa9deb0a4a5 100644 --- a/projects/core/interfaces/hint.ts +++ b/projects/core/interfaces/hint.ts @@ -1,8 +1,9 @@ import {TuiActiveZoneDirective} from '@taiga-ui/cdk'; -import {PolymorpheusComponent} from '@tinkoff/ng-polymorpheus'; +import {PolymorpheusComponent, PolymorpheusContent} from '@tinkoff/ng-polymorpheus'; export interface TuiHint { readonly id: string | null; readonly component: PolymorpheusComponent; + readonly content: PolymorpheusContent; readonly activeZone: TuiActiveZoneDirective | null; } diff --git a/projects/kit/abstract/slider/slider.ts b/projects/kit/abstract/slider/slider.ts index f199b67b5c0f..94be00834d60 100644 --- a/projects/kit/abstract/slider/slider.ts +++ b/projects/kit/abstract/slider/slider.ts @@ -15,7 +15,7 @@ import { quantize, round, setNativeFocused, - tuiAssertIsHTMLElement, + tuiAssertIsElement, tuiDefaultProp, TuiEventWith, TuiNativeFocusableElement, @@ -159,7 +159,7 @@ export abstract class AbstractTuiSlider this.pointerDown$ .pipe( map((event: MouseEvent | TouchEvent) => { - tuiAssertIsHTMLElement(event.currentTarget); + tuiAssertIsElement(event.currentTarget); const rect = event.currentTarget.getBoundingClientRect(); const clientX = diff --git a/projects/kit/components/multi-select/test/multi-select.component.spec.ts b/projects/kit/components/multi-select/test/multi-select.component.spec.ts index e94bf6a757d0..a13cf233fa8f 100644 --- a/projects/kit/components/multi-select/test/multi-select.component.spec.ts +++ b/projects/kit/components/multi-select/test/multi-select.component.spec.ts @@ -2,7 +2,6 @@ import {Component, DebugElement, ViewChild} from '@angular/core'; import {ComponentFixture, TestBed} from '@angular/core/testing'; import {FormControl, ReactiveFormsModule} from '@angular/forms'; import {NoopAnimationsModule} from '@angular/platform-browser/animations'; -import {tuiAssertIsHTMLElement} from '@taiga-ui/cdk'; import { TuiDataListModule, TuiHintControllerModule, @@ -17,8 +16,8 @@ import { } from '@taiga-ui/kit/components'; import {configureTestSuite, TuiNativeInputPO, TuiPageObject} from '@taiga-ui/testing'; -describe(`MultiSelect`, () => { - describe(`Basic`, () => { +describe('MultiSelect', () => { + describe('Basic', () => { let fixture: ComponentFixture; let testComponent: TestComponent; let pageObject: TuiPageObject; @@ -37,9 +36,9 @@ describe(`MultiSelect`, () => { } const items = [ - new User(`Marsi`, `Barsi`, `0`), - new User(`Water`, `Plea`, `2`), - new User(`Alexander`, `Inkin`, `3`), + new User('Marsi', 'Barsi', '0'), + new User('Water', 'Plea', '2'), + new User('Alexander', 'Inkin', '3'), ]; @Component({ @@ -90,26 +89,26 @@ describe(`MultiSelect`, () => { pageObject = new TuiPageObject(fixture); testComponent = fixture.componentInstance; - inputPO = new TuiNativeInputPO(fixture, `tui-input-tag__native`); + inputPO = new TuiNativeInputPO(fixture, 'tui-input-tag__native'); fixture.detectChanges(); }); - describe(`Field`, () => { - describe(`when you click on it`, () => { + describe('Field', () => { + describe('when you click on it', () => { beforeEach(() => { // Focus happens before click, after mousedown inputPO.focus(); }); - it(`opens a dropdown`, () => { + it('opens a dropdown', () => { getInputTag(pageObject).nativeElement.click(); fixture.detectChanges(); expect(getDropdown(pageObject)).not.toBeNull(); }); - describe(`does not open the dropdown`, () => { - it(`in readOnly mode`, () => { + describe('does not open the dropdown', () => { + it('in readOnly mode', () => { testComponent.readOnly = true; fixture.detectChanges(); getInputTag(pageObject).nativeElement.click(); @@ -118,7 +117,7 @@ describe(`MultiSelect`, () => { expect(getDropdown(pageObject)).toBeNull(); }); - it(`if control is disabled`, () => { + it('if control is disabled', () => { testComponent.control.disable(); fixture.detectChanges(); getInputTag(pageObject).nativeElement.click(); @@ -130,15 +129,15 @@ describe(`MultiSelect`, () => { }); }); - describe(`Arrow`, () => { - it(`Click on the arrow to open the dropdown`, () => { + describe('Arrow', () => { + it('Click on the arrow to open the dropdown', () => { getArrow(pageObject)?.nativeElement.click(); fixture.detectChanges(); expect(getDropdown(pageObject)).not.toBeNull(); }); - it(`Clicking the arrow again closes the dropdown`, () => { + it('Clicking the arrow again closes the dropdown', () => { getArrow(pageObject)?.nativeElement.click(); fixture.detectChanges(); getArrow(pageObject)?.nativeElement.click(); @@ -147,14 +146,14 @@ describe(`MultiSelect`, () => { expect(getDropdown(pageObject)).toBeNull(); }); - it(`There is exists interactive arrow in readOnly mode`, () => { + it('There is exists interactive arrow in readOnly mode', () => { testComponent.readOnly = true; fixture.detectChanges(); expect(getArrow(pageObject)?.nativeElement).toBeTruthy(); }); - it(`In disabled mode there is interactive arrow exists`, () => { + it('In disabled mode there is interactive arrow exists', () => { testComponent.control.disable(); fixture.detectChanges(); @@ -162,65 +161,65 @@ describe(`MultiSelect`, () => { }); }); - describe(`Keyboard`, () => { + describe('Keyboard', () => { beforeEach(() => { inputPO.focus(); }); - it(`Down arrow opens a dropdown`, () => { - inputPO.sendKeydown(`ArrowDown`); + it('Down arrow opens a dropdown', () => { + inputPO.sendKeydown('ArrowDown'); fixture.detectChanges(); expect(getDropdown(pageObject)).not.toBeNull(); }); - it(`Esc closes the dropdown`, () => { - inputPO.sendKeydown(`ArrowDown`); + it('Esc closes the dropdown', () => { + inputPO.sendKeydown('ArrowDown'); fixture.detectChanges(); - inputPO.sendKeydown(`Escape`); + inputPO.sendKeydown('Escape'); fixture.detectChanges(); expect(getDropdown(pageObject)).toBeNull(); }); - it(`Down arrow does not open dropdown in readOnly mode`, () => { + it('Down arrow does not open dropdown in readOnly mode', () => { testComponent.readOnly = true; fixture.detectChanges(); - inputPO.sendKeydown(`ArrowDown`); + inputPO.sendKeydown('ArrowDown'); fixture.detectChanges(); expect(getDropdown(pageObject)).toBeNull(); }); - it(`The repeated down arrow moves focus to the item`, () => { - inputPO.sendKeydown(`ArrowDown`); - inputPO.sendKeydown(`ArrowDown`); + it('The repeated down arrow moves focus to the item', () => { + inputPO.sendKeydown('ArrowDown'); + inputPO.sendKeydown('ArrowDown'); - expect(document.activeElement?.tagName.toLowerCase()).toBe(`button`); + expect(document.activeElement?.tagName.toLowerCase()).toBe('button'); }); - it(`Click to remove the selected item`, () => { - inputPO.sendKeydown(`ArrowDown`); - inputPO.sendKeydown(`ArrowDown`); - tuiAssertIsHTMLElement(document.activeElement); - document.activeElement.click(); + it('Click to remove the selected item', () => { + inputPO.sendKeydown('ArrowDown'); + inputPO.sendKeydown('ArrowDown'); + + (document.activeElement as HTMLElement).click(); expect(testComponent.control.value).toEqual([]); }); - it(`Click to select an unselected item`, () => { - inputPO.sendKeydown(`ArrowDown`); - inputPO.sendKeydown(`ArrowDown`); - tuiAssertIsHTMLElement(document.activeElement); - document.activeElement.click(); - document.activeElement.click(); + it('Click to select an unselected item', () => { + inputPO.sendKeydown('ArrowDown'); + inputPO.sendKeydown('ArrowDown'); + + (document.activeElement as HTMLElement).click(); + (document.activeElement as HTMLElement).click(); expect(testComponent.control.value).toEqual([items[0]]); }); }); }); - describe(`Change arrow mode`, () => { + describe('Change arrow mode', () => { let fixture: ComponentFixture; let testComponent: TestComponent; let pageObject: TuiPageObject; @@ -237,7 +236,7 @@ describe(`MultiSelect`, () => { } } - const items = [new User(`Alexander`, `Inkin`, `1`)]; + const items = [new User('Alexander', 'Inkin', '1')]; @Component({ template: ` @@ -283,7 +282,7 @@ describe(`MultiSelect`, () => { providers: [ { provide: TUI_ARROW_MODE, - useValue: {interactive: `☆`, disabled: `★`}, + useValue: {interactive: '☆', disabled: '★'}, }, ], }); @@ -297,7 +296,7 @@ describe(`MultiSelect`, () => { fixture.detectChanges(); }); - it(`switch arrow mode by disable or enable method`, () => { + it('switch arrow mode by disable or enable method', () => { testComponent.control.disable(); fixture.detectChanges(); @@ -312,13 +311,13 @@ describe(`MultiSelect`, () => { }); function getArrow(pageObject: TuiPageObject): DebugElement | null { - return pageObject.getByAutomationId(`tui-multi-select__arrow`); + return pageObject.getByAutomationId('tui-multi-select__arrow'); } function getInputTag(pageObject: TuiPageObject): DebugElement { - return pageObject.getByAutomationId(`tui-multi-select__input`)!; + return pageObject.getByAutomationId('tui-multi-select__input')!; } function getDropdown(pageObject: TuiPageObject): DebugElement | null { - return pageObject.getByAutomationId(`tui-multi-select__menu`); + return pageObject.getByAutomationId('tui-multi-select__menu'); } diff --git a/projects/kit/components/stepper/stepper.component.ts b/projects/kit/components/stepper/stepper.component.ts index b23c654594e2..67e0d5d68506 100644 --- a/projects/kit/components/stepper/stepper.component.ts +++ b/projects/kit/components/stepper/stepper.component.ts @@ -15,7 +15,7 @@ import { EMPTY_QUERY, getOriginalArrayFromQueryList, itemsQueryListObservable, - tuiAssertIsHTMLElement, + tuiAssertIsElement, tuiDefaultProp, tuiMoveFocus, tuiPure, @@ -115,11 +115,12 @@ export class TuiStepperComponent { } private moveFocus(current: EventTarget, step: number): void { - tuiAssertIsHTMLElement(current); + tuiAssertIsElement(current); const stepElements = this.getNativeElements(this.steps); + const index = stepElements.findIndex(item => item === current); - tuiMoveFocus(stepElements.indexOf(current), stepElements, step); + tuiMoveFocus(index, stepElements, step); } private scrollIntoView(targetStepIndex: number): void { diff --git a/projects/kit/components/tabs/tabs-with-more/tabs-with-more.component.ts b/projects/kit/components/tabs/tabs-with-more/tabs-with-more.component.ts index 04a4152b8981..dbc4278a18f4 100644 --- a/projects/kit/components/tabs/tabs-with-more/tabs-with-more.component.ts +++ b/projects/kit/components/tabs/tabs-with-more/tabs-with-more.component.ts @@ -20,7 +20,7 @@ import { setNativeFocused, toInt, TuiActiveZoneDirective, - tuiAssertIsHTMLElement, + tuiAssertIsElement, tuiClamp, TuiContextWithImplicit, tuiDefaultProp, @@ -157,7 +157,7 @@ export class TuiTabsWithMoreComponent implements AfterViewInit { } onArrowRight(event: Event): void { - tuiAssertIsHTMLElement(event.target); + tuiAssertIsElement(event.target); if (tuiIsNativeFocused(event.target)) { this.focusMore(); diff --git a/projects/kit/directives/highlight/test/highlight.directive.spec.ts b/projects/kit/directives/highlight/test/highlight.directive.spec.ts index 31a5fca406a7..f7ba53721380 100644 --- a/projects/kit/directives/highlight/test/highlight.directive.spec.ts +++ b/projects/kit/directives/highlight/test/highlight.directive.spec.ts @@ -1,11 +1,10 @@ import {Component} from '@angular/core'; import {TestBed} from '@angular/core/testing'; -import {tuiAssertIsHTMLElement} from '@taiga-ui/cdk'; import {configureTestSuite} from '@taiga-ui/testing'; import {TuiHighlightModule} from '../highlight.module'; -describe(`TuiHighlight directive`, () => { +describe('TuiHighlight directive', () => { @Component({ template: `
{ fixture.detectChanges(); }); - it(`Highlight is shown`, () => { - const element = document.querySelector(`#ica`)?.firstElementChild; + it('Highlight is shown', () => { + const element = document.querySelector('#ica')?.firstElementChild as HTMLElement; - tuiAssertIsHTMLElement(element); - - expect(element.style.display).toBe(`block`); + expect(element.style.display).toBe('block'); }); - it(`Highlight is not shown`, () => { - const element = document.querySelector(`#dong`)?.firstElementChild; - - tuiAssertIsHTMLElement(element); + it('Highlight is not shown', () => { + const element = document.querySelector('#dong')?.firstElementChild as HTMLElement; - expect(element.style.display).toBe(`none`); + expect(element.style.display).toBe('none'); }); - it(`Highlight color is yellow`, () => { - const element = document.querySelector(`#aaa`)?.firstElementChild; - - tuiAssertIsHTMLElement(element); + it('Highlight color is yellow', () => { + const element = document.querySelector('#aaa')?.firstElementChild as HTMLElement; - expect(element.style.background).toBe(`yellow`); + expect(element.style.background).toBe('yellow'); }); }); diff --git a/projects/kit/pipes/field-error/test/field-error-content-pipe.spec.ts b/projects/kit/pipes/field-error/test/field-error-content-pipe.spec.ts index 24962df75880..c61811d7c9a0 100644 --- a/projects/kit/pipes/field-error/test/field-error-content-pipe.spec.ts +++ b/projects/kit/pipes/field-error/test/field-error-content-pipe.spec.ts @@ -8,15 +8,15 @@ import { } from '@angular/core/testing'; import {FormControl, ReactiveFormsModule, Validators} from '@angular/forms'; import {NoopAnimationsModule} from '@angular/platform-browser/animations'; -import {tuiAssertIsHTMLElement} from '@taiga-ui/cdk'; +import {tuiAssertIsElement} from '@taiga-ui/cdk'; import {TuiHintModule, TuiRootModule} from '@taiga-ui/core'; import {TuiInputModule} from '@taiga-ui/kit/components'; import {TuiFieldErrorPipeModule} from '@taiga-ui/kit/pipes'; import {TUI_VALIDATION_ERRORS} from '@taiga-ui/kit/tokens'; import {configureTestSuite} from '@taiga-ui/testing'; -describe(`TuiFieldErrorContentPipe`, () => { - const testError = `testError`; +describe('TuiFieldErrorContentPipe', () => { + const testError = 'testError'; const max = 15; @Component({ @@ -75,20 +75,20 @@ describe(`TuiFieldErrorContentPipe`, () => { }); beforeEach(() => { - document.body.style.margin = `0`; + document.body.style.margin = '0'; fixture = TestBed.createComponent(TestComponent); component = fixture.componentInstance; fixture.detectChanges(); }); - describe(`Hint`, () => { - it(`shows validation error`, fakeAsync(() => { + describe('Hint', () => { + it('shows validation error', fakeAsync(() => { showHint(); fixture.detectChanges(); expect(getTooltip()!.textContent!.trim()).toBe(testError); })); - it(`shows validation error (function error)`, fakeAsync(() => { + it('shows validation error (function error)', fakeAsync(() => { component.control.setValue(22); showHint(); fixture.detectChanges(); @@ -99,22 +99,22 @@ describe(`TuiFieldErrorContentPipe`, () => { function showHint(): void { component.control.markAsTouched(); fixture.detectChanges(); - getHost().dispatchEvent(new Event(`mouseenter`)); + getHost().dispatchEvent(new Event('mouseenter')); fixture.detectChanges(); tick(500); fixture.detectChanges(); discardPeriodicTasks(); } - function getHost(): HTMLElement { - const element = document.querySelector(`#hint-host`); + function getHost(): Element { + const element = document.querySelector('#hint-host'); - tuiAssertIsHTMLElement(element); + tuiAssertIsElement(element); return element; } function getTooltip(): Element | null { - return document.querySelector(`[automation-id=tui-hint-box__tooltip]`); + return document.querySelector('[automation-id=tui-hint-box__tooltip]'); } });