项目初始化
This commit is contained in:
24
src/app/shared/components/scrollbar/index.en-US.md
Normal file
24
src/app/shared/components/scrollbar/index.en-US.md
Normal file
@ -0,0 +1,24 @@
|
||||
---
|
||||
order: 40
|
||||
title: scrollbar
|
||||
type: Component
|
||||
---
|
||||
|
||||
Based on [perfect-scrollbar](http://utatti.github.io/perfect-scrollbar/) perfect custom scrollbar plugin, [DEMO](https://preview.ng-alain.com/pro/#/other/chat).
|
||||
|
||||
## API
|
||||
|
||||
| Property | Description | Type | Default |
|
||||
| ----------------- | ------------------------ | ------------------- | ------- |
|
||||
| `[options]` | [Options](https://github.com/utatti/perfect-scrollbar#options) | `ScrollbarOptions` | - |
|
||||
| `[disabled]` | Whether to disable | `boolean` | `false` |
|
||||
| `[psScrollX]` | `ps-scroll-x` event | `EventEmitter<any>` | - |
|
||||
| `[psScrollY]` | `ps-scroll-y` event | `EventEmitter<any>` | - |
|
||||
| `[psScrollUp]` | `ps-scroll-up` event | `EventEmitter<any>` | - |
|
||||
| `[psScrollDown]` | `ps-scroll-down` event | `EventEmitter<any>` | - |
|
||||
| `[psScrollLeft]` | `ps-scroll-left` event | `EventEmitter<any>` | - |
|
||||
| `[psScrollRight]` | `ps-scroll-right` event | `EventEmitter<any>` | - |
|
||||
| `[psXReachStart]` | `ps-x-reach-start` event | `EventEmitter<any>` | - |
|
||||
| `[psXReachEnd]` | `ps-x-reach-end` event | `EventEmitter<any>` | - |
|
||||
| `[psYReachStart]` | `ps-y-reach-start` event | `EventEmitter<any>` | - |
|
||||
| `[psYReachEnd]` | `ps-y-reach-end` event | `EventEmitter<any>` | - |
|
||||
3
src/app/shared/components/scrollbar/index.ts
Normal file
3
src/app/shared/components/scrollbar/index.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export * from './scrollbar.directive';
|
||||
export * from './scrollbar.interface';
|
||||
export * from './scrollbar.module';
|
||||
24
src/app/shared/components/scrollbar/index.zh-CN.md
Normal file
24
src/app/shared/components/scrollbar/index.zh-CN.md
Normal file
@ -0,0 +1,24 @@
|
||||
---
|
||||
order: 40
|
||||
title: scrollbar
|
||||
type: Component
|
||||
---
|
||||
|
||||
基于 [perfect-scrollbar](http://utatti.github.io/perfect-scrollbar/) 自定义滚动条插件,参考[示例](https://preview.ng-alain.com/pro/#/other/chat)。
|
||||
|
||||
## API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| ----- | ------ | ----- | ------ |
|
||||
| `[options]` | [选项](https://github.com/utatti/perfect-scrollbar#options) | `ScrollbarOptions` | - |
|
||||
| `[disabled]` | 是否禁用 | `boolean` | `false` |
|
||||
| `[psScrollX]` | `ps-scroll-x` 事件 | `EventEmitter<any>` | - |
|
||||
| `[psScrollY]` | `ps-scroll-y` 事件 | `EventEmitter<any>` | - |
|
||||
| `[psScrollUp]` | `ps-scroll-up` 事件 | `EventEmitter<any>` | - |
|
||||
| `[psScrollDown]` | `ps-scroll-down` 事件 | `EventEmitter<any>` | - |
|
||||
| `[psScrollLeft]` | `ps-scroll-left` 事件 | `EventEmitter<any>` | - |
|
||||
| `[psScrollRight]` | `ps-scroll-right` 事件 | `EventEmitter<any>` | - |
|
||||
| `[psXReachStart]` | `ps-x-reach-start` 事件 | `EventEmitter<any>` | - |
|
||||
| `[psXReachEnd]` | `ps-x-reach-end` 事件 | `EventEmitter<any>` | - |
|
||||
| `[psYReachStart]` | `ps-y-reach-start` 事件 | `EventEmitter<any>` | - |
|
||||
| `[psYReachEnd]` | `ps-y-reach-end` 事件 | `EventEmitter<any>` | - |
|
||||
115
src/app/shared/components/scrollbar/scrollbar.directive.ts
Normal file
115
src/app/shared/components/scrollbar/scrollbar.directive.ts
Normal file
@ -0,0 +1,115 @@
|
||||
import { AfterViewInit, Directive, ElementRef, EventEmitter, Input, NgZone, OnDestroy, Output } from '@angular/core';
|
||||
import { toBoolean } from '@delon/util';
|
||||
import PerfectScrollbar from 'perfect-scrollbar';
|
||||
import { fromEvent, Subject } from 'rxjs';
|
||||
import { debounceTime, takeUntil } from 'rxjs/operators';
|
||||
|
||||
import { PerfectScrollbarEvent, PerfectScrollbarEvents, ScrollbarOptions } from './scrollbar.interface';
|
||||
|
||||
@Directive({
|
||||
selector: '[scrollbar]',
|
||||
exportAs: 'scrollbarComp'
|
||||
})
|
||||
export class ScrollbarDirective implements AfterViewInit, OnDestroy {
|
||||
static ngAcceptInputType_options: ScrollbarOptions | string | null | undefined;
|
||||
|
||||
private instance: PerfectScrollbar | null = null;
|
||||
private readonly ngDestroy: Subject<void> = new Subject();
|
||||
private _disabled = false;
|
||||
|
||||
// #region fields
|
||||
|
||||
@Input('scrollbar') options?: ScrollbarOptions;
|
||||
|
||||
@Input()
|
||||
set disabled(value: boolean) {
|
||||
this._disabled = toBoolean(value)!;
|
||||
if (this._disabled) {
|
||||
this.ngOnDestroy();
|
||||
} else {
|
||||
this.init();
|
||||
}
|
||||
}
|
||||
|
||||
@Output() readonly psScrollX: EventEmitter<any> = new EventEmitter<any>();
|
||||
@Output() readonly psScrollY: EventEmitter<any> = new EventEmitter<any>();
|
||||
|
||||
@Output() readonly psScrollUp: EventEmitter<any> = new EventEmitter<any>();
|
||||
@Output() readonly psScrollDown: EventEmitter<any> = new EventEmitter<any>();
|
||||
@Output() readonly psScrollLeft: EventEmitter<any> = new EventEmitter<any>();
|
||||
@Output() readonly psScrollRight: EventEmitter<any> = new EventEmitter<any>();
|
||||
|
||||
@Output() readonly psXReachStart: EventEmitter<any> = new EventEmitter<any>();
|
||||
@Output() readonly psXReachEnd: EventEmitter<any> = new EventEmitter<any>();
|
||||
@Output() readonly psYReachStart: EventEmitter<any> = new EventEmitter<any>();
|
||||
@Output() readonly psYReachEnd: EventEmitter<any> = new EventEmitter<any>();
|
||||
|
||||
// #endregion
|
||||
|
||||
scrollToBottom(): void {
|
||||
this.el.scrollTop = this.el.scrollHeight - this.el.clientHeight;
|
||||
}
|
||||
|
||||
scrollToTop(): void {
|
||||
this.el.scrollTop = 0;
|
||||
}
|
||||
|
||||
scrollToLeft(): void {
|
||||
this.el.scrollLeft = 0;
|
||||
}
|
||||
|
||||
scrollToRight(): void {
|
||||
this.el.scrollLeft = this.el.scrollWidth - this.el.clientWidth;
|
||||
}
|
||||
|
||||
constructor(private elRef: ElementRef, private zone: NgZone) {}
|
||||
|
||||
private get el(): HTMLElement {
|
||||
return this.elRef.nativeElement as HTMLElement;
|
||||
}
|
||||
|
||||
private init(): void {
|
||||
this.zone.runOutsideAngular(() => {
|
||||
const options = {
|
||||
wheelSpeed: 0.5,
|
||||
swipeEasing: true,
|
||||
wheelPropagation: false,
|
||||
minScrollbarLength: 40,
|
||||
maxScrollbarLength: 300,
|
||||
...this.options
|
||||
};
|
||||
setTimeout(() => {
|
||||
if (this._disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.instance = new PerfectScrollbar(this.el, options);
|
||||
|
||||
PerfectScrollbarEvents.forEach((eventName: PerfectScrollbarEvent) => {
|
||||
const eventType = eventName.replace(/([A-Z])/g, c => `-${c.toLowerCase()}`);
|
||||
|
||||
fromEvent<Event>(this.el, eventType)
|
||||
.pipe(debounceTime(20), takeUntil(this.ngDestroy))
|
||||
.subscribe((event: Event) => {
|
||||
this[eventName].emit(event);
|
||||
});
|
||||
});
|
||||
}, this.options?.delay || 0);
|
||||
});
|
||||
}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
this.init();
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.ngDestroy.next();
|
||||
this.ngDestroy.complete();
|
||||
this.zone.runOutsideAngular(() => {
|
||||
if (this.instance) {
|
||||
this.instance.destroy();
|
||||
}
|
||||
this.instance = null;
|
||||
});
|
||||
}
|
||||
}
|
||||
35
src/app/shared/components/scrollbar/scrollbar.interface.ts
Normal file
35
src/app/shared/components/scrollbar/scrollbar.interface.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import PerfectScrollbar from 'perfect-scrollbar';
|
||||
|
||||
export interface ScrollbarOptions extends PerfectScrollbar.Options {
|
||||
/**
|
||||
* 延迟初始化
|
||||
*/
|
||||
delay?: number;
|
||||
}
|
||||
|
||||
export type PerfectScrollbarEvent =
|
||||
| 'psScrollY'
|
||||
| 'psScrollX'
|
||||
| 'psScrollUp'
|
||||
| 'psScrollDown'
|
||||
| 'psScrollLeft'
|
||||
| 'psScrollRight'
|
||||
| 'psYReachEnd'
|
||||
| 'psYReachStart'
|
||||
| 'psXReachEnd'
|
||||
| 'psXReachStart';
|
||||
|
||||
export const PerfectScrollbarEvents: PerfectScrollbarEvent[] = [
|
||||
'psScrollY',
|
||||
'psScrollX',
|
||||
|
||||
'psScrollUp',
|
||||
'psScrollDown',
|
||||
'psScrollLeft',
|
||||
'psScrollRight',
|
||||
|
||||
'psYReachEnd',
|
||||
'psYReachStart',
|
||||
'psXReachEnd',
|
||||
'psXReachStart'
|
||||
];
|
||||
11
src/app/shared/components/scrollbar/scrollbar.module.ts
Normal file
11
src/app/shared/components/scrollbar/scrollbar.module.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
|
||||
import { ScrollbarDirective } from './scrollbar.directive';
|
||||
|
||||
const COMPONENTS = [ScrollbarDirective];
|
||||
|
||||
@NgModule({
|
||||
declarations: COMPONENTS,
|
||||
exports: COMPONENTS
|
||||
})
|
||||
export class ScrollbarModule {}
|
||||
Reference in New Issue
Block a user