项目初始化
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