From 960d64b8e143796c7db5d6083e79909d728015d5 Mon Sep 17 00:00:00 2001 From: splincode Date: Mon, 30 Sep 2024 18:00:57 +0300 Subject: [PATCH] feat(core): support using native scrollbar --- .../core/components/root/root.component.ts | 32 ++++++++---- projects/core/components/root/root.style.less | 1 - .../scrollbar/scroll-controls.component.ts | 3 ++ .../scrollbar/scroll-controls.template.html | 51 ++++++++++--------- .../scrollbar/scrollbar.component.ts | 9 ++-- .../components/scrollbar/scrollbar.options.ts | 18 ++----- .../scrollbar/scrollbar.template.html | 2 +- .../scrollbar/examples/6/index.html | 3 +- .../components/scrollbar/examples/6/index.ts | 6 ++- .../scrollbar/examples/8/index.html | 50 ++++++++++++++++++ .../scrollbar/examples/8/index.less | 13 +++++ .../components/scrollbar/examples/8/index.ts | 19 +++++++ .../src/modules/components/scrollbar/index.ts | 1 + 13 files changed, 152 insertions(+), 56 deletions(-) create mode 100644 projects/demo/src/modules/components/scrollbar/examples/8/index.html create mode 100644 projects/demo/src/modules/components/scrollbar/examples/8/index.less create mode 100644 projects/demo/src/modules/components/scrollbar/examples/8/index.ts diff --git a/projects/core/components/root/root.component.ts b/projects/core/components/root/root.component.ts index 00d7dad427025..1f87b69f84ed7 100644 --- a/projects/core/components/root/root.component.ts +++ b/projects/core/components/root/root.component.ts @@ -16,7 +16,10 @@ import {tuiWatch, tuiZonefreeScheduler} from '@taiga-ui/cdk/observables'; import {TUI_IS_MOBILE} from '@taiga-ui/cdk/tokens'; import {TuiAlerts} from '@taiga-ui/core/components/alert'; import {TUI_DIALOGS, TuiDialogs} from '@taiga-ui/core/components/dialog'; -import {TuiScrollControls} from '@taiga-ui/core/components/scrollbar'; +import { + TUI_SCROLLBAR_OPTIONS, + TuiScrollControls, +} from '@taiga-ui/core/components/scrollbar'; import {TuiDropdowns} from '@taiga-ui/core/directives'; import {TuiHints} from '@taiga-ui/core/directives/hint'; import {TuiBreakpointService} from '@taiga-ui/core/services'; @@ -57,15 +60,18 @@ export class TuiRoot { {initialValue: false}, ); - protected readonly scrollbars = inject(TUI_IS_MOBILE) - ? signal(false) - : toSignal( - inject>(TUI_DIALOGS).pipe( - map(({length}) => !length), - debounceTime(0, tuiZonefreeScheduler()), - ), - {initialValue: false}, - ); + protected readonly nativeScrollbar = inject(TUI_SCROLLBAR_OPTIONS).mode === 'native'; + + protected readonly scrollbars = + this.nativeScrollbar || inject(TUI_IS_MOBILE) + ? signal(false) + : toSignal( + inject>(TUI_DIALOGS).pipe( + map(({length}) => !length), + debounceTime(0, tuiZonefreeScheduler()), + ), + {initialValue: false}, + ); constructor() { inject(DOCUMENT).documentElement.setAttribute( @@ -73,6 +79,12 @@ export class TuiRoot { inject(TUI_THEME).toLowerCase(), ); + if (!this.nativeScrollbar) { + inject(DOCUMENT).defaultView?.document.documentElement.classList.add( + 'tui-zero-scrollbar', + ); + } + ngDevMode && console.assert( !!inject(EVENT_MANAGER_PLUGINS).find( diff --git a/projects/core/components/root/root.style.less b/projects/core/components/root/root.style.less index bd5b193a3d9e7..5d14f041309c8 100644 --- a/projects/core/components/root/root.style.less +++ b/projects/core/components/root/root.style.less @@ -13,7 +13,6 @@ } } -html[data-tui-theme], .tui-zero-scrollbar { .scrollbar-hidden(); } diff --git a/projects/core/components/scrollbar/scroll-controls.component.ts b/projects/core/components/scrollbar/scroll-controls.component.ts index f2dff9b5ae722..262670622759b 100644 --- a/projects/core/components/scrollbar/scroll-controls.component.ts +++ b/projects/core/components/scrollbar/scroll-controls.component.ts @@ -8,6 +8,7 @@ import {tuiToAnimationOptions} from '@taiga-ui/core/utils'; import {distinctUntilChanged, map, startWith, throttleTime} from 'rxjs'; import {TuiScrollbarDirective} from './scrollbar.directive'; +import {TUI_SCROLLBAR_OPTIONS} from './scrollbar.options'; @Component({ standalone: true, @@ -21,7 +22,9 @@ import {TuiScrollbarDirective} from './scrollbar.directive'; export class TuiScrollControls { private readonly scrollRef = inject(TUI_SCROLL_REF).nativeElement; + protected readonly nativeScrollbar = inject(TUI_SCROLLBAR_OPTIONS).mode === 'native'; protected readonly options = tuiToAnimationOptions(inject(TUI_ANIMATIONS_SPEED)); + protected readonly refresh$ = inject(WA_ANIMATION_FRAME).pipe( throttleTime(300, tuiZonefreeScheduler()), map(() => this.scrollbars), diff --git a/projects/core/components/scrollbar/scroll-controls.template.html b/projects/core/components/scrollbar/scroll-controls.template.html index 3efff73548647..3cc6eea4a5e53 100644 --- a/projects/core/components/scrollbar/scroll-controls.template.html +++ b/projects/core/components/scrollbar/scroll-controls.template.html @@ -1,26 +1,29 @@ - -
+ + +
-
-
+ *ngIf="bars[0]" + class="t-bar t-bar_vertical" + [@tuiFadeIn]="options" + [class.t-bar_has-horizontal]="bars[1]" + (mousedown.capture.prevent)="(0)" + > +
+
- -
+ *ngIf="bars[1]" + class="t-bar t-bar_horizontal" + [@tuiFadeIn]="options" + [class.t-bar_has-vertical]="bars[0]" + (mousedown.capture.prevent)="(0)" + > +
+ + + diff --git a/projects/core/components/scrollbar/scrollbar.component.ts b/projects/core/components/scrollbar/scrollbar.component.ts index 0fc184a85ba29..82aa499c02cdd 100644 --- a/projects/core/components/scrollbar/scrollbar.component.ts +++ b/projects/core/components/scrollbar/scrollbar.component.ts @@ -38,7 +38,7 @@ export const TUI_SCROLLABLE = 'tui-scrollable'; }, ], host: { - '[class._native-hidden]': '!isIOS || hidden', + '[class._native-hidden]': 'options.mode !== "native" && (!isIOS || hidden)', [`(${TUI_SCROLLABLE}.stop)`]: 'scrollRef = $event.detail', [`(${TUI_SCROLL_INTO_VIEW}.stop)`]: 'scrollIntoView($event.detail)', }, @@ -50,11 +50,14 @@ export class TuiScrollbar { protected readonly isIOS = inject(TUI_IS_IOS); protected readonly browserScrollRef = new ElementRef(this.el); + /** + * @deprecated: use tuiScrollbarOptionsProvider({ mode: 'hidden' }) + */ @Input() - public hidden = false; + public hidden = this.options.mode === 'hidden'; protected get delegated(): boolean { - return this.scrollRef !== this.el; + return this.scrollRef !== this.el || this.options.mode === 'native'; } protected get scrollRef(): HTMLElement { diff --git a/projects/core/components/scrollbar/scrollbar.options.ts b/projects/core/components/scrollbar/scrollbar.options.ts index d91cc59cd76bf..fef21043fe3af 100644 --- a/projects/core/components/scrollbar/scrollbar.options.ts +++ b/projects/core/components/scrollbar/scrollbar.options.ts @@ -1,22 +1,12 @@ -import type {Provider} from '@angular/core'; -import {tuiCreateToken, tuiProvideOptions} from '@taiga-ui/cdk/utils/miscellaneous'; +import {tuiCreateOptions} from '@taiga-ui/cdk/utils/di'; export interface TuiScrollbarOptions { - mode: 'always' | 'hover'; + mode: 'always' | 'hidden' | 'hover' | 'native'; } export const TUI_DEFAULT_SCROLLBAR_OPTIONS: TuiScrollbarOptions = { mode: 'always', }; -export const TUI_SCROLLBAR_OPTIONS = tuiCreateToken(TUI_DEFAULT_SCROLLBAR_OPTIONS); - -export function tuiScrollbarOptionsProvider( - options: Partial, -): Provider { - return tuiProvideOptions( - TUI_SCROLLBAR_OPTIONS, - options, - TUI_DEFAULT_SCROLLBAR_OPTIONS, - ); -} +export const [TUI_SCROLLBAR_OPTIONS, tuiScrollbarOptionsProvider] = + tuiCreateOptions(TUI_DEFAULT_SCROLLBAR_OPTIONS); diff --git a/projects/core/components/scrollbar/scrollbar.template.html b/projects/core/components/scrollbar/scrollbar.template.html index f78c321491db3..858feeb0f80e7 100644 --- a/projects/core/components/scrollbar/scrollbar.template.html +++ b/projects/core/components/scrollbar/scrollbar.template.html @@ -1,5 +1,5 @@ diff --git a/projects/demo/src/modules/components/scrollbar/examples/6/index.html b/projects/demo/src/modules/components/scrollbar/examples/6/index.html index 386bc9bb8bf16..83cfff7696c87 100644 --- a/projects/demo/src/modules/components/scrollbar/examples/6/index.html +++ b/projects/demo/src/modules/components/scrollbar/examples/6/index.html @@ -9,7 +9,8 @@ appendOnly itemSize="50" tuiScrollable - class="example-viewport tui-zero-scrollbar" + class="example-viewport" + [class.tui-zero-scrollbar]="!nativeScrollbar" >
`Item #${i}`); protected add(): void { diff --git a/projects/demo/src/modules/components/scrollbar/examples/8/index.html b/projects/demo/src/modules/components/scrollbar/examples/8/index.html new file mode 100644 index 0000000000000..24bd1c125fb79 --- /dev/null +++ b/projects/demo/src/modules/components/scrollbar/examples/8/index.html @@ -0,0 +1,50 @@ + +
+

+ Lorem ipsum dolor sit amet, consectetur adipisicing elit. Deleniti dignissimos, doloremque. Aperiam + assumenda atque aut blanditiis corporis, eum, facilis harum laudantium magni necessitatibus nobis quas + repudiandae sint ut voluptatem! Optio. +

+

+ Accusamus aperiam assumenda aut consectetur, corporis delectus, dolor eaque eius est hic impedit labore + possimus provident quas rem, rerum sequi sint tempora tempore ut? Debitis esse neque odio odit provident? +

+

+ Cum eum illo, ipsa iure nostrum ut voluptates? Autem blanditiis corporis debitis deserunt ex expedita + facilis fuga, illum iusto magnam praesentium provident recusandae repudiandae, totam, voluptatem. Minima + numquam sapiente sunt. +

+

+ Beatae consectetur cupiditate dignissimos ducimus eos excepturi labore pariatur placeat quia similique. + Architecto aspernatur cumque debitis distinctio esse, facere fugit harum ipsum libero minus neque numquam + omnis quidem, tempora, ut! +

+

+ Mollitia, perspiciatis sunt! Architecto aspernatur assumenda beatae, blanditiis commodi consequuntur debitis + et id, laboriosam maxime molestiae neque nihil officiis omnis, quam quos sint veritatis voluptate? Alias + deserunt distinctio modi perferendis? +

+

+ Ab aspernatur aut cumque cupiditate deleniti, dolorem ducimus eligendi eos facere harum hic ipsam ipsum iste + itaque modi nam necessitatibus nostrum nulla omnis quae repellat, sapiente sit tempore. Ipsam, quidem! +

+

+ Ab debitis deleniti distinctio est ex facere magni nemo numquam placeat quia, quibusdam sequi! Aliquid at + consectetur culpa ea enim facilis, harum hic, inventore iste possimus praesentium quas tempora voluptates. +

+

+ Aliquam eligendi ipsam modi nemo numquam obcaecati officia, quidem unde? Accusantium amet, animi deleniti + dolorum ea earum eos, expedita ipsa minima modi, pariatur perspiciatis porro quibusdam quo repellat tempore + voluptates! +

+

+ Ab assumenda fugiat magni natus officiis perferendis ratione rem repellendus tenetur. At commodi laudantium + modi, natus nobis nulla odio odit sed sint tempora tenetur voluptas? At odio praesentium quas ut! +

+

+ Atque aut consectetur consequuntur debitis eius facere ipsa ipsam maiores minima minus mollitia qui quos + repudiandae sapiente, soluta? Ad, amet dolore doloribus ducimus eos exercitationem molestiae quisquam soluta + ullam voluptate. +

+
+
diff --git a/projects/demo/src/modules/components/scrollbar/examples/8/index.less b/projects/demo/src/modules/components/scrollbar/examples/8/index.less new file mode 100644 index 0000000000000..dcfb27db8ee52 --- /dev/null +++ b/projects/demo/src/modules/components/scrollbar/examples/8/index.less @@ -0,0 +1,13 @@ +.box { + inline-size: 16rem; + block-size: 16rem; + border: 1px solid; +} + +.content { + padding: 0 0.6875rem; +} + +p { + white-space: nowrap; +} diff --git a/projects/demo/src/modules/components/scrollbar/examples/8/index.ts b/projects/demo/src/modules/components/scrollbar/examples/8/index.ts new file mode 100644 index 0000000000000..bc99311979208 --- /dev/null +++ b/projects/demo/src/modules/components/scrollbar/examples/8/index.ts @@ -0,0 +1,19 @@ +import {Component} from '@angular/core'; +import {changeDetection} from '@demo/emulate/change-detection'; +import {encapsulation} from '@demo/emulate/encapsulation'; +import {TuiScrollbar, tuiScrollbarOptionsProvider} from '@taiga-ui/core'; + +@Component({ + standalone: true, + imports: [TuiScrollbar], + templateUrl: './index.html', + styleUrls: ['./index.less'], + encapsulation, + changeDetection, + providers: [ + tuiScrollbarOptionsProvider({ + mode: 'native', + }), + ], +}) +export default class Example {} diff --git a/projects/demo/src/modules/components/scrollbar/index.ts b/projects/demo/src/modules/components/scrollbar/index.ts index 3ba4e14b85a8d..ea62badc4b743 100644 --- a/projects/demo/src/modules/components/scrollbar/index.ts +++ b/projects/demo/src/modules/components/scrollbar/index.ts @@ -17,5 +17,6 @@ export default class Page { 'Light scrollbar', 'Virtual scroll', 'Show scroll bars on hover', + 'Native scrollbar', ]; }