diff --git a/package.json b/package.json index 65e0402..4bb3984 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "@angular/compiler": "^4.0.0", "@angular/compiler-cli": "^4.0.0", "@angular/core": "^4.0.0", + "@angular/forms": "^4.0.0", "@angular/platform-browser": "^4.0.0", "@angular/platform-browser-dynamic": "^4.0.0", "@compodoc/compodoc": "^1.0.0-beta.7", @@ -64,5 +65,9 @@ }, "engines": { "node": ">=6.0.0" + }, + "dependencies": { + "jquery": "^3.2.1", + "slick-carousel": "^1.6.0" } } diff --git a/src/index.ts b/src/index.ts index 1fc1e6a..3e7b920 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,35 +1,26 @@ -import { NgModule, ModuleWithProviders } from '@angular/core'; -import { CommonModule } from '@angular/common'; -import { SampleComponent } from './sample.component'; -import { SampleDirective } from './sample.directive'; -import { SamplePipe } from './sample.pipe'; -import { SampleService } from './sample.service'; +import {NgModule, ModuleWithProviders} from '@angular/core'; +import {CommonModule} from '@angular/common'; +import {SlickComponent, SlickItemDirective} from './slick.component'; -export * from './sample.component'; -export * from './sample.directive'; -export * from './sample.pipe'; -export * from './sample.service'; +export * from './slick.component'; @NgModule({ - imports: [ - CommonModule - ], - declarations: [ - SampleComponent, - SampleDirective, - SamplePipe - ], - exports: [ - SampleComponent, - SampleDirective, - SamplePipe - ] + imports: [ + CommonModule + ], + declarations: [ + SlickComponent, + SlickItemDirective, + ], + exports: [ + SlickComponent, + SlickItemDirective, + ] }) -export class SampleModule { - static forRoot(): ModuleWithProviders { - return { - ngModule: SampleModule, - providers: [SampleService] - }; - } +export class SlickModule { + static forRoot(): ModuleWithProviders { + return { + ngModule: SlickModule, + }; + } } diff --git a/src/package.json b/src/package.json index 089d01a..3e06f47 100644 --- a/src/package.json +++ b/src/package.json @@ -20,7 +20,12 @@ "typings": "ngx-slick.d.ts", "peerDependencies": { "@angular/core": "^4.0.0", + "@angular/forms": "^4.0.0", "rxjs": "^5.1.0", "zone.js": "^0.8.4" + }, + "dependencies": { + "jquery": "^3.2.1", + "slick-carousel": "^1.6.0" } } diff --git a/src/sample.component.ts b/src/sample.component.ts deleted file mode 100644 index 57938aa..0000000 --- a/src/sample.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component } from '@angular/core'; - -@Component({ - selector: 'sample-component', - template: `

Sample component

` -}) -export class SampleComponent { - - constructor() { - } - -} diff --git a/src/sample.directive.ts b/src/sample.directive.ts deleted file mode 100644 index dca99db..0000000 --- a/src/sample.directive.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { Directive, ElementRef } from '@angular/core'; - -@Directive({ - selector: '[sampleDirective]' -}) -export class SampleDirective { - - constructor(private el: ElementRef) { - } - -} diff --git a/src/sample.pipe.ts b/src/sample.pipe.ts deleted file mode 100644 index cd47113..0000000 --- a/src/sample.pipe.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Injectable, PipeTransform, Pipe } from '@angular/core'; - -/** - * Transforms any input value - */ -@Pipe({ - name: 'samplePipe' -}) -@Injectable() -export class SamplePipe implements PipeTransform { - transform(value: any, args: any[] = null): string { - return value; - } -} diff --git a/src/sample.service.ts b/src/sample.service.ts deleted file mode 100644 index 541343d..0000000 --- a/src/sample.service.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Injectable } from '@angular/core'; - -@Injectable() -export class SampleService { - - constructor() { - - } -} diff --git a/src/slick.component.ts b/src/slick.component.ts new file mode 100755 index 0000000..22c0748 --- /dev/null +++ b/src/slick.component.ts @@ -0,0 +1,167 @@ +import { + Component, Input, Output, EventEmitter, NgZone, forwardRef, AfterViewInit, + OnDestroy, Directive, ElementRef, Host +} from '@angular/core'; +import {NG_VALUE_ACCESSOR} from '@angular/forms'; + +import {JQuerySlickOptions} from 'slick'; +declare var $: any; + +/** + * Slick component + * Usage : + * + */ +@Component({ + selector: 'ngx-slick', + exportAs: 'slick-modal', + providers: [ + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => SlickComponent), + multi: true + } + ], + template: '', +}) +export class SlickComponent implements AfterViewInit, OnDestroy { + + @Input() config: JQuerySlickOptions; + @Output() afterChange: EventEmitter = new EventEmitter(); + @Output() beforeChange: EventEmitter = new EventEmitter(); + @Output() breakpoint: EventEmitter = new EventEmitter(); + @Output() destroy: EventEmitter = new EventEmitter(); + + public slides: any = []; + public $instance: any; + private initialized: Boolean = false; + + /** + * Constructor + */ + constructor(private el: ElementRef, private zone: NgZone) { + + } + + /** + * On component destroy + */ + ngOnDestroy() { + this.unslick(); + } + + /** + * On component view init + */ + ngAfterViewInit() { + } + + /** + * init slick + */ + initSlick() { + const self = this; + + this.zone.runOutsideAngular(() => { + this.$instance = $(this.el.nativeElement).slick(this.config); + this.initialized = true; + + this.$instance.on('afterChange', (event, slick, currentSlide) => { + self.zone.run(() => { + self.afterChange.emit({event, slick, currentSlide}); + }); + }); + + this.$instance.on('beforeChange', (event, slick, currentSlide, nextSlide) => { + self.zone.run(() => { + self.beforeChange.emit({event, slick, currentSlide, nextSlide}); + }); + }); + + this.$instance.on('breakpoint', (event, slick, breakpoint) => { + self.zone.run(() => { + self.breakpoint.emit({event, slick, breakpoint}); + }); + }); + + this.$instance.on('destroy', (event, slick) => { + self.zone.run(() => { + self.destroy.emit({event, slick}); + }); + }); + }); + } + + addSlide(slickItem: SlickItemDirective) { + if (!this.initialized) { + this.initSlick(); + } + + this.slides.push(slickItem); + this.$instance.slick('slickAdd', slickItem.el.nativeElement); + } + + removeSlide(slickItem: SlickItemDirective) { + console.log(`removeSlide`, slickItem); + const idx = this.slides.indexOf(slickItem); + this.$instance.slick('slickRemove', idx); + this.slides = this.slides.filter(s => s !== slickItem); + } + + /** + * Slick Method + */ + public slickGoTo(index: number) { + this.zone.run(() => { + this.$instance.slick('slickGoTo', index); + }); + } + + public slickNext() { + this.zone.run(() => { + this.$instance.slick('slickNext'); + }); + } + + + public slickPrev() { + this.zone.run(() => { + this.$instance.slick('slickPrev'); + }); + } + + public slickPause() { + this.zone.run(() => { + this.$instance.slick('slickPause'); + }); + } + + public slickPlay() { + this.zone.run(() => { + this.$instance.slick('slickPlay'); + }); + } + + public unslick() { + this.zone.run(() => { + this.$instance.slick('unslick'); + }); + } + +} + +@Directive({ + selector: '[ngxSlickItem]', +}) +export class SlickItemDirective implements AfterViewInit, OnDestroy { + constructor(public el: ElementRef, @Host() private carousel: SlickComponent) { + } + + ngAfterViewInit() { + this.carousel.addSlide(this); + } + + ngOnDestroy() { + this.carousel.removeSlide(this); + } +} diff --git a/tsconfig.json b/tsconfig.json index 5a61547..1df82d4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,6 +9,8 @@ "dom" ], "skipLibCheck": true, - "types": [] + "types": [ + "./src/slick.d.ts" + ] } }