diff --git a/projects/kit/components/carousel/carousel.template.html b/projects/kit/components/carousel/carousel.template.html index a58e4c885110..5d4b507f9e2c 100644 --- a/projects/kit/components/carousel/carousel.template.html +++ b/projects/kit/components/carousel/carousel.template.html @@ -22,7 +22,7 @@ class="t-item" [disabled]="isDisabled(i)" [ngStyle]="getStyle(itemsCount)" - (waIntersectionObservee)="onIntersection($event[0], i)" + (waIntersectionObservee)="$event[0] && onIntersection($event[0], i)" > diff --git a/projects/kit/components/files/input-files/input-files.directive.ts b/projects/kit/components/files/input-files/input-files.directive.ts index e937b4c36d10..10b1535ada2f 100644 --- a/projects/kit/components/files/input-files/input-files.directive.ts +++ b/projects/kit/components/files/input-files/input-files.directive.ts @@ -54,11 +54,13 @@ export class TuiInputFilesDirective public readonly input = tuiInjectElement(); public process(files: FileList): void { - this.onChange( - this.input.multiple - ? [...toArray(this.value()), ...Array.from(files)] - : files[0] || null, - ); + const fileOrFiles = this.input.multiple + ? [...toArray(this.value()), ...Array.from(files)] + : files[0]; + + if (fileOrFiles) { + this.onChange(fileOrFiles); + } } protected onClick(event: MouseEvent): void { diff --git a/projects/kit/components/items-with-more/items-with-more.service.ts b/projects/kit/components/items-with-more/items-with-more.service.ts index 6e921ca4c1b7..54d70e8bf5f5 100644 --- a/projects/kit/components/items-with-more/items-with-more.service.ts +++ b/projects/kit/components/items-with-more/items-with-more.service.ts @@ -40,7 +40,7 @@ export class TuiItemsWithMoreService extends Observable { const items = Array.from(children, ({clientWidth}) => clientWidth); const first = this.directive.required === -1 ? 0 : this.directive.required; const last = items.length - 1; - const more = children[last]?.tagName === 'SPAN' ? items[last] : 0; + const more = children[last]?.tagName === 'SPAN' ? (items[last] ?? 0) : 0; items.unshift(...items.splice(first, 1)); @@ -51,7 +51,7 @@ export class TuiItemsWithMoreService extends Observable { } for (let i = last - 1; i > 0; i--) { - total -= items[i]; + total -= items[i] ?? 0; if (total + more <= clientWidth) { return tuiClamp( diff --git a/projects/kit/components/pagination/pagination.component.ts b/projects/kit/components/pagination/pagination.component.ts index 02b41820ec7c..b36f0ad32a6a 100644 --- a/projects/kit/components/pagination/pagination.component.ts +++ b/projects/kit/components/pagination/pagination.component.ts @@ -197,7 +197,7 @@ export class TuiPagination { } const previous = this.els.find( - (_, index, array) => array[index + 1].nativeElement === element, + (_, index, array) => array[index + 1]?.nativeElement === element, ); previous?.nativeElement.focus(); diff --git a/projects/kit/components/preview/preview.component.ts b/projects/kit/components/preview/preview.component.ts index ed7ec3da914b..f05c4fd7210e 100644 --- a/projects/kit/components/preview/preview.component.ts +++ b/projects/kit/components/preview/preview.component.ts @@ -112,14 +112,10 @@ export class TuiPreviewComponent { } } - protected onResize(contentResizeEntries: readonly ResizeObserverEntry[]): void { - if (contentResizeEntries.length === 0) { - return; + protected onResize([entry]: readonly ResizeObserverEntry[]): void { + if (entry?.contentRect) { + this.refresh(entry.contentRect.width, entry.contentRect.height); } - - const {width, height} = contentResizeEntries[0].contentRect; - - this.refresh(width, height); } protected reset(): void { diff --git a/projects/kit/components/push/push-alert.template.html b/projects/kit/components/push/push-alert.template.html index 80356390f1b6..303f32294ea0 100644 --- a/projects/kit/components/push/push-alert.template.html +++ b/projects/kit/components/push/push-alert.template.html @@ -23,7 +23,7 @@ *ngIf="context.buttons.length > 1" tuiButton type="button" - (click)="context.$implicit.next(context.buttons[0])" + (click)="context.$implicit.next(context.buttons[0] || '')" > {{ context.buttons[0] }} @@ -31,7 +31,7 @@ *ngIf="context.buttons.length" tuiLink type="button" - (click)="context.$implicit.next(context.buttons[context.buttons.length - 1])" + (click)="context.$implicit.next(context.buttons[context.buttons.length - 1] || '')" > {{ context.buttons[context.buttons.length - 1] }} diff --git a/projects/kit/components/range/range-change.directive.ts b/projects/kit/components/range/range-change.directive.ts index 74dd55c19168..d6dc25707501 100644 --- a/projects/kit/components/range/range-change.directive.ts +++ b/projects/kit/components/range/range-change.directive.ts @@ -30,6 +30,7 @@ export class TuiRangeChange { tuiTypedFromEvent(this.doc, 'touchmove').pipe( filter(({touches}) => touches.length === 1), map(({touches}) => touches[0]), + filter((event): event is Touch => !!event), ), tuiTypedFromEvent(this.doc, 'mousemove'), ); @@ -56,7 +57,7 @@ export class TuiRangeChange { } }), switchMap((event) => this.pointerMove$.pipe(startWith(event))), - map(({clientX}) => this.getFractionFromEvents(clientX)), + map(({clientX}) => this.getFractionFromEvents(clientX ?? 0)), takeUntil(this.pointerUp$), repeat(), takeUntilDestroyed(), @@ -83,9 +84,9 @@ export class TuiRangeChange { const [leftSliderRef, rightSliderRef] = this.range.slidersRefs; switch (target) { - case leftSliderRef.nativeElement: + case leftSliderRef?.nativeElement: return 'left'; - case rightSliderRef.nativeElement: + case rightSliderRef?.nativeElement: return 'right'; default: return this.findNearestActiveThumb(clientX); diff --git a/projects/kit/components/range/range.component.ts b/projects/kit/components/range/range.component.ts index 156ea6604b0e..fe7782af176c 100644 --- a/projects/kit/components/range/range.component.ts +++ b/projects/kit/components/range/range.component.ts @@ -133,8 +133,8 @@ export class TuiRange extends TuiControl<[number, number]> implements OnChanges protected changeByStep(coefficient: number, target: HTMLElement): void { const [sliderLeftRef, sliderRightRef] = this.slidersRefs; - const leftThumbElement = sliderLeftRef.nativeElement; - const rightThumbElement = sliderRightRef.nativeElement; + const leftThumbElement = sliderLeftRef?.nativeElement; + const rightThumbElement = sliderRightRef?.nativeElement; const isRightThumb = target === this.el diff --git a/projects/kit/components/slider/helpers/key-steps.ts b/projects/kit/components/slider/helpers/key-steps.ts index 231aaf179207..d9c0f38d3bd9 100644 --- a/projects/kit/components/slider/helpers/key-steps.ts +++ b/projects/kit/components/slider/helpers/key-steps.ts @@ -32,7 +32,8 @@ function tuiFindKeyStepsBoundariesByFn( const keyStepUpperIndex = keySteps.findIndex((keyStep, i) => i && fn(keyStep)); const lowerStep = keySteps[keyStepUpperIndex - 1] || keySteps[0]; - const upperStep = keySteps[keyStepUpperIndex] || keySteps[keySteps.length - 1]; + const upperStep = keySteps[keyStepUpperIndex] || + keySteps[keySteps.length - 1] || [0, 0]; return [lowerStep, upperStep]; } diff --git a/projects/kit/components/slider/helpers/slider-key-steps.directive.ts b/projects/kit/components/slider/helpers/slider-key-steps.directive.ts index c989d8a40774..3f19db266579 100644 --- a/projects/kit/components/slider/helpers/slider-key-steps.directive.ts +++ b/projects/kit/components/slider/helpers/slider-key-steps.directive.ts @@ -50,7 +50,7 @@ export class TuiSliderKeySteps extends TuiControl { } protected get max(): number { - return this.keySteps[this.keySteps.length - 1][1]; + return this.keySteps[this.keySteps.length - 1]?.[1] ?? 0; } protected updateControlValue(): void { diff --git a/projects/kit/components/tabs/tabs-with-more.component.ts b/projects/kit/components/tabs/tabs-with-more.component.ts index 2705702782bf..4a465784ab5c 100644 --- a/projects/kit/components/tabs/tabs-with-more.component.ts +++ b/projects/kit/components/tabs/tabs-with-more.component.ts @@ -181,7 +181,7 @@ export class TuiTabsWithMore implements AfterViewChecked, AfterViewInit { let index = tabs.length - 2; while (index >= 0) { - tabs[index].focus(); + tabs[index]?.focus(); if (tuiIsNativeFocused(tabs[index])) { return; @@ -231,20 +231,21 @@ export class TuiTabsWithMore implements AfterViewChecked, AfterViewInit { const {exposeActive, minMoreWidth} = this.options; const {clientWidth} = this.el; - const activeWidth = tabs[activeItemIndex] ? tabs[activeItemIndex].scrollWidth : 0; - const moreWidth = Math.max(tabs[tabs.length - 1].scrollWidth, minMoreWidth); + const active = tabs[activeItemIndex]; + const activeWidth = active?.scrollWidth ?? 0; + const moreWidth = Math.max(tabs[tabs.length - 1]?.scrollWidth ?? 0, minMoreWidth); let maxIndex = tabs.length - 2; let total = tabs.reduce((acc, {scrollWidth}) => acc + scrollWidth, 0) + maxIndex * margin - - tabs[tabs.length - 1].scrollWidth; + (tabs[tabs.length - 1]?.scrollWidth ?? 0); if (Number.isNaN(total) || total <= clientWidth) { return Infinity; } while (maxIndex) { - total -= tabs[maxIndex].scrollWidth + margin; + total -= (tabs[maxIndex]?.scrollWidth ?? 0) + margin; maxIndex--; const activeDisplaced = exposeActive && activeItemIndex > maxIndex; diff --git a/projects/kit/directives/lazy-loading/lazy-loading.service.ts b/projects/kit/directives/lazy-loading/lazy-loading.service.ts index 2080000f1753..50dbe17d5fef 100644 --- a/projects/kit/directives/lazy-loading/lazy-loading.service.ts +++ b/projects/kit/directives/lazy-loading/lazy-loading.service.ts @@ -11,7 +11,7 @@ export class TuiLazyLoadingService extends Observable private readonly stream$ = this.src$.pipe( switchMap((src) => this.intersections$.pipe( - filter(([{isIntersecting}]) => isIntersecting), + filter((entry) => !!entry[0]?.isIntersecting), map(() => src), take(1), ), diff --git a/projects/kit/directives/sensitive/sensitive.directive.ts b/projects/kit/directives/sensitive/sensitive.directive.ts index c432bde6023a..23763c6f6573 100644 --- a/projects/kit/directives/sensitive/sensitive.directive.ts +++ b/projects/kit/directives/sensitive/sensitive.directive.ts @@ -44,10 +44,11 @@ export class TuiSensitive { protected readonly height = toSignal( inject(ResizeObserverService, {self: true}).pipe( - map(([{contentRect}]) => [ - Math.max(2, Math.floor(contentRect.height / 16) + 1), - contentRect.height, - ]), + map((entry): [number, number] => { + const height = entry[0]?.contentRect.height ?? 0; + + return [Math.max(2, Math.floor(height / 16) + 1), height]; + }), map(([rows, height]) => height * (rowsInSvg / rows)), tuiZonefull(inject(NgZone)), tuiWatch(inject(ChangeDetectorRef)), diff --git a/projects/kit/directives/skeleton/skeleton.directive.ts b/projects/kit/directives/skeleton/skeleton.directive.ts index ef54248bc933..f556abce00ea 100644 --- a/projects/kit/directives/skeleton/skeleton.directive.ts +++ b/projects/kit/directives/skeleton/skeleton.directive.ts @@ -50,7 +50,7 @@ export class TuiSkeleton implements OnChanges { public ngOnChanges({tuiSkeleton}: SimpleChanges): void { this.animation?.cancel(); - if (!tuiSkeleton.currentValue && !tuiSkeleton.firstChange) { + if (!tuiSkeleton?.currentValue && !tuiSkeleton?.firstChange) { this.animation = this.el.animate(FADE, this.duration); } }