Skip to content

Commit

Permalink
Some stuff (#2102)
Browse files Browse the repository at this point in the history
* chore: some stuff

* chore: fix tests

* chore: fix tests
  • Loading branch information
waterplea authored and splincode committed Aug 24, 2022
1 parent c84789d commit d3c1a9e
Show file tree
Hide file tree
Showing 27 changed files with 252 additions and 313 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import {
AbstractTuiNullableControl,
isNativeFocusedIn,
TUI_FOCUSABLE_ITEM_ACCESSOR,
tuiAssertIsHTMLElement,
tuiAssertIsElement,
TuiBooleanHandler,
TuiCreditCardAutofillName,
tuiDefaultProp,
Expand Down Expand Up @@ -385,7 +385,7 @@ export class TuiInputCardGroupedComponent
}

onMouseDown(event: MouseEvent): void {
tuiAssertIsHTMLElement(event.target);
tuiAssertIsElement(event.target);

if (event.target.matches(`input`)) {
return;
Expand All @@ -396,7 +396,7 @@ export class TuiInputCardGroupedComponent
}

onScroll({currentTarget}: Event): void {
tuiAssertIsHTMLElement(currentTarget);
tuiAssertIsElement(currentTarget);

currentTarget.scrollLeft = 0;
}
Expand Down
4 changes: 2 additions & 2 deletions projects/addon-editor/components/editor/editor.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import {
setNativeFocused,
TUI_FOCUSABLE_ITEM_ACCESSOR,
tuiAssert,
tuiAssertIsHTMLElement,
tuiAssertIsElement,
TuiBooleanHandler,
tuiDefaultProp,
TuiDestroyService,
Expand Down Expand Up @@ -290,7 +290,7 @@ export class TuiEditorComponent extends AbstractTuiControl<string> implements On
return;
}

tuiAssertIsHTMLElement(suitableNode);
tuiAssertIsElement(suitableNode);

const element = suitableNode.closest(selector);

Expand Down
15 changes: 2 additions & 13 deletions projects/cdk/classes/assert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
38 changes: 9 additions & 29 deletions projects/cdk/directives/hovered/hovered.directive.ts
Original file line number Diff line number Diff line change
@@ -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<boolean>();

@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<boolean>,
) {}
}
32 changes: 32 additions & 0 deletions projects/cdk/directives/hovered/hovered.service.ts
Original file line number Diff line number Diff line change
@@ -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<boolean> {
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<Element>,
@Inject(NgZone) private readonly ngZone: NgZone,
) {
super(subscriber => this.stream$.subscribe(subscriber));
}
}
1 change: 1 addition & 0 deletions projects/cdk/directives/hovered/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './hovered.directive';
export * from './hovered.module';
export * from './hovered.service';
54 changes: 0 additions & 54 deletions projects/cdk/services/hovered.service.ts

This file was deleted.

1 change: 0 additions & 1 deletion projects/cdk/services/index.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down
5 changes: 3 additions & 2 deletions projects/cdk/utils/focus/get-closest-keyboard-focusable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -43,7 +43,8 @@ export function getClosestFocusable(
initial = treeWalker.currentNode;
}

if (check(initial)) {
// TODO: iframe warning
if (check(initial) && initial instanceof HTMLElement) {
return initial;
}
}
Expand Down
2 changes: 1 addition & 1 deletion projects/core/components/button/button.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {TUI_BUTTON_OPTIONS, TuiButtonOptions} from './button-options';
useExisting: forwardRef(() => TuiButtonComponent),
},
TuiDestroyService,
TuiHoveredService,
TuiFocusVisibleService,
],
})
Expand Down Expand Up @@ -92,7 +93,6 @@ export class TuiButtonComponent
super();

hoveredService
.createHovered$(elementRef.nativeElement)
.pipe(watch(changeDetectorRef), takeUntil(destroy$))
.subscribe(hovered => {
this.updateHovered(hovered);
Expand Down
34 changes: 16 additions & 18 deletions projects/core/components/data-list/data-list.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
isPresent,
itemsQueryListObservable,
setNativeMouseFocused,
tuiAssertIsHTMLElement,
tuiAssertIsElement,
tuiDefaultProp,
tuiMoveFocus,
tuiPure,
Expand All @@ -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: [
Expand All @@ -53,13 +53,13 @@ export class TuiDataListComponent<T> implements TuiDataListAccessor<T> {
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<HTMLElement>,
Expand All @@ -72,30 +72,28 @@ export class TuiDataListComponent<T> implements TuiDataListAccessor<T> {
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;

tuiMoveFocus(elements.indexOf(current), elements, step);
}

// 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);
}
Expand All @@ -110,7 +108,7 @@ export class TuiDataListComponent<T> implements TuiDataListAccessor<T> {
}

onFocus({target}: Event, top: boolean): void {
tuiAssertIsHTMLElement(target);
tuiAssertIsElement(target);

const {elements} = this;

Expand All @@ -119,6 +117,6 @@ export class TuiDataListComponent<T> implements TuiDataListAccessor<T> {
}

private get elements(): readonly HTMLElement[] {
return Array.from(this.elementRef.nativeElement.querySelectorAll(`[tuiOption]`));
return Array.from(this.elementRef.nativeElement.querySelectorAll('[tuiOption]'));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
inRange,
POLLING_TIME,
TuiActiveZoneDirective,
tuiAssertIsHTMLElement,
tuiAssertIsElement,
TuiDestroyService,
TuiDropdownHostComponent,
TuiOverscrollMode,
Expand Down Expand Up @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion projects/core/components/hints-host/hints-host.style.less
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

:host {
position: fixed;
bottom: 0;
top: 0;
left: 0;
width: 100%;
height: 0;
Expand Down
Loading

0 comments on commit d3c1a9e

Please sign in to comment.