From 00f97b27933fa935907d116a41aee1399494c08e Mon Sep 17 00:00:00 2001 From: waterplea Date: Tue, 22 Aug 2023 14:30:26 -0500 Subject: [PATCH 1/3] feat(experimental): `Fade` add new component --- .../line-chart/line-chart-hint.directive.ts | 4 +- .../line-chart/line-chart.component.ts | 4 +- .../line-days-chart-hint.directive.ts | 4 +- .../line-days-chart.component.ts | 4 +- .../pie-chart/pie-chart.directive.ts | 4 +- .../pull-to-refresh.component.ts | 4 +- .../sheet-bar/sheet-bar.component.ts | 4 +- .../sheet/components/sheet/sheet.component.ts | 4 +- .../sheet/components/sheet/sheet.providers.ts | 6 +- .../sheet-close/sheet-close.directive.ts | 4 +- .../sheet-wrapper/sheet-wrapper.directive.ts | 6 +- .../components/sheet/ios.hacks.ts | 4 +- .../elastic-sticky/elastic-sticky.service.ts | 6 +- .../active-zone/active-zone.directive.ts | 4 +- .../auto-focus/autofocus.options.ts | 4 +- .../auto-focus/handlers/ios.handler.ts | 4 +- .../directives/focused/focused.directive.ts | 4 +- .../cdk/directives/hovered/hovered.service.ts | 4 +- .../overscroll/overscroll.directive.ts | 6 +- .../prevent-default.directive.ts | 4 +- projects/cdk/observables/zone-free.ts | 16 +-- projects/cdk/services/obscured.service.ts | 4 +- projects/cdk/services/resize.service.ts | 6 +- .../scroll-controls.component.ts | 4 +- .../scroll-controls/scrollbar.directive.ts | 6 +- .../hint/hint-describe.directive.ts | 4 +- projects/core/observables/zoneful-map.ts | 6 +- projects/core/services/position.service.ts | 4 +- .../services/router-link-active.service.ts | 4 +- projects/demo/src/modules/app/app.routes.ts | 8 ++ projects/demo/src/modules/app/pages.ts | 6 + .../experimental/avatar/avatar.module.ts | 4 +- .../experimental/avatar/avatar.template.html | 8 +- .../experimental/fade/examples/1/index.html | 8 ++ .../experimental/fade/examples/1/index.less | 14 +++ .../experimental/fade/examples/1/index.ts | 12 ++ .../experimental/fade/examples/2/index.html | 27 +++++ .../experimental/fade/examples/2/index.less | 27 +++++ .../experimental/fade/examples/2/index.ts | 20 ++++ .../experimental/fade/examples/3/index.html | 11 ++ .../experimental/fade/examples/3/index.less | 9 ++ .../experimental/fade/examples/3/index.ts | 14 +++ .../fade/examples/import/import-module.md | 13 ++ .../fade/examples/import/insert-template.md | 5 + .../experimental/fade/fade.component.ts | 39 ++++++ .../modules/experimental/fade/fade.module.ts | 31 +++++ .../modules/experimental/fade/fade.style.less | 4 + .../experimental/fade/fade.template.html | 113 ++++++++++++++++++ .../components/avatar/avatar.module.ts | 4 +- .../components/avatar/avatar.template.html | 4 +- .../components/fade/fade.component.ts | 76 ++++++++++++ .../components/fade/fade.module.ts | 9 ++ .../components/fade/fade.style.less | 68 +++++++++++ .../experimental/components/fade/index.ts | 2 + .../components/{text => fade}/ng-package.json | 0 projects/experimental/components/index.ts | 2 +- .../experimental/components/text/index.ts | 2 - .../components/text/text.component.ts | 63 ---------- .../components/text/text.module.ts | 9 -- .../components/text/text.style.less | 13 -- .../items-with-more.service.ts | 4 +- .../line-clamp/line-clamp.component.ts | 4 +- .../tabs/underline/underline.component.ts | 4 +- .../kit/components/tiles/tile.component.ts | 4 +- 64 files changed, 610 insertions(+), 173 deletions(-) create mode 100644 projects/demo/src/modules/experimental/fade/examples/1/index.html create mode 100644 projects/demo/src/modules/experimental/fade/examples/1/index.less create mode 100644 projects/demo/src/modules/experimental/fade/examples/1/index.ts create mode 100644 projects/demo/src/modules/experimental/fade/examples/2/index.html create mode 100644 projects/demo/src/modules/experimental/fade/examples/2/index.less create mode 100644 projects/demo/src/modules/experimental/fade/examples/2/index.ts create mode 100644 projects/demo/src/modules/experimental/fade/examples/3/index.html create mode 100644 projects/demo/src/modules/experimental/fade/examples/3/index.less create mode 100644 projects/demo/src/modules/experimental/fade/examples/3/index.ts create mode 100644 projects/demo/src/modules/experimental/fade/examples/import/import-module.md create mode 100644 projects/demo/src/modules/experimental/fade/examples/import/insert-template.md create mode 100644 projects/demo/src/modules/experimental/fade/fade.component.ts create mode 100644 projects/demo/src/modules/experimental/fade/fade.module.ts create mode 100644 projects/demo/src/modules/experimental/fade/fade.style.less create mode 100644 projects/demo/src/modules/experimental/fade/fade.template.html create mode 100644 projects/experimental/components/fade/fade.component.ts create mode 100644 projects/experimental/components/fade/fade.module.ts create mode 100644 projects/experimental/components/fade/fade.style.less create mode 100644 projects/experimental/components/fade/index.ts rename projects/experimental/components/{text => fade}/ng-package.json (100%) delete mode 100644 projects/experimental/components/text/index.ts delete mode 100644 projects/experimental/components/text/text.component.ts delete mode 100644 projects/experimental/components/text/text.module.ts delete mode 100644 projects/experimental/components/text/text.style.less diff --git a/projects/addon-charts/components/line-chart/line-chart-hint.directive.ts b/projects/addon-charts/components/line-chart/line-chart-hint.directive.ts index bf92a3ea37d6..5ef01d6f6d4b 100644 --- a/projects/addon-charts/components/line-chart/line-chart-hint.directive.ts +++ b/projects/addon-charts/components/line-chart/line-chart-hint.directive.ts @@ -52,7 +52,7 @@ export class TuiLineChartHintDirective implements AfterViewInit { constructor( @Inject(Renderer2) private readonly renderer: Renderer2, @Self() @Inject(TuiDestroyService) private readonly destroy$: TuiDestroyService, - @Inject(NgZone) private readonly ngZone: NgZone, + @Inject(NgZone) private readonly zone: NgZone, @Inject(TuiHoveredService) private readonly hovered$: Observable, ) {} @@ -60,7 +60,7 @@ export class TuiLineChartHintDirective implements AfterViewInit { combineLatest([tuiLineChartDrivers(this.charts), this.hovered$]) .pipe( filter(result => !result.some(Boolean)), - tuiZonefree(this.ngZone), + tuiZonefree(this.zone), takeUntil(this.destroy$), ) .subscribe(() => { diff --git a/projects/addon-charts/components/line-chart/line-chart.component.ts b/projects/addon-charts/components/line-chart/line-chart.component.ts index 6c1f81c760ce..f9e0782b1c7a 100644 --- a/projects/addon-charts/components/line-chart/line-chart.component.ts +++ b/projects/addon-charts/components/line-chart/line-chart.component.ts @@ -83,7 +83,7 @@ export class TuiLineChartComponent { constructor( @Inject(TuiIdService) idService: TuiIdService, - @Inject(NgZone) private readonly ngZone: NgZone, + @Inject(NgZone) private readonly zone: NgZone, @Optional() @Inject(TuiLineChartHintDirective) readonly hintDirective: TuiLineChartHintDirective | null, @@ -97,7 +97,7 @@ export class TuiLineChartComponent { @tuiPure get hovered$(): Observable { - return this._hovered$.pipe(distinctUntilChanged(), tuiZoneOptimized(this.ngZone)); + return this._hovered$.pipe(distinctUntilChanged(), tuiZoneOptimized(this.zone)); } get hintContent(): PolymorpheusContent> { diff --git a/projects/addon-charts/components/line-days-chart/line-days-chart-hint.directive.ts b/projects/addon-charts/components/line-days-chart/line-days-chart-hint.directive.ts index 40f5bf9d109e..272794ba3549 100644 --- a/projects/addon-charts/components/line-days-chart/line-days-chart-hint.directive.ts +++ b/projects/addon-charts/components/line-days-chart/line-days-chart-hint.directive.ts @@ -40,7 +40,7 @@ export class TuiLineDaysChartHintDirective implements AfterContentInit { constructor( @Self() @Inject(TuiDestroyService) private readonly destroy$: TuiDestroyService, - @Inject(NgZone) private readonly ngZone: NgZone, + @Inject(NgZone) private readonly zone: NgZone, @Inject(TuiHoveredService) private readonly hovered$: Observable, ) {} @@ -51,7 +51,7 @@ export class TuiLineDaysChartHintDirective implements AfterContentInit { ]) .pipe( filter(result => !result.some(Boolean)), - tuiZonefree(this.ngZone), + tuiZonefree(this.zone), takeUntil(this.destroy$), ) .subscribe(() => { diff --git a/projects/addon-charts/components/line-days-chart/line-days-chart.component.ts b/projects/addon-charts/components/line-days-chart/line-days-chart.component.ts index 18888686002b..1cabae9c7d33 100644 --- a/projects/addon-charts/components/line-days-chart/line-days-chart.component.ts +++ b/projects/addon-charts/components/line-days-chart/line-days-chart.component.ts @@ -111,7 +111,7 @@ export class TuiLineDaysChartComponent implements AfterViewInit { @Inject(TuiLineDaysChartHintDirective) private readonly hintDirective: TuiLineDaysChartHintDirective | null, @Self() @Inject(TuiDestroyService) private readonly destroy$: TuiDestroyService, - @Inject(NgZone) private readonly ngZone: NgZone, + @Inject(NgZone) private readonly zone: NgZone, @Inject(TuiHoveredService) private readonly hovered$: Observable, @Inject(TUI_LINE_CHART_OPTIONS) private readonly options: TuiLineChartOptions, ) {} @@ -144,7 +144,7 @@ export class TuiLineDaysChartComponent implements AfterViewInit { combineLatest([tuiLineChartDrivers(this.charts), this.hovered$]) .pipe( filter(result => !result.some(Boolean)), - tuiZonefree(this.ngZone), + tuiZonefree(this.zone), takeUntil(this.destroy$), ) .subscribe(() => { diff --git a/projects/addon-charts/components/pie-chart/pie-chart.directive.ts b/projects/addon-charts/components/pie-chart/pie-chart.directive.ts index d6d8e1da5d53..d9157932f30f 100644 --- a/projects/addon-charts/components/pie-chart/pie-chart.directive.ts +++ b/projects/addon-charts/components/pie-chart/pie-chart.directive.ts @@ -20,7 +20,7 @@ export class TuiPieChartDirective { constructor( @Inject(ElementRef) {nativeElement}: ElementRef, - @Inject(NgZone) ngZone: NgZone, + @Inject(NgZone) zone: NgZone, @Self() @Inject(TuiDestroyService) destroy$: Observable, @Inject(PERFORMANCE) performance: Performance, @Inject(ANIMATION_FRAME) animationFrame$: Observable, @@ -47,7 +47,7 @@ export class TuiPieChartDirective { ]), ); }), - tuiZonefree(ngZone), + tuiZonefree(zone), takeUntil(destroy$), ) .subscribe(([start, end]) => { diff --git a/projects/addon-mobile/components/pull-to-refresh/pull-to-refresh.component.ts b/projects/addon-mobile/components/pull-to-refresh/pull-to-refresh.component.ts index 9fbbba028089..64cd504be7a5 100644 --- a/projects/addon-mobile/components/pull-to-refresh/pull-to-refresh.component.ts +++ b/projects/addon-mobile/components/pull-to-refresh/pull-to-refresh.component.ts @@ -52,7 +52,7 @@ export class TuiPullToRefreshComponent { ); constructor( - @Inject(NgZone) ngZone: NgZone, + @Inject(NgZone) zone: NgZone, @Inject(TuiDestroyService) @Self() destroy$: Observable, @Inject(TUI_SCROLL_REF) {nativeElement}: ElementRef, @Inject(TUI_IS_IOS) private readonly isIOS: boolean, @@ -64,7 +64,7 @@ export class TuiPullToRefreshComponent { // Ensure scrolling down is impossible while pulling if (this.component) { tuiScrollFrom(nativeElement) - .pipe(startWith(null), tuiZonefree(ngZone), takeUntil(destroy$)) + .pipe(startWith(null), tuiZonefree(zone), takeUntil(destroy$)) .subscribe(() => { if (nativeElement.scrollTop) { nativeElement.style.touchAction = ''; diff --git a/projects/addon-mobile/components/sheet/components/sheet-bar/sheet-bar.component.ts b/projects/addon-mobile/components/sheet/components/sheet-bar/sheet-bar.component.ts index 4b457747a974..677d1e1cb2e1 100644 --- a/projects/addon-mobile/components/sheet/components/sheet-bar/sheet-bar.component.ts +++ b/projects/addon-mobile/components/sheet/components/sheet-bar/sheet-bar.component.ts @@ -14,13 +14,13 @@ import {TUI_SHEET, TUI_SHEET_SCROLL} from '../../sheet-tokens'; }) export class TuiSheetBarComponent { readonly rotate$ = this.scroll$.pipe( - tuiZonefulMap(y => tuiClamp(10 - (y - this.stop) / 5, 0, 10), this.ngZone), + tuiZonefulMap(y => tuiClamp(10 - (y - this.stop) / 5, 0, 10), this.zone), ); constructor( @Inject(TUI_SHEET) private readonly sheet: TuiSheetRequiredProps, @Inject(TUI_SHEET_SCROLL) private readonly scroll$: Observable, - @Inject(NgZone) private readonly ngZone: NgZone, + @Inject(NgZone) private readonly zone: NgZone, ) {} private get stop(): number { diff --git a/projects/addon-mobile/components/sheet/components/sheet/sheet.component.ts b/projects/addon-mobile/components/sheet/components/sheet/sheet.component.ts index ede4caa9a4e2..0847ed603858 100644 --- a/projects/addon-mobile/components/sheet/components/sheet/sheet.component.ts +++ b/projects/addon-mobile/components/sheet/components/sheet/sheet.component.ts @@ -59,7 +59,7 @@ export class TuiSheetComponent implements TuiSheetRequiredProps, AfterView constructor( @Inject(TUI_SHEET_SCROLL) private readonly scroll$: Observable, @Inject(ElementRef) private readonly el: ElementRef, - @Inject(NgZone) private readonly ngZone: NgZone, + @Inject(NgZone) private readonly zone: NgZone, @Inject(TUI_IS_IOS) readonly isIos: boolean, @Inject(TUI_MORE_WORD) readonly moreWord$: Observable, ) {} @@ -80,7 +80,7 @@ export class TuiSheetComponent implements TuiSheetRequiredProps, AfterView get context(): TuiSheet { return { ...this.item, - scroll$: this.scroll$.pipe(tuiZonefull(this.ngZone)), + scroll$: this.scroll$.pipe(tuiZonefull(this.zone)), }; } diff --git a/projects/addon-mobile/components/sheet/components/sheet/sheet.providers.ts b/projects/addon-mobile/components/sheet/components/sheet/sheet.providers.ts index c3226aaed242..7b65a8899891 100644 --- a/projects/addon-mobile/components/sheet/components/sheet/sheet.providers.ts +++ b/projects/addon-mobile/components/sheet/components/sheet/sheet.providers.ts @@ -35,18 +35,18 @@ export const TUI_SHEET_PROVIDERS: Provider[] = [ deps: [ElementRef, NgZone, DOCUMENT, TUI_IS_IOS], useFactory: ( {nativeElement}: ElementRef, - ngZone: NgZone, + zone: NgZone, doc: Document, isIos: boolean, ): Observable => { return isIos - ? iosScrollFactory(nativeElement, doc, ngZone) + ? iosScrollFactory(nativeElement, doc, zone) : merge( tuiTypedFromEvent(nativeElement, `scroll`), tuiTypedFromEvent(nativeElement, `load`, {capture: true}), ).pipe( map(() => nativeElement.scrollTop), - tuiZonefree(ngZone), + tuiZonefree(zone), share(), ); }, diff --git a/projects/addon-mobile/components/sheet/directives/sheet-close/sheet-close.directive.ts b/projects/addon-mobile/components/sheet/directives/sheet-close/sheet-close.directive.ts index 06940e384b2d..dfc16a1eddeb 100644 --- a/projects/addon-mobile/components/sheet/directives/sheet-close/sheet-close.directive.ts +++ b/projects/addon-mobile/components/sheet/directives/sheet-close/sheet-close.directive.ts @@ -23,12 +23,12 @@ export class TuiSheetCloseDirective { ), filter(y => this.sheet.item?.closeable && this.shouldClose(y)), distinctUntilChanged(), - tuiZonefull(this.ngZone), + tuiZonefull(this.zone), ), ); constructor( - @Inject(NgZone) private readonly ngZone: NgZone, + @Inject(NgZone) private readonly zone: NgZone, @Inject(TUI_SHEET_DRAGGED) private readonly dragged$: Observable, @Inject(TUI_SHEET_SCROLL) private readonly scroll$: Observable, @Inject(WINDOW) private readonly win: Window, diff --git a/projects/addon-mobile/components/sheet/directives/sheet-wrapper/sheet-wrapper.directive.ts b/projects/addon-mobile/components/sheet/directives/sheet-wrapper/sheet-wrapper.directive.ts index 0af3b9a358c1..960c601c7206 100644 --- a/projects/addon-mobile/components/sheet/directives/sheet-wrapper/sheet-wrapper.directive.ts +++ b/projects/addon-mobile/components/sheet/directives/sheet-wrapper/sheet-wrapper.directive.ts @@ -42,7 +42,7 @@ export class TuiSheetWrapperDirective { tuiSheetWrapper = 16; constructor( - @Inject(NgZone) private readonly ngZone: NgZone, + @Inject(NgZone) private readonly zone: NgZone, @Inject(WINDOW) private readonly win: Window, ) {} @@ -51,7 +51,7 @@ export class TuiSheetWrapperDirective { return this.scroll$.pipe( map(y => y + 16 > this.win.innerHeight - this.tuiSheetWrapper), distinctUntilChanged(), - tuiZonefull(this.ngZone), + tuiZonefull(this.zone), ); } @@ -59,7 +59,7 @@ export class TuiSheetWrapperDirective { get visible$(): Observable { return processDragged(this.dragged$, this.scroll$).pipe( distinctUntilChanged(), - tuiZonefull(this.ngZone), + tuiZonefull(this.zone), ); } diff --git a/projects/addon-mobile/components/sheet/ios.hacks.ts b/projects/addon-mobile/components/sheet/ios.hacks.ts index d7e91ec2ff0f..c1d8c1ab245f 100644 --- a/projects/addon-mobile/components/sheet/ios.hacks.ts +++ b/projects/addon-mobile/components/sheet/ios.hacks.ts @@ -7,7 +7,7 @@ import {delay, map, share, switchMap, take, takeUntil} from 'rxjs/operators'; export function iosScrollFactory( element: HTMLElement, doc: Document, - ngZone: NgZone, + zone: NgZone, ): Observable { const load$ = tuiTypedFromEvent(element, `load`, {capture: true}); const touchstart$ = tuiTypedFromEvent(element, `touchstart`, {passive: true}); @@ -38,7 +38,7 @@ export function iosScrollFactory( ), ); - return concat(scroll$.pipe(take(1)), result$).pipe(tuiZonefree(ngZone), share()); + return concat(scroll$.pipe(take(1)), result$).pipe(tuiZonefree(zone), share()); } // eslint-disable-next-line @typescript-eslint/naming-convention diff --git a/projects/addon-mobile/directives/elastic-sticky/elastic-sticky.service.ts b/projects/addon-mobile/directives/elastic-sticky/elastic-sticky.service.ts index babb48ad724b..31154234e811 100644 --- a/projects/addon-mobile/directives/elastic-sticky/elastic-sticky.service.ts +++ b/projects/addon-mobile/directives/elastic-sticky/elastic-sticky.service.ts @@ -22,11 +22,11 @@ export class TuiElasticStickyService extends Observable { constructor( @Inject(TUI_SCROLL_REF) scrollRef: ElementRef, @Inject(ElementRef) {nativeElement}: ElementRef, - @Inject(NgZone) ngZone: NgZone, + @Inject(NgZone) zone: NgZone, @Self() @Inject(TuiDestroyService) destroy$: TuiDestroyService, ) { super(subscriber => - ngZone.onStable + zone.onStable .pipe( take(1), switchMap(() => { @@ -53,7 +53,7 @@ export class TuiElasticStickyService extends Observable { startWith(1), distinctUntilChanged(), skip(1), - tuiZoneOptimized(ngZone), + tuiZoneOptimized(zone), takeUntil(destroy$), ) .subscribe(subscriber), diff --git a/projects/cdk/directives/active-zone/active-zone.directive.ts b/projects/cdk/directives/active-zone/active-zone.directive.ts index c85d40c91b27..1c7eec6afbfa 100644 --- a/projects/cdk/directives/active-zone/active-zone.directive.ts +++ b/projects/cdk/directives/active-zone/active-zone.directive.ts @@ -37,13 +37,13 @@ export class TuiActiveZoneDirective implements OnDestroy { startWith(false), distinctUntilChanged(), skip(1), - tuiZoneOptimized(this.ngZone), + tuiZoneOptimized(this.zone), ); constructor( @Inject(TUI_ACTIVE_ELEMENT) private readonly active$: Observable, - @Inject(NgZone) private readonly ngZone: NgZone, + @Inject(NgZone) private readonly zone: NgZone, @Inject(ElementRef) private readonly el: ElementRef, @Optional() @SkipSelf() diff --git a/projects/cdk/directives/auto-focus/autofocus.options.ts b/projects/cdk/directives/auto-focus/autofocus.options.ts index 3bf9e2535ae0..38bf9418f087 100644 --- a/projects/cdk/directives/auto-focus/autofocus.options.ts +++ b/projects/cdk/directives/auto-focus/autofocus.options.ts @@ -54,12 +54,12 @@ export const TUI_AUTOFOCUS_PROVIDERS = [ el: ElementRef, animationFrame$: Observable, renderer: Renderer2, - ngZone: NgZone, + zone: NgZone, win: Window, isIos: boolean, ) => isIos - ? new TuiIosAutofocusHandler(focusable, el, renderer, ngZone, win) + ? new TuiIosAutofocusHandler(focusable, el, renderer, zone, win) : new TuiDefaultAutofocusHandler(focusable, el, animationFrame$), deps: [ [new Optional(), new Self(), TUI_FOCUSABLE_ITEM_ACCESSOR], diff --git a/projects/cdk/directives/auto-focus/handlers/ios.handler.ts b/projects/cdk/directives/auto-focus/handlers/ios.handler.ts index 133ce34af95c..978a4fec40b8 100644 --- a/projects/cdk/directives/auto-focus/handlers/ios.handler.ts +++ b/projects/cdk/directives/auto-focus/handlers/ios.handler.ts @@ -36,7 +36,7 @@ export class TuiIosAutofocusHandler extends AbstractTuiAutofocusHandler { focusable: TuiFocusableElementAccessor | null, @Inject(ElementRef) el: ElementRef, @Inject(Renderer2) private readonly renderer: Renderer2, - @Inject(NgZone) private readonly ngZone: NgZone, + @Inject(NgZone) private readonly zone: NgZone, @Inject(WINDOW) private readonly win: Window, ) { super(focusable, el); @@ -45,7 +45,7 @@ export class TuiIosAutofocusHandler extends AbstractTuiAutofocusHandler { setFocus(): void { if (this.isTextFieldElement) { - this.ngZone.runOutsideAngular(() => this.iosWebkitAutofocus()); + this.zone.runOutsideAngular(() => this.iosWebkitAutofocus()); } else { this.element.focus(); } diff --git a/projects/cdk/directives/focused/focused.directive.ts b/projects/cdk/directives/focused/focused.directive.ts index 1ab835c7dc25..a5749db1a54a 100644 --- a/projects/cdk/directives/focused/focused.directive.ts +++ b/projects/cdk/directives/focused/focused.directive.ts @@ -19,7 +19,7 @@ export class TuiFocusedDirective { constructor( @Inject(ElementRef) {nativeElement}: ElementRef, - @Inject(NgZone) ngZone: NgZone, + @Inject(NgZone) zone: NgZone, ) { this.tuiFocusedChange = merge( tuiTypedFromEvent(nativeElement, 'focusin'), @@ -29,7 +29,7 @@ export class TuiFocusedDirective { startWith(false), distinctUntilChanged(), skip(1), - tuiZoneOptimized(ngZone), + tuiZoneOptimized(zone), ); } } diff --git a/projects/cdk/directives/hovered/hovered.service.ts b/projects/cdk/directives/hovered/hovered.service.ts index 231ce025d279..5e9764081c76 100644 --- a/projects/cdk/directives/hovered/hovered.service.ts +++ b/projects/cdk/directives/hovered/hovered.service.ts @@ -27,11 +27,11 @@ export class TuiHoveredService extends Observable { filter(movedOut), map(ALWAYS_FALSE_HANDLER), ), - ).pipe(distinctUntilChanged(), tuiZoneOptimized(this.ngZone)); + ).pipe(distinctUntilChanged(), tuiZoneOptimized(this.zone)); constructor( @Inject(ElementRef) private readonly el: ElementRef, - @Inject(NgZone) private readonly ngZone: NgZone, + @Inject(NgZone) private readonly zone: NgZone, ) { super(subscriber => this.stream$.subscribe(subscriber)); } diff --git a/projects/cdk/directives/overscroll/overscroll.directive.ts b/projects/cdk/directives/overscroll/overscroll.directive.ts index 0186c79a9397..4328ba78faee 100644 --- a/projects/cdk/directives/overscroll/overscroll.directive.ts +++ b/projects/cdk/directives/overscroll/overscroll.directive.ts @@ -27,13 +27,13 @@ export class TuiOverscrollDirective { constructor( @Inject(ElementRef) {nativeElement}: ElementRef, - @Inject(NgZone) ngZone: NgZone, + @Inject(NgZone) zone: NgZone, @Self() @Inject(TuiDestroyService) destroy$: Observable, ) { tuiTypedFromEvent(nativeElement, 'wheel', {passive: false}) .pipe( filter(() => this.enabled), - tuiZonefree(ngZone), + tuiZonefree(zone), takeUntil(destroy$), ) .subscribe(event => { @@ -77,7 +77,7 @@ export class TuiOverscrollDirective { }), ); }), - tuiZonefree(ngZone), + tuiZonefree(zone), takeUntil(destroy$), ) .subscribe(); diff --git a/projects/cdk/directives/prevent-default/prevent-default.directive.ts b/projects/cdk/directives/prevent-default/prevent-default.directive.ts index 64cd6285b294..b0943ffef5ef 100644 --- a/projects/cdk/directives/prevent-default/prevent-default.directive.ts +++ b/projects/cdk/directives/prevent-default/prevent-default.directive.ts @@ -19,13 +19,13 @@ export class TuiPreventDefaultDirective implements OnInit { constructor( @Inject(ElementRef) private readonly el: ElementRef, - @Inject(NgZone) private readonly ngZone: NgZone, + @Inject(NgZone) private readonly zone: NgZone, @Self() @Inject(TuiDestroyService) private readonly destroy$: Observable, ) {} ngOnInit(): void { fromEvent(this.el.nativeElement, this.eventName, {passive: false}) - .pipe(tuiZonefree(this.ngZone), tuiPreventDefault(), takeUntil(this.destroy$)) + .pipe(tuiZonefree(this.zone), tuiPreventDefault(), takeUntil(this.destroy$)) .subscribe(); } } diff --git a/projects/cdk/observables/zone-free.ts b/projects/cdk/observables/zone-free.ts index c9ec6f706442..74b20c4ef079 100644 --- a/projects/cdk/observables/zone-free.ts +++ b/projects/cdk/observables/zone-free.ts @@ -1,24 +1,24 @@ import {NgZone} from '@angular/core'; import {MonoTypeOperatorFunction, Observable, pipe} from 'rxjs'; -export function tuiZonefull(ngZone: NgZone): MonoTypeOperatorFunction { +export function tuiZonefull(zone: NgZone): MonoTypeOperatorFunction { return source => new Observable(subscriber => source.subscribe({ - next: value => ngZone.run(() => subscriber.next(value)), - error: (error: unknown) => ngZone.run(() => subscriber.error(error)), - complete: () => ngZone.run(() => subscriber.complete()), + next: value => zone.run(() => subscriber.next(value)), + error: (error: unknown) => zone.run(() => subscriber.error(error)), + complete: () => zone.run(() => subscriber.complete()), }), ); } -export function tuiZonefree(ngZone: NgZone): MonoTypeOperatorFunction { +export function tuiZonefree(zone: NgZone): MonoTypeOperatorFunction { return source => new Observable(subscriber => - ngZone.runOutsideAngular(() => source.subscribe(subscriber)), + zone.runOutsideAngular(() => source.subscribe(subscriber)), ); } -export function tuiZoneOptimized(ngZone: NgZone): MonoTypeOperatorFunction { - return pipe(tuiZonefree(ngZone), tuiZonefull(ngZone)); +export function tuiZoneOptimized(zone: NgZone): MonoTypeOperatorFunction { + return pipe(tuiZonefree(zone), tuiZonefull(zone)); } diff --git a/projects/cdk/services/obscured.service.ts b/projects/cdk/services/obscured.service.ts index 3c2abaac92d9..56ab1a3c9be1 100644 --- a/projects/cdk/services/obscured.service.ts +++ b/projects/cdk/services/obscured.service.ts @@ -31,7 +31,7 @@ export class TuiObscuredService extends Observable { @Self() parentsScroll$: TuiParentsScrollService, @Inject(ElementRef) {nativeElement}: ElementRef, - @Inject(NgZone) ngZone: NgZone, + @Inject(NgZone) zone: NgZone, @Inject(WINDOW) win: Window, @Self() @Inject(TuiDestroyService) destroy$: Observable, @Inject(ANIMATION_FRAME) animationFrame$: Observable, @@ -46,7 +46,7 @@ export class TuiObscuredService extends Observable { map(() => tuiGetElementObscures(nativeElement)), startWith(null), distinctUntilChanged(), - tuiZoneOptimized(ngZone), + tuiZoneOptimized(zone), takeUntil(destroy$), ); } diff --git a/projects/cdk/services/resize.service.ts b/projects/cdk/services/resize.service.ts index 7aa0b785dd10..567d1a66f02c 100644 --- a/projects/cdk/services/resize.service.ts +++ b/projects/cdk/services/resize.service.ts @@ -25,13 +25,13 @@ import {TuiDestroyService} from './destroy.service'; export class TuiResizeService extends ResizeObserverService { constructor( @Inject(ElementRef) el: ElementRef, - @Inject(NgZone) ngZone: NgZone, + @Inject(NgZone) zone: NgZone, @Self() @Inject(TuiDestroyService) destroy$: Observable, @Inject(RESIZE_OBSERVER_SUPPORT) support: boolean, @Inject(RESIZE_OPTION_BOX) box: ResizeObserverBoxOptions, @Inject(ANIMATION_FRAME) animationFrame$: Observable, ) { - super(el, ngZone, support, box); + super(el, zone, support, box); return this.pipe( catchError(() => @@ -50,7 +50,7 @@ export class TuiResizeService extends ResizeObserverService { ), ), debounceTime(0), - tuiZonefree(ngZone), + tuiZonefree(zone), share(), takeUntil(destroy$), ); diff --git a/projects/core/components/scroll-controls/scroll-controls.component.ts b/projects/core/components/scroll-controls/scroll-controls.component.ts index 32bd4cdebf00..c3efde9b0c02 100644 --- a/projects/core/components/scroll-controls/scroll-controls.component.ts +++ b/projects/core/components/scroll-controls/scroll-controls.component.ts @@ -32,12 +32,12 @@ export class TuiScrollControlsComponent { map(() => this.scrollbars), startWith([false, false]), distinctUntilChanged((a, b) => a[0] === b[0] && a[1] === b[1]), - tuiZoneOptimized(this.ngZone), + tuiZoneOptimized(this.zone), ); constructor( @Inject(TUI_ANIMATION_OPTIONS) readonly animation: AnimationOptions, - @Inject(NgZone) private readonly ngZone: NgZone, + @Inject(NgZone) private readonly zone: NgZone, @Inject(TUI_SCROLL_REF) private readonly scrollRef: ElementRef, @Inject(ANIMATION_FRAME) private readonly animationFrame$: Observable, @Inject(TUI_MODE) readonly mode$: Observable, diff --git a/projects/core/components/scroll-controls/scrollbar.directive.ts b/projects/core/components/scroll-controls/scrollbar.directive.ts index 4c61d4a2ad32..1f83a28763be 100644 --- a/projects/core/components/scroll-controls/scrollbar.directive.ts +++ b/projects/core/components/scroll-controls/scrollbar.directive.ts @@ -34,7 +34,7 @@ export class TuiScrollbarDirective { tuiScrollbar: TuiOrientation = 'vertical'; constructor( - @Inject(NgZone) ngZone: NgZone, + @Inject(NgZone) zone: NgZone, @Inject(Renderer2) renderer: Renderer2, @Self() @Inject(TuiDestroyService) destroy$: Observable, @Inject(ANIMATION_FRAME) animationFrame$: Observable, @@ -72,7 +72,7 @@ export class TuiScrollbarDirective { }), ), ) - .pipe(tuiZonefree(ngZone), takeUntil(destroy$)) + .pipe(tuiZonefree(zone), takeUntil(destroy$)) .subscribe(([scrollTop, scrollLeft]) => { if (this.tuiScrollbar === 'vertical') { renderer.setProperty(this.element, 'scrollTop', scrollTop); @@ -85,7 +85,7 @@ export class TuiScrollbarDirective { animationFrame$.pipe(throttleTime(POLLING_TIME)), tuiScrollFrom(this.element), ) - .pipe(tuiZonefree(ngZone), takeUntil(destroy$)) + .pipe(tuiZonefree(zone), takeUntil(destroy$)) .subscribe(() => { if (this.tuiScrollbar === 'vertical') { renderer.setStyle(nativeElement, 'top', `${this.thumb * 100}%`); diff --git a/projects/core/directives/hint/hint-describe.directive.ts b/projects/core/directives/hint/hint-describe.directive.ts index 6588c639c94f..8123d999ad87 100644 --- a/projects/core/directives/hint/hint-describe.directive.ts +++ b/projects/core/directives/hint/hint-describe.directive.ts @@ -37,7 +37,7 @@ export class TuiHintDescribeDirective extends TuiDriver { startWith(false), distinctUntilChanged(), skip(1), - tuiZoneOptimized(this.ngZone), + tuiZoneOptimized(this.zone), ); @Input() @@ -46,7 +46,7 @@ export class TuiHintDescribeDirective extends TuiDriver { readonly type = 'hint'; constructor( - @Inject(NgZone) private readonly ngZone: NgZone, + @Inject(NgZone) private readonly zone: NgZone, @Inject(DOCUMENT) private readonly doc: Document, @Inject(ElementRef) private readonly el: ElementRef, ) { diff --git a/projects/core/observables/zoneful-map.ts b/projects/core/observables/zoneful-map.ts index 19bfe46c0826..75e9385a3c7a 100644 --- a/projects/core/observables/zoneful-map.ts +++ b/projects/core/observables/zoneful-map.ts @@ -8,11 +8,11 @@ import {distinctUntilChanged, map} from 'rxjs/operators'; * and only returns to NgZone if value has changed * * @param project mapping function - * @param ngZone NgZone instance + * @param zone NgZone instance */ export function tuiZonefulMap( project: (value: T, index: number) => R, - ngZone: NgZone, + zone: NgZone, ): OperatorFunction { - return pipe(map(project), distinctUntilChanged(), tuiZonefull(ngZone)); + return pipe(map(project), distinctUntilChanged(), tuiZonefull(zone)); } diff --git a/projects/core/services/position.service.ts b/projects/core/services/position.service.ts index 0e07fb06934f..59113be4e4eb 100644 --- a/projects/core/services/position.service.ts +++ b/projects/core/services/position.service.ts @@ -12,7 +12,7 @@ export class TuiPositionService extends Observable { // Destructuring here causes memory leak @Inject(ElementRef) el: ElementRef, @Inject(ANIMATION_FRAME) animationFrame: Observable, - @Inject(NgZone) ngZone: NgZone, + @Inject(NgZone) zone: NgZone, @Inject(TuiPositionAccessor) accessor: TuiPositionAccessor, ) { super(subscriber => @@ -20,7 +20,7 @@ export class TuiPositionService extends Observable { .pipe( map(() => el.nativeElement.getBoundingClientRect()), map(rect => accessor.getPosition(rect)), - tuiZonefree(ngZone), + tuiZonefree(zone), ) .subscribe(subscriber), ); diff --git a/projects/core/services/router-link-active.service.ts b/projects/core/services/router-link-active.service.ts index 2920375f7e76..e2444053db50 100644 --- a/projects/core/services/router-link-active.service.ts +++ b/projects/core/services/router-link-active.service.ts @@ -12,7 +12,7 @@ export class TuiRouterLinkActiveService extends Observable { @Optional() @Inject(RouterLinkActive) routerLinkActive: RouterLinkActive | null, - @Inject(NgZone) ngZone: NgZone, + @Inject(NgZone) zone: NgZone, @Inject(ANIMATION_FRAME) animationFrame$: Observable, @Self() @Inject(TuiDestroyService) destroy$: TuiDestroyService, ) { @@ -23,7 +23,7 @@ export class TuiRouterLinkActiveService extends Observable { ).pipe( map(() => routerLinkActive.isActive), distinctUntilChanged(), - tuiZoneOptimized(ngZone), + tuiZoneOptimized(zone), takeUntil(destroy$), ) : EMPTY; diff --git a/projects/demo/src/modules/app/app.routes.ts b/projects/demo/src/modules/app/app.routes.ts index 6781f2f733d5..15f3861ef51b 100644 --- a/projects/demo/src/modules/app/app.routes.ts +++ b/projects/demo/src/modules/app/app.routes.ts @@ -206,6 +206,14 @@ export const ROUTES: Routes = [ title: `Avatar`, }, }, + { + path: `experimental/fade`, + loadChildren: async () => + (await import(`../experimental/fade/fade.module`)).ExampleTuiFadeModule, + data: { + title: `Fade`, + }, + }, { path: `navigation/breadcrumbs`, loadChildren: async () => diff --git a/projects/demo/src/modules/app/pages.ts b/projects/demo/src/modules/app/pages.ts index be1f53c89789..b0f71d713d88 100644 --- a/projects/demo/src/modules/app/pages.ts +++ b/projects/demo/src/modules/app/pages.ts @@ -821,6 +821,12 @@ export const pages = [ keywords: `аватар, image, pic, icon, картинка, изображение, avatar, stack`, route: `/experimental/avatar`, }, + { + section: `Experimental`, + title: `Fade`, + keywords: `overflow, ellipsis, gradient, clamp, line`, + route: `/experimental/fade`, + }, // Charts { section: `Charts`, diff --git a/projects/demo/src/modules/experimental/avatar/avatar.module.ts b/projects/demo/src/modules/experimental/avatar/avatar.module.ts index 1e6c44e2cc52..9ea6db368d92 100644 --- a/projects/demo/src/modules/experimental/avatar/avatar.module.ts +++ b/projects/demo/src/modules/experimental/avatar/avatar.module.ts @@ -2,6 +2,7 @@ import {CommonModule} from '@angular/common'; import {NgModule} from '@angular/core'; import {RouterModule} from '@angular/router'; import {TuiAddonDocModule, tuiGenerateRoutes} from '@taiga-ui/addon-doc'; +import {TuiNotificationModule} from '@taiga-ui/core'; import { TuiAutoColorModule, TuiAvatarModule, @@ -21,8 +22,9 @@ import {TuiAvatarExample3} from './examples/3'; TuiAvatarStackModule, TuiAutoColorModule, TuiAddonDocModule, - RouterModule.forChild(tuiGenerateRoutes(ExampleTuiAvatarComponent)), TuiInitialsModule, + TuiNotificationModule, + RouterModule.forChild(tuiGenerateRoutes(ExampleTuiAvatarComponent)), ], declarations: [ ExampleTuiAvatarComponent, diff --git a/projects/demo/src/modules/experimental/avatar/avatar.template.html b/projects/demo/src/modules/experimental/avatar/avatar.template.html index 5056417e8000..a11244b14559 100644 --- a/projects/demo/src/modules/experimental/avatar/avatar.template.html +++ b/projects/demo/src/modules/experimental/avatar/avatar.template.html @@ -4,7 +4,13 @@ type="components" > - New version for Avatar component following updated design specs for displaying text, pictures and icons. + + This code is + experimental + and is a subject to change. Expect final solution to be shipped in the next major version + + +

New version for Avatar component following updated design specs for displaying text, pictures and icons.

+ + I am a very long text that overflows with a single line fade + + diff --git a/projects/demo/src/modules/experimental/fade/examples/1/index.less b/projects/demo/src/modules/experimental/fade/examples/1/index.less new file mode 100644 index 000000000000..b7ac5d33a783 --- /dev/null +++ b/projects/demo/src/modules/experimental/fade/examples/1/index.less @@ -0,0 +1,14 @@ +@import 'taiga-ui-local'; + +.scrollbar { + width: 20rem; +} + +.fade { + .scrollbar-hidden(); + width: 100%; + height: 2rem; + font: var(--tui-font-heading-6); + white-space: nowrap; + overflow: auto; +} diff --git a/projects/demo/src/modules/experimental/fade/examples/1/index.ts b/projects/demo/src/modules/experimental/fade/examples/1/index.ts new file mode 100644 index 000000000000..3b289a3faa10 --- /dev/null +++ b/projects/demo/src/modules/experimental/fade/examples/1/index.ts @@ -0,0 +1,12 @@ +import {Component} from '@angular/core'; +import {changeDetection} from '@demo/emulate/change-detection'; +import {encapsulation} from '@demo/emulate/encapsulation'; + +@Component({ + selector: 'tui-fade-example-1', + templateUrl: './index.html', + styleUrls: ['./index.less'], + changeDetection, + encapsulation, +}) +export class TuiFadeExample1 {} diff --git a/projects/demo/src/modules/experimental/fade/examples/2/index.html b/projects/demo/src/modules/experimental/fade/examples/2/index.html new file mode 100644 index 000000000000..3f4024304aa9 --- /dev/null +++ b/projects/demo/src/modules/experimental/fade/examples/2/index.html @@ -0,0 +1,27 @@ +
+ + Daenerys of the House Targaryen, the First of Her Name, The Unburnt, Queen of the Andals, the Rhoynar and the + First Men, Queen of Meereen, Khaleesi of the Great Grass Sea, Protector of the Realm, Lady Regent of the Seven + Kingdoms, Breaker of Chains and Mother of Dragons. + + + +
diff --git a/projects/demo/src/modules/experimental/fade/examples/2/index.less b/projects/demo/src/modules/experimental/fade/examples/2/index.less new file mode 100644 index 000000000000..cb4763b099f1 --- /dev/null +++ b/projects/demo/src/modules/experimental/fade/examples/2/index.less @@ -0,0 +1,27 @@ +@import 'taiga-ui-local'; + +.wrapper { + position: relative; +} + +.fade { + .transition(height); + height: 3.75rem; + + &_expanded { + height: 8.75rem; + } +} + +.expand { + .transition(opacity, visibility); + position: absolute; + bottom: 0; + right: 0; + transition-delay: var(--tui-duration); + + &_hidden { + opacity: 0; + visibility: hidden; + } +} diff --git a/projects/demo/src/modules/experimental/fade/examples/2/index.ts b/projects/demo/src/modules/experimental/fade/examples/2/index.ts new file mode 100644 index 000000000000..b9bdfec0bc10 --- /dev/null +++ b/projects/demo/src/modules/experimental/fade/examples/2/index.ts @@ -0,0 +1,20 @@ +import {Component} from '@angular/core'; +import {changeDetection} from '@demo/emulate/change-detection'; +import {encapsulation} from '@demo/emulate/encapsulation'; +import {tuiFadeIn} from '@taiga-ui/core'; + +@Component({ + selector: 'tui-fade-example-2', + templateUrl: './index.html', + styleUrls: ['./index.less'], + animations: [tuiFadeIn], + changeDetection, + encapsulation, +}) +export class TuiFadeExample2 { + expanded = false; + + toggle(): void { + this.expanded = !this.expanded; + } +} diff --git a/projects/demo/src/modules/experimental/fade/examples/3/index.html b/projects/demo/src/modules/experimental/fade/examples/3/index.html new file mode 100644 index 000000000000..f46e09d85013 --- /dev/null +++ b/projects/demo/src/modules/experimental/fade/examples/3/index.html @@ -0,0 +1,11 @@ + + + Daenerys of the House Targaryen, the First of Her Name, The Unburnt, Queen of the Andals, the Rhoynar and the + First Men, Queen of Meereen, Khaleesi of the Great Grass Sea, Protector of the Realm, Lady Regent of the Seven + Kingdoms, Breaker of Chains and Mother of Dragons. + + diff --git a/projects/demo/src/modules/experimental/fade/examples/3/index.less b/projects/demo/src/modules/experimental/fade/examples/3/index.less new file mode 100644 index 000000000000..6a11e3f904c0 --- /dev/null +++ b/projects/demo/src/modules/experimental/fade/examples/3/index.less @@ -0,0 +1,9 @@ +@import 'taiga-ui-local'; + +.fade { + .scrollbar-hidden(); + width: 17rem; + height: 10rem; + font: var(--tui-font-text-l); + overflow: auto; +} diff --git a/projects/demo/src/modules/experimental/fade/examples/3/index.ts b/projects/demo/src/modules/experimental/fade/examples/3/index.ts new file mode 100644 index 000000000000..6003d7556aae --- /dev/null +++ b/projects/demo/src/modules/experimental/fade/examples/3/index.ts @@ -0,0 +1,14 @@ +import {Component} from '@angular/core'; +import {changeDetection} from '@demo/emulate/change-detection'; +import {encapsulation} from '@demo/emulate/encapsulation'; + +@Component({ + selector: 'tui-fade-example-3', + templateUrl: './index.html', + styleUrls: ['./index.less'], + changeDetection, + encapsulation, +}) +export class TuiFadeExample3 { + readonly names = ['Jason Statham', 'Silvester Stallone', 'Jackie Chan']; +} diff --git a/projects/demo/src/modules/experimental/fade/examples/import/import-module.md b/projects/demo/src/modules/experimental/fade/examples/import/import-module.md new file mode 100644 index 000000000000..e09b36f3c960 --- /dev/null +++ b/projects/demo/src/modules/experimental/fade/examples/import/import-module.md @@ -0,0 +1,13 @@ +```ts +import {NgModule} from '@angular/core'; +import {TuiFadeModule} from '@taiga-ui/experimental'; +// ... + +@NgModule({ + imports: [ + // ... + TuiFadeModule, + ], +}) +export class MyModule {} +``` diff --git a/projects/demo/src/modules/experimental/fade/examples/import/insert-template.md b/projects/demo/src/modules/experimental/fade/examples/import/insert-template.md new file mode 100644 index 000000000000..0e7bd8634c04 --- /dev/null +++ b/projects/demo/src/modules/experimental/fade/examples/import/insert-template.md @@ -0,0 +1,5 @@ +```html + + + +``` diff --git a/projects/demo/src/modules/experimental/fade/fade.component.ts b/projects/demo/src/modules/experimental/fade/fade.component.ts new file mode 100644 index 000000000000..00be108d17c8 --- /dev/null +++ b/projects/demo/src/modules/experimental/fade/fade.component.ts @@ -0,0 +1,39 @@ +import {Component} from '@angular/core'; +import {changeDetection} from '@demo/emulate/change-detection'; +import {RawLoaderContent, TuiDocExample} from '@taiga-ui/addon-doc'; + +@Component({ + selector: 'example-fade', + templateUrl: './fade.template.html', + styleUrls: ['./fade.style.less'], + changeDetection, +}) +export class ExampleTuiFadeComponent { + readonly exampleModule: RawLoaderContent = import( + './examples/import/import-module.md?raw' + ); + + readonly exampleHtml: RawLoaderContent = import( + './examples/import/insert-template.md?raw' + ); + + readonly example1: TuiDocExample = { + TypeScript: import('./examples/1/index.ts?raw'), + HTML: import('./examples/1/index.html?raw'), + }; + + readonly example2: TuiDocExample = { + TypeScript: import('./examples/2/index.ts?raw'), + HTML: import('./examples/2/index.html?raw'), + LESS: import('./examples/2/index.less?raw'), + }; + + readonly example3: TuiDocExample = { + TypeScript: import('./examples/3/index.ts?raw'), + HTML: import('./examples/3/index.html?raw'), + }; + + lineHeight = '100%'; + size = '1.5em'; + offset = '0em'; +} diff --git a/projects/demo/src/modules/experimental/fade/fade.module.ts b/projects/demo/src/modules/experimental/fade/fade.module.ts new file mode 100644 index 000000000000..a66071c8a8e8 --- /dev/null +++ b/projects/demo/src/modules/experimental/fade/fade.module.ts @@ -0,0 +1,31 @@ +import {CommonModule} from '@angular/common'; +import {NgModule} from '@angular/core'; +import {RouterModule} from '@angular/router'; +import {TuiAddonDocModule, tuiGenerateRoutes} from '@taiga-ui/addon-doc'; +import {TuiLinkModule, TuiNotificationModule, TuiScrollbarModule} from '@taiga-ui/core'; +import {TuiFadeModule} from '@taiga-ui/experimental'; + +import {TuiFadeExample1} from './examples/1'; +import {TuiFadeExample2} from './examples/2'; +import {TuiFadeExample3} from './examples/3'; +import {ExampleTuiFadeComponent} from './fade.component'; + +@NgModule({ + imports: [ + CommonModule, + TuiFadeModule, + TuiNotificationModule, + TuiScrollbarModule, + TuiLinkModule, + TuiAddonDocModule, + RouterModule.forChild(tuiGenerateRoutes(ExampleTuiFadeComponent)), + ], + declarations: [ + ExampleTuiFadeComponent, + TuiFadeExample1, + TuiFadeExample2, + TuiFadeExample3, + ], + exports: [ExampleTuiFadeComponent], +}) +export class ExampleTuiFadeModule {} diff --git a/projects/demo/src/modules/experimental/fade/fade.style.less b/projects/demo/src/modules/experimental/fade/fade.style.less new file mode 100644 index 000000000000..e3cf1f458923 --- /dev/null +++ b/projects/demo/src/modules/experimental/fade/fade.style.less @@ -0,0 +1,4 @@ +.fade { + font: var(--tui-font-heading-6); + white-space: nowrap; +} diff --git a/projects/demo/src/modules/experimental/fade/fade.template.html b/projects/demo/src/modules/experimental/fade/fade.template.html new file mode 100644 index 000000000000..88492420c137 --- /dev/null +++ b/projects/demo/src/modules/experimental/fade/fade.template.html @@ -0,0 +1,113 @@ + + + + This code is + experimental + and is a subject to change. Expect final solution to be shipped in the next major version + + +

Wrapper that uses masking to fade out overflown content

+ + + + + + + + + + + + +
+ + + + + I am a very long text with + white-space: nowrap + that fades + + + + + Line height (required for multiline text fade) + + + Offset from the edge for the fade to start + + + Size of the fade + + + Orientation of the fade + + + + + +
    +
  1. +

    + Import + TuiFadeModule + into a module where you want to use our component +

    + + +
  2. + +
  3. +

    Add to the template:

    + + +
  4. +
+
+
diff --git a/projects/experimental/components/avatar/avatar.module.ts b/projects/experimental/components/avatar/avatar.module.ts index 066359d9f73c..8add5abb9ddd 100644 --- a/projects/experimental/components/avatar/avatar.module.ts +++ b/projects/experimental/components/avatar/avatar.module.ts @@ -1,7 +1,7 @@ import {CommonModule} from '@angular/common'; import {NgModule} from '@angular/core'; import {TuiSvgModule} from '@taiga-ui/core'; -import {TuiTextModule} from '@taiga-ui/experimental/components/text'; +import {TuiFadeModule} from '@taiga-ui/experimental/components/fade'; import {TuiFallbackSrcModule, TuiFallbackSrcPipe} from '@taiga-ui/experimental/pipes'; import {TuiLazyLoadingModule} from '@taiga-ui/kit'; @@ -13,7 +13,7 @@ import {TuiAvatarComponent} from './avatar.component'; TuiSvgModule, TuiLazyLoadingModule, TuiFallbackSrcModule, - TuiTextModule, + TuiFadeModule, ], declarations: [TuiAvatarComponent], exports: [TuiAvatarComponent, TuiFallbackSrcPipe], diff --git a/projects/experimental/components/avatar/avatar.template.html b/projects/experimental/components/avatar/avatar.template.html index 2aa9212d97b1..437b6d5821b4 100644 --- a/projects/experimental/components/avatar/avatar.template.html +++ b/projects/experimental/components/avatar/avatar.template.html @@ -17,11 +17,11 @@ class="t-img" [src]="value" /> - - + diff --git a/projects/experimental/components/fade/fade.component.ts b/projects/experimental/components/fade/fade.component.ts new file mode 100644 index 000000000000..d2364bf30ccc --- /dev/null +++ b/projects/experimental/components/fade/fade.component.ts @@ -0,0 +1,76 @@ +import { + ChangeDetectionStrategy, + Component, + ElementRef, + HostBinding, + Inject, + Input, + NgZone, + Self, +} from '@angular/core'; +import { + MUTATION_OBSERVER_INIT, + MutationObserverService, +} from '@ng-web-apis/mutation-observer'; +import {TuiDestroyService, TuiResizeService, tuiZonefree} from '@taiga-ui/cdk'; +import {TuiOrientation} from '@taiga-ui/core'; +import {fromEvent, merge, Observable} from 'rxjs'; +import {takeUntil} from 'rxjs/operators'; + +@Component({ + selector: 'tui-fade', + template: '', + styleUrls: ['./fade.style.less'], + changeDetection: ChangeDetectionStrategy.OnPush, + providers: [ + TuiDestroyService, + TuiResizeService, + MutationObserverService, + { + provide: MUTATION_OBSERVER_INIT, + useValue: {characterData: true, subtree: true}, + }, + ], +}) +export class TuiFadeComponent { + @Input() + @HostBinding('style.--line-height') + lineHeight = '100%'; + + @Input() + @HostBinding('style.--fade-size') + size = '1.5em'; + + @Input() + @HostBinding('style.--fade-offset') + offset = '0em'; + + @Input() + @HostBinding('attr.data-orientation') + orientation: TuiOrientation = 'horizontal'; + + constructor( + @Self() @Inject(TuiDestroyService) destroy$: Observable, + @Inject(TuiResizeService) resize$: Observable, + @Inject(MutationObserverService) mutate$: Observable, + @Inject(ElementRef) element: ElementRef, + @Inject(NgZone) zone: NgZone, + ) { + const el = element.nativeElement; + + merge(resize$, mutate$, fromEvent(el, 'scroll')) + .pipe(tuiZonefree(zone), takeUntil(destroy$)) + .subscribe(() => { + el.classList.toggle('_start', !!el.scrollLeft || !!el.scrollTop); + el.classList.toggle('_end', this.isEnd(el)); + }); + } + + private isEnd(el: HTMLElement): boolean { + return ( + el.scrollLeft < el.scrollWidth - el.clientWidth || + el.scrollTop < el.scrollHeight - el.clientHeight || + (this.orientation === 'horizontal' && el.scrollHeight > el.clientHeight) + ); + } +} diff --git a/projects/experimental/components/fade/fade.module.ts b/projects/experimental/components/fade/fade.module.ts new file mode 100644 index 000000000000..c105f459c1be --- /dev/null +++ b/projects/experimental/components/fade/fade.module.ts @@ -0,0 +1,9 @@ +import {NgModule} from '@angular/core'; + +import {TuiFadeComponent} from './fade.component'; + +@NgModule({ + declarations: [TuiFadeComponent], + exports: [TuiFadeComponent], +}) +export class TuiFadeModule {} diff --git a/projects/experimental/components/fade/fade.style.less b/projects/experimental/components/fade/fade.style.less new file mode 100644 index 000000000000..3f354e2cf2b9 --- /dev/null +++ b/projects/experimental/components/fade/fade.style.less @@ -0,0 +1,68 @@ +@import 'taiga-ui-local'; + +// prettier-ignore +:host { + .transition(mask-position); + display: block; + overflow: hidden; + mask-repeat: no-repeat; + + &[data-orientation='horizontal'] { + line-height: var(--line-height) !important; + mask-image: + linear-gradient(to right, transparent var(--fade-offset), #000 calc(var(--fade-size) + var(--fade-offset))), + linear-gradient(to left, transparent var(--fade-offset), #000 calc(var(--fade-size) + var(--fade-offset))), + linear-gradient(#000, #000); + mask-position: + calc(-1 * var(--fade-size) - var(--fade-offset)) bottom, + calc(100% + var(--fade-size) + var(--fade-offset)) bottom, + top; + mask-size: + calc(50% + var(--fade-size) + var(--fade-offset)) var(--line-height), + calc(50% + var(--fade-size) + var(--fade-offset)) var(--line-height), + 100% calc(100% - var(--line-height)); + + &._start { + mask-position: + left bottom, + calc(100% + var(--fade-size) + var(--fade-offset)) bottom, + top; + } + + &._end { + mask-position: + calc(-1 * var(--fade-size) - var(--fade-offset)) bottom, + right bottom, + top; + } + + &._start._end { + mask-position: + left bottom, + right bottom, + top; + } + } + + &[data-orientation='vertical'] { + mask-image: + linear-gradient(to bottom, transparent var(--fade-offset), #000 calc(var(--fade-size) + var(--fade-offset))), + linear-gradient(to top, transparent var(--fade-offset), #000 calc(var(--fade-size) + var(--fade-offset))); + mask-position: + left calc(-1 * var(--fade-size) - var(--fade-offset)), + left calc(100% + var(--fade-size) + var(--fade-offset)); + mask-size: 100% calc(50% + var(--fade-size) + var(--fade-offset)); + + &._start { + mask-position: left top, left calc(100% + var(--fade-size) + var(--fade-offset)); + } + + &._end { + mask-position: left calc(-1 * var(--fade-size) - var(--fade-offset)), left bottom; + } + + &._start._end { + mask-position: left top, left bottom; + } + } +} diff --git a/projects/experimental/components/fade/index.ts b/projects/experimental/components/fade/index.ts new file mode 100644 index 000000000000..3b4b8795b9c8 --- /dev/null +++ b/projects/experimental/components/fade/index.ts @@ -0,0 +1,2 @@ +export * from './fade.component'; +export * from './fade.module'; diff --git a/projects/experimental/components/text/ng-package.json b/projects/experimental/components/fade/ng-package.json similarity index 100% rename from projects/experimental/components/text/ng-package.json rename to projects/experimental/components/fade/ng-package.json diff --git a/projects/experimental/components/index.ts b/projects/experimental/components/index.ts index 92fd4c77361b..e570b5d0807d 100644 --- a/projects/experimental/components/index.ts +++ b/projects/experimental/components/index.ts @@ -1,3 +1,3 @@ export * from '@taiga-ui/experimental/components/avatar'; export * from '@taiga-ui/experimental/components/avatar-stack'; -export * from '@taiga-ui/experimental/components/text'; +export * from '@taiga-ui/experimental/components/fade'; diff --git a/projects/experimental/components/text/index.ts b/projects/experimental/components/text/index.ts deleted file mode 100644 index 0b7dab4e1030..000000000000 --- a/projects/experimental/components/text/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from './text.component'; -export * from './text.module'; diff --git a/projects/experimental/components/text/text.component.ts b/projects/experimental/components/text/text.component.ts deleted file mode 100644 index 77a834796944..000000000000 --- a/projects/experimental/components/text/text.component.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { - ChangeDetectionStrategy, - Component, - ElementRef, - HostBinding, - Inject, - Input, - Self, -} from '@angular/core'; -import { - MUTATION_OBSERVER_INIT, - MutationObserverService, -} from '@ng-web-apis/mutation-observer'; -import {TuiDestroyService, TuiResizeService} from '@taiga-ui/cdk'; -import {merge, Observable} from 'rxjs'; -import {map, takeUntil} from 'rxjs/operators'; - -@Component({ - selector: 'tui-text', - template: '', - styleUrls: ['./text.style.less'], - changeDetection: ChangeDetectionStrategy.OnPush, - providers: [ - TuiDestroyService, - TuiResizeService, - MutationObserverService, - { - provide: MUTATION_OBSERVER_INIT, - useValue: {characterData: true, subtree: true}, - }, - ], -}) -export class TuiTextComponent { - @Input() - @HostBinding('style.--line-height') - lineHeight = '1.5rem'; - - @Input() - @HostBinding('style.--fade-size') - fadeSize = '1.5em'; - - constructor( - @Self() @Inject(TuiDestroyService) destroy$: Observable, - @Inject(TuiResizeService) resize$: Observable, - @Inject(MutationObserverService) mutate$: Observable, - @Inject(ElementRef) element: ElementRef, - ) { - const el = element.nativeElement; - - merge(resize$, mutate$) - .pipe( - map( - () => - el.scrollWidth > el.clientWidth || - el.scrollHeight > el.clientHeight, - ), - takeUntil(destroy$), - ) - .subscribe(overflown => { - el.classList.toggle('_overflown', overflown); - }); - } -} diff --git a/projects/experimental/components/text/text.module.ts b/projects/experimental/components/text/text.module.ts deleted file mode 100644 index fafc0deb3725..000000000000 --- a/projects/experimental/components/text/text.module.ts +++ /dev/null @@ -1,9 +0,0 @@ -import {NgModule} from '@angular/core'; - -import {TuiTextComponent} from './text.component'; - -@NgModule({ - declarations: [TuiTextComponent], - exports: [TuiTextComponent], -}) -export class TuiTextModule {} diff --git a/projects/experimental/components/text/text.style.less b/projects/experimental/components/text/text.style.less deleted file mode 100644 index e9ed68039445..000000000000 --- a/projects/experimental/components/text/text.style.less +++ /dev/null @@ -1,13 +0,0 @@ -:host { - mask-size: - 100% var(--line-height), - 100% calc(100% - var(--line-height)); - mask-position: bottom, top; - mask-repeat: no-repeat; - overflow: hidden; - line-height: var(--line-height) !important; - - &._overflown { - mask-image: linear-gradient(to left, transparent, #000 var(--fade-size)), linear-gradient(#000, #000); - } -} 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 3299ab80d5d7..676cf96d091e 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 @@ -12,12 +12,12 @@ export class TuiItemsWithMoreService extends Observable { throttleTime(0), map(() => this.getOverflowIndex()), distinctUntilChanged(), - tuiZoneOptimized(this.ngZone), + tuiZoneOptimized(this.zone), share(), ); constructor( - @Inject(NgZone) private readonly ngZone: NgZone, + @Inject(NgZone) private readonly zone: NgZone, @Inject(ElementRef) private readonly el: ElementRef, @Inject(MutationObserverService) private readonly mutation$: Observable, @Inject(TuiResizeService) private readonly resize$: Observable, diff --git a/projects/kit/components/line-clamp/line-clamp.component.ts b/projects/kit/components/line-clamp/line-clamp.component.ts index 5a1fa57c8312..a5d105e8f99f 100644 --- a/projects/kit/components/line-clamp/line-clamp.component.ts +++ b/projects/kit/components/line-clamp/line-clamp.component.ts @@ -82,7 +82,7 @@ export class TuiLineClampComponent implements DoCheck, AfterViewInit { @Inject(ElementRef) private readonly el: ElementRef, @Inject(Renderer2) private readonly renderer: Renderer2, @Inject(ChangeDetectorRef) private readonly cd: ChangeDetectorRef, - @Inject(NgZone) private readonly ngZone: NgZone, + @Inject(NgZone) private readonly zone: NgZone, @Inject(TUI_LINE_CLAMP_OPTIONS) private readonly options: TuiLineClampOptions, ) { this.skipInitialTransition(); @@ -120,7 +120,7 @@ export class TuiLineClampComponent implements DoCheck, AfterViewInit { private skipInitialTransition(): void { timer(0) - .pipe(tuiZonefree(this.ngZone)) + .pipe(tuiZonefree(this.zone)) .subscribe(() => { this.renderer.addClass(this.el.nativeElement, '_initialized'); this.cd.detectChanges(); diff --git a/projects/kit/components/tabs/underline/underline.component.ts b/projects/kit/components/tabs/underline/underline.component.ts index 5e8489aaa2e8..646caccd2d96 100644 --- a/projects/kit/components/tabs/underline/underline.component.ts +++ b/projects/kit/components/tabs/underline/underline.component.ts @@ -32,7 +32,7 @@ export class TuiUnderlineComponent { element ? this.animationFrame$.pipe( map(() => element), - tuiZonefree(this.ngZone), + tuiZonefree(this.zone), ) : of(null), ), @@ -68,7 +68,7 @@ export class TuiUnderlineComponent { constructor( @Inject(ElementRef) {nativeElement}: ElementRef, - @Inject(NgZone) private readonly ngZone: NgZone, + @Inject(NgZone) private readonly zone: NgZone, @Inject(ANIMATION_FRAME) private readonly animationFrame$: Observable, @Inject(TUI_MODE) readonly mode$: Observable, ) { diff --git a/projects/kit/components/tiles/tile.component.ts b/projects/kit/components/tiles/tile.component.ts index 12306f5bde46..710e2c8d4fab 100644 --- a/projects/kit/components/tiles/tile.component.ts +++ b/projects/kit/components/tiles/tile.component.ts @@ -45,11 +45,11 @@ export class TuiTileComponent implements OnDestroy { width: this.element.clientWidth, height: this.element.clientHeight, })), - tuiZonefull(this.ngZone), + tuiZonefull(this.zone), ); constructor( - @Inject(NgZone) private readonly ngZone: NgZone, + @Inject(NgZone) private readonly zone: NgZone, @Inject(ElementRef) private readonly el: ElementRef, @Inject(TuiTilesComponent) private readonly tiles: TuiTilesComponent, @Inject(TuiResizeService) private readonly resize$: Observable, From 4646e02f35f4108a6b9aec38bdaac8ecb75c4618 Mon Sep 17 00:00:00 2001 From: taiga-family-bot Date: Tue, 22 Aug 2023 19:34:02 +0000 Subject: [PATCH 2/3] chore: apply changes after linting [bot] --- .../demo/src/modules/experimental/fade/examples/3/index.html | 2 +- projects/demo/src/modules/experimental/fade/fade.template.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/projects/demo/src/modules/experimental/fade/examples/3/index.html b/projects/demo/src/modules/experimental/fade/examples/3/index.html index f46e09d85013..9de9fbfb12f4 100644 --- a/projects/demo/src/modules/experimental/fade/examples/3/index.html +++ b/projects/demo/src/modules/experimental/fade/examples/3/index.html @@ -1,7 +1,7 @@ Daenerys of the House Targaryen, the First of Her Name, The Unburnt, Queen of the Andals, the Rhoynar and the diff --git a/projects/demo/src/modules/experimental/fade/fade.template.html b/projects/demo/src/modules/experimental/fade/fade.template.html index 88492420c137..fb0c3b4452d0 100644 --- a/projects/demo/src/modules/experimental/fade/fade.template.html +++ b/projects/demo/src/modules/experimental/fade/fade.template.html @@ -42,8 +42,8 @@ I am a very long text with white-space: nowrap From 785b6cd870eaae5b8e8d31c50466efb3254a307a Mon Sep 17 00:00:00 2001 From: waterplea Date: Wed, 23 Aug 2023 14:33:48 -0500 Subject: [PATCH 3/3] chore: comments --- .../demo/src/modules/experimental/fade/examples/2/index.less | 2 +- .../demo/src/modules/experimental/fade/examples/3/index.ts | 4 +--- projects/demo/src/modules/experimental/fade/fade.component.ts | 1 + 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/projects/demo/src/modules/experimental/fade/examples/2/index.less b/projects/demo/src/modules/experimental/fade/examples/2/index.less index cb4763b099f1..dbcc5728b65c 100644 --- a/projects/demo/src/modules/experimental/fade/examples/2/index.less +++ b/projects/demo/src/modules/experimental/fade/examples/2/index.less @@ -9,7 +9,7 @@ height: 3.75rem; &_expanded { - height: 8.75rem; + height: 10rem; } } diff --git a/projects/demo/src/modules/experimental/fade/examples/3/index.ts b/projects/demo/src/modules/experimental/fade/examples/3/index.ts index 6003d7556aae..adfc6c13dbbb 100644 --- a/projects/demo/src/modules/experimental/fade/examples/3/index.ts +++ b/projects/demo/src/modules/experimental/fade/examples/3/index.ts @@ -9,6 +9,4 @@ import {encapsulation} from '@demo/emulate/encapsulation'; changeDetection, encapsulation, }) -export class TuiFadeExample3 { - readonly names = ['Jason Statham', 'Silvester Stallone', 'Jackie Chan']; -} +export class TuiFadeExample3 {} diff --git a/projects/demo/src/modules/experimental/fade/fade.component.ts b/projects/demo/src/modules/experimental/fade/fade.component.ts index 00be108d17c8..cfff0ea505fd 100644 --- a/projects/demo/src/modules/experimental/fade/fade.component.ts +++ b/projects/demo/src/modules/experimental/fade/fade.component.ts @@ -31,6 +31,7 @@ export class ExampleTuiFadeComponent { readonly example3: TuiDocExample = { TypeScript: import('./examples/3/index.ts?raw'), HTML: import('./examples/3/index.html?raw'), + LESS: import('./examples/3/index.less?raw'), }; lineHeight = '100%';