Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(core): support using native scrollbar #9276

Merged
merged 2 commits into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 22 additions & 10 deletions projects/core/components/root/root.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -57,22 +60,31 @@ export class TuiRoot {
{initialValue: false},
);

protected readonly scrollbars = inject(TUI_IS_MOBILE)
? signal(false)
: toSignal(
inject<Observable<readonly unknown[]>>(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<Observable<readonly unknown[]>>(TUI_DIALOGS).pipe(
map(({length}) => !length),
debounceTime(0, tuiZonefreeScheduler()),
),
{initialValue: false},
);

constructor() {
inject(DOCUMENT).documentElement.setAttribute(
'data-tui-theme',
inject(TUI_THEME).toLowerCase(),
);

if (!this.nativeScrollbar) {
inject(DOCUMENT).defaultView?.document.documentElement.classList.add(
'tui-zero-scrollbar',
);
}

ngDevMode &&
console.assert(
!!inject<unknown[]>(EVENT_MANAGER_PLUGINS).find(
Expand Down
1 change: 0 additions & 1 deletion projects/core/components/root/root.style.less
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
}
}

html[data-tui-theme],
.tui-zero-scrollbar {
.scrollbar-hidden();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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),
Expand Down
51 changes: 27 additions & 24 deletions projects/core/components/scrollbar/scroll-controls.template.html
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
<ng-container *ngIf="refresh$ | async as bars">
<div
*ngIf="bars[0]"
class="t-bar t-bar_vertical"
[@tuiFadeIn]="options"
[class.t-bar_has-horizontal]="bars[1]"
(mousedown.capture.prevent)="(0)"
>
<ng-container *ngIf="nativeScrollbar; else custom" />
<ng-template #custom>
<ng-container *ngIf="refresh$ | async as bars">
<div
tuiScrollbar="vertical"
class="t-thumb"
></div>
</div>
<div
*ngIf="bars[1]"
class="t-bar t-bar_horizontal"
[@tuiFadeIn]="options"
[class.t-bar_has-vertical]="bars[0]"
(mousedown.capture.prevent)="(0)"
>
*ngIf="bars[0]"
class="t-bar t-bar_vertical"
[@tuiFadeIn]="options"
[class.t-bar_has-horizontal]="bars[1]"
(mousedown.capture.prevent)="(0)"
>
<div
tuiScrollbar="vertical"
class="t-thumb"
></div>
</div>
<div
tuiScrollbar="horizontal"
class="t-thumb"
></div>
</div>
</ng-container>
*ngIf="bars[1]"
class="t-bar t-bar_horizontal"
[@tuiFadeIn]="options"
[class.t-bar_has-vertical]="bars[0]"
(mousedown.capture.prevent)="(0)"
>
<div
tuiScrollbar="horizontal"
class="t-thumb"
></div>
</div>
</ng-container>
</ng-template>
9 changes: 6 additions & 3 deletions projects/core/components/scrollbar/scrollbar.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)',
},
Expand All @@ -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';
waterplea marked this conversation as resolved.
Show resolved Hide resolved

protected get delegated(): boolean {
return this.scrollRef !== this.el;
return this.scrollRef !== this.el || this.options.mode === 'native';
}

protected get scrollRef(): HTMLElement {
Expand Down
18 changes: 4 additions & 14 deletions projects/core/components/scrollbar/scrollbar.options.ts
Original file line number Diff line number Diff line change
@@ -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<TuiScrollbarOptions>,
): Provider {
return tuiProvideOptions(
TUI_SCROLLBAR_OPTIONS,
options,
TUI_DEFAULT_SCROLLBAR_OPTIONS,
);
}
export const [TUI_SCROLLBAR_OPTIONS, tuiScrollbarOptionsProvider] =
tuiCreateOptions<TuiScrollbarOptions>(TUI_DEFAULT_SCROLLBAR_OPTIONS);
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<tui-scroll-controls
*ngIf="!hidden && !isIOS"
*ngIf="!hidden && !isIOS && options.mode !== 'native'"
class="t-bars"
[class.t-hover-mode]="options.mode === 'hover'"
/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<tui-scrollbar class="box">
<div class="content">
<p>
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.
</p>
<p>
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?
</p>
<p>
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.
</p>
<p>
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!
</p>
<p>
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?
</p>
<p>
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!
</p>
<p>
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.
</p>
<p>
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!
</p>
<p>
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!
</p>
<p>
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.
</p>
</div>
</tui-scrollbar>
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.box {
inline-size: 16rem;
block-size: 16rem;
border: 1px solid;
}

.content {
padding: 0 0.6875rem;
}

p {
white-space: nowrap;
}
Original file line number Diff line number Diff line change
@@ -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 {}
1 change: 1 addition & 0 deletions projects/demo/src/modules/components/scrollbar/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ export default class Page {
'Light scrollbar',
'Virtual scroll',
'Show scroll bars on hover',
'Native scrollbar',
];
}
Loading