├── .gitignore
├── .npmignore
├── .travis.yml
├── .yo-rc.json
├── README.MD
├── bs-config.json
├── gulpfile.js
├── package.json
├── playground
├── index.html
├── index.ts
├── systemjs-angular-loader.js
├── systemjs.config.js
└── tsconfig.json
├── src
├── index.ts
├── package.json
├── slick.component.ts
├── tsconfig.es5.json
└── tsconfig.spec.json
├── tools
└── gulp
│ └── inline-resources.js
├── tsconfig.json
└── tslint.json
/.gitignore:
--------------------------------------------------------------------------------
1 | # Node
2 | node_modules/*
3 | npm-debug.log
4 |
5 | # TypeScript
6 | src/*.js
7 | src/*.map
8 | src/*.d.ts
9 |
10 | # JetBrains
11 | .idea
12 | .project
13 | .settings
14 | .idea/*
15 | *.iml
16 |
17 | # VS Code
18 | .vscode/*
19 |
20 | # Windows
21 | Thumbs.db
22 | Desktop.ini
23 |
24 | # Mac
25 | .DS_Store
26 | **/.DS_Store
27 |
28 | # Ngc generated files
29 | **/*.ngfactory.ts
30 |
31 | # Build files
32 | dist/*
33 |
34 | # Playground tmp files
35 | .playground
36 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | # Node
2 | node_modules/*
3 | npm-debug.log
4 | docs/*
5 | # DO NOT IGNORE TYPESCRIPT FILES FOR NPM
6 | # TypeScript
7 | # *.js
8 | # *.map
9 | # *.d.ts
10 |
11 | # JetBrains
12 | .idea
13 | .project
14 | .settings
15 | .idea/*
16 | *.iml
17 |
18 | # VS Code
19 | .vscode/*
20 |
21 | # Windows
22 | Thumbs.db
23 | Desktop.ini
24 |
25 | # Mac
26 | .DS_Store
27 | **/.DS_Store
28 |
29 | # Ngc generated files
30 | **/*.ngfactory.ts
31 |
32 | # Library files
33 | src/*
34 | build/*
35 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | sudo: false
3 | node_js:
4 | - '4.2.1'
5 |
--------------------------------------------------------------------------------
/.yo-rc.json:
--------------------------------------------------------------------------------
1 | {
2 | "generator-angular2-library": {
3 | "promptValues": {
4 | "gitRepositoryUrl": "https://github.com/devmark/ngx-slick"
5 | }
6 | }
7 | }
--------------------------------------------------------------------------------
/README.MD:
--------------------------------------------------------------------------------
1 | # ngx-slick
2 |
3 | Support angular 6+, Slick 1.8.1
4 |
5 | [Example](https://embed.plnkr.co/fblxzfPneL66950A4VDM/)
6 |
7 | ## Installation
8 |
9 | To install this library, run:
10 |
11 | ```bash
12 | $ npm install ngx-slick --save
13 | ```
14 |
15 | ## Consuming your library
16 |
17 | Once you have published your library to npm, you can import your library in any Angular application by running:
18 |
19 | ```bash
20 | $ npm install ngx-slick
21 | ```
22 |
23 | and then from your Angular `AppModule`:
24 |
25 | ```typescript
26 | import { BrowserModule } from '@angular/platform-browser';
27 | import { NgModule } from '@angular/core';
28 |
29 | import { AppComponent } from './app.component';
30 |
31 | // Import your library
32 | import { SlickModule } from 'ngx-slick';
33 |
34 | @NgModule({
35 | declarations: [
36 | AppComponent
37 | ],
38 | imports: [
39 | BrowserModule,
40 |
41 | // Specify your library as an import
42 | SlickModule.forRoot()
43 | ],
44 | providers: [],
45 | bootstrap: [AppComponent]
46 | })
47 | export class AppModule { }
48 | ```
49 |
50 | - Include jquery and slick css/js in your application :
51 | ```
52 |
53 |
54 |
55 |
56 |
57 | ```
58 |
59 | Once your library is imported, you can use its components, directives and pipes in your Angular application:
60 | ```html
61 |
62 |
63 |
64 |

65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 | ```
73 |
74 | ```javascript
75 | slides = [
76 | {img: "http://placehold.it/350x150/000000"},
77 | {img: "http://placehold.it/350x150/111111"},
78 | {img: "http://placehold.it/350x150/333333"},
79 | {img: "http://placehold.it/350x150/666666"}
80 | ];
81 | slideConfig = {"slidesToShow": 4, "slidesToScroll": 4};
82 |
83 | addSlide() {
84 | this.slides.push({img: "http://placehold.it/350x150/777777"})
85 | }
86 |
87 | removeSlide() {
88 | this.slides.length = this.slides.length - 1;
89 | }
90 |
91 | afterChange(e) {
92 | console.log('afterChange');
93 | }
94 | ```
95 |
96 |
97 | ## Development
98 |
99 | To generate all `*.js`, `*.d.ts` and `*.metadata.json` files:
100 |
101 | ```bash
102 | $ npm run build
103 | ```
104 |
105 | To lint all `*.ts` files:
106 |
107 | ```bash
108 | $ npm run lint
109 | ```
110 |
111 | ## License
112 |
113 | MIT © [Mark](mailto:hc.devmark@gmail.com)
--------------------------------------------------------------------------------
/bs-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "server": {
3 | "baseDir": "src",
4 | "routes": {
5 | "/": "playground",
6 | "/node_modules/": "node_modules",
7 | "/dist/": "dist",
8 | "/.playground": ".playground"
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | var gulp = require('gulp'),
3 | path = require('path'),
4 | ngc = require('@angular/compiler-cli/src/main').main,
5 | rollup = require('gulp-rollup'),
6 | rename = require('gulp-rename'),
7 | fs = require('fs-extra'),
8 | runSequence = require('run-sequence'),
9 | inlineResources = require('./tools/gulp/inline-resources');
10 |
11 | const rootFolder = path.join(__dirname);
12 | const srcFolder = path.join(rootFolder, 'src');
13 | const tmpFolder = path.join(rootFolder, '.tmp');
14 | const buildFolder = path.join(rootFolder, 'build');
15 | const distFolder = path.join(rootFolder, 'dist');
16 |
17 | /**
18 | * 1. Delete /dist folder
19 | */
20 | gulp.task('clean:dist', function () {
21 |
22 | // Delete contents but not dist folder to avoid broken npm links
23 | // when dist directory is removed while npm link references it.
24 | return fs.emptyDirSync(distFolder);
25 | });
26 |
27 | /**
28 | * 2. Clone the /src folder into /.tmp. If an npm link inside /src has been made,
29 | * then it's likely that a node_modules folder exists. Ignore this folder
30 | * when copying to /.tmp.
31 | */
32 | gulp.task('copy:source', function () {
33 | return gulp.src([`${srcFolder}/**/*`, `!${srcFolder}/node_modules`])
34 | .pipe(gulp.dest(tmpFolder));
35 | });
36 |
37 | /**
38 | * 3. Inline template (.html) and style (.css) files into the the component .ts files.
39 | * We do this on the /.tmp folder to avoid editing the original /src files
40 | */
41 | gulp.task('inline-resources', function () {
42 | return Promise.resolve()
43 | .then(() => inlineResources(tmpFolder));
44 | });
45 |
46 |
47 | /**
48 | * 4. Run the Angular compiler, ngc, on the /.tmp folder. This will output all
49 | * compiled modules to the /build folder.
50 | *
51 | * As of Angular 5, ngc accepts an array and no longer returns a promise.
52 | */
53 | gulp.task('ngc', function () {
54 | ngc(['--project', `${tmpFolder}/tsconfig.es5.json`]);
55 | return Promise.resolve()
56 | });
57 |
58 | /**
59 | * 5. Run rollup inside the /build folder to generate our Flat ES module and place the
60 | * generated file into the /dist folder
61 | */
62 | gulp.task('rollup:fesm', function () {
63 | return gulp.src(`${buildFolder}/**/*.js`)
64 | // transform the files here.
65 | .pipe(rollup({
66 |
67 | // Bundle's entry point
68 | // See "input" in https://rollupjs.org/#core-functionality
69 | input: `${buildFolder}/index.js`,
70 |
71 | // Allow mixing of hypothetical and actual files. "Actual" files can be files
72 | // accessed by Rollup or produced by plugins further down the chain.
73 | // This prevents errors like: 'path/file' does not exist in the hypothetical file system
74 | // when subdirectories are used in the `src` directory.
75 | allowRealFiles: true,
76 |
77 | // A list of IDs of modules that should remain external to the bundle
78 | // See "external" in https://rollupjs.org/#core-functionality
79 | external: [
80 | '@angular/core',
81 | '@angular/common'
82 | ],
83 |
84 | output: {
85 | // Format of generated bundle
86 | // See "format" in https://rollupjs.org/#core-functionality
87 | format: 'es'
88 | }
89 | }))
90 | .pipe(gulp.dest(distFolder));
91 | });
92 |
93 | /**
94 | * 6. Run rollup inside the /build folder to generate our UMD module and place the
95 | * generated file into the /dist folder
96 | */
97 | gulp.task('rollup:umd', function () {
98 | return gulp.src(`${buildFolder}/**/*.js`)
99 | // transform the files here.
100 | .pipe(rollup({
101 |
102 | // Bundle's entry point
103 | // See "input" in https://rollupjs.org/#core-functionality
104 | input: `${buildFolder}/index.js`,
105 |
106 | // Allow mixing of hypothetical and actual files. "Actual" files can be files
107 | // accessed by Rollup or produced by plugins further down the chain.
108 | // This prevents errors like: 'path/file' does not exist in the hypothetical file system
109 | // when subdirectories are used in the `src` directory.
110 | allowRealFiles: true,
111 |
112 | // A list of IDs of modules that should remain external to the bundle
113 | // See "external" in https://rollupjs.org/#core-functionality
114 | external: [
115 | '@angular/core',
116 | '@angular/common'
117 | ],
118 |
119 | output: {
120 | // The name to use for the module for UMD/IIFE bundles
121 | // (required for bundles with exports)
122 | // See "name" in https://rollupjs.org/#core-functionality
123 | name: 'ngx-slick',
124 |
125 | // See "globals" in https://rollupjs.org/#core-functionality
126 | globals: {
127 | typescript: 'ts'
128 | },
129 |
130 | // Format of generated bundle
131 | // See "format" in https://rollupjs.org/#core-functionality
132 | format: 'umd',
133 |
134 | // Export mode to use
135 | // See "exports" in https://rollupjs.org/#danger-zone
136 | exports: 'named'
137 | }
138 |
139 | }))
140 | .pipe(rename('ngx-slick.umd.js'))
141 | .pipe(gulp.dest(distFolder));
142 | });
143 |
144 | /**
145 | * 7. Copy all the files from /build to /dist, except .js files. We ignore all .js from /build
146 | * because with don't need individual modules anymore, just the Flat ES module generated
147 | * on step 5.
148 | */
149 | gulp.task('copy:build', function () {
150 | return gulp.src([`${buildFolder}/**/*`, `!${buildFolder}/**/*.js`])
151 | .pipe(gulp.dest(distFolder));
152 | });
153 |
154 | /**
155 | * 8. Copy package.json from /src to /dist
156 | */
157 | gulp.task('copy:manifest', function () {
158 | return gulp.src([`${srcFolder}/package.json`])
159 | .pipe(gulp.dest(distFolder));
160 | });
161 |
162 | /**
163 | * 9. Copy README.md from / to /dist
164 | */
165 | gulp.task('copy:readme', function () {
166 | return gulp.src([path.join(rootFolder, 'README.MD')])
167 | .pipe(gulp.dest(distFolder));
168 | });
169 |
170 | /**
171 | * 10. Delete /.tmp folder
172 | */
173 | gulp.task('clean:tmp', function () {
174 | return deleteFolder(tmpFolder);
175 | });
176 |
177 | /**
178 | * 11. Delete /build folder
179 | */
180 | gulp.task('clean:build', function () {
181 | return deleteFolder(buildFolder);
182 | });
183 |
184 | gulp.task('compile', function () {
185 | runSequence(
186 | 'clean:dist',
187 | 'copy:source',
188 | 'inline-resources',
189 | 'ngc',
190 | 'rollup:fesm',
191 | 'rollup:umd',
192 | 'copy:build',
193 | 'copy:manifest',
194 | 'copy:readme',
195 | 'clean:build',
196 | 'clean:tmp',
197 | function (err) {
198 | if (err) {
199 | console.log('ERROR:', err.message);
200 | deleteFolder(distFolder);
201 | deleteFolder(tmpFolder);
202 | deleteFolder(buildFolder);
203 | } else {
204 | console.log('Compilation finished succesfully');
205 | }
206 | });
207 | });
208 |
209 | /**
210 | * Watch for any change in the /src folder and compile files
211 | */
212 | gulp.task('watch', function () {
213 | gulp.watch(`${srcFolder}/**/*`, ['compile']);
214 | });
215 |
216 | gulp.task('clean', function (callback) {
217 | runSequence('clean:dist', 'clean:tmp', 'clean:build', callback);
218 | });
219 |
220 | gulp.task('build', function (callback) {
221 | runSequence('clean', 'compile', callback);
222 | });
223 |
224 | gulp.task('build:watch', function (callback) {
225 | runSequence('build', 'watch', callback);
226 | });
227 |
228 | gulp.task('default', ['build:watch']);
229 |
230 | /**
231 | * Deletes the specified folder
232 | */
233 | function deleteFolder(folder) {
234 | return fs.removeSync(folder);
235 | }
236 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ngx-slick",
3 | "version": "0.2.1",
4 | "scripts": {
5 | "build": "gulp build",
6 | "build:watch": "gulp",
7 | "docs": "npm run docs:build",
8 | "docs:build": "compodoc -p tsconfig.json -n ngx-slick -d docs --hideGenerator",
9 | "docs:serve": "npm run docs:build -- -s",
10 | "docs:watch": "npm run docs:build -- -s -w",
11 | "lint": "tslint --type-check --project tsconfig.json src/**/*.ts",
12 | "lite": "lite-server",
13 | "playground:build": "tsc -p playground -w",
14 | "playground": "concurrently \"npm run build:watch\" \"npm run playground:build\" \"npm run lite\"",
15 | "test": "tsc && karma start"
16 | },
17 | "repository": {
18 | "type": "git",
19 | "url": "https://github.com/devmark/ngx-slick"
20 | },
21 | "author": {
22 | "name": "Mark",
23 | "email": "hc.devmark@gmail.com"
24 | },
25 | "keywords": [
26 | "angular"
27 | ],
28 | "license": "MIT",
29 | "bugs": {
30 | "url": "https://github.com/devmark/ngx-slick/issues"
31 | },
32 | "devDependencies": {
33 | "@angular/common": "^6.0.7",
34 | "@angular/compiler": "^6.0.7",
35 | "@angular/compiler-cli": "^6.0.7",
36 | "@angular/core": "^6.0.7",
37 | "@angular/forms": "^6.0.7",
38 | "@angular/platform-browser": "^6.0.7",
39 | "@angular/platform-browser-dynamic": "^6.0.7",
40 | "@compodoc/compodoc": "^1.0.0-beta.10",
41 | "@types/jasmine": "2.5.53",
42 | "@types/node": "~6.0.60",
43 | "angular-in-memory-web-api": "^0.3.2",
44 | "codelyzer": "~3.2.0",
45 | "concurrently": "^3.4.0",
46 | "core-js": "^2.4.1",
47 | "fs-extra": "^5.0.0",
48 | "gulp": "^3.9.1",
49 | "gulp-rename": "^1.2.2",
50 | "gulp-rollup": "^2.16.2",
51 | "jasmine-core": "~2.6.2",
52 | "jasmine-spec-reporter": "~4.1.0",
53 | "karma": "~1.7.0",
54 | "karma-chrome-launcher": "~2.1.1",
55 | "karma-cli": "~1.0.1",
56 | "karma-coverage-istanbul-reporter": "^1.2.1",
57 | "karma-jasmine": "~1.1.0",
58 | "karma-jasmine-html-reporter": "^0.2.2",
59 | "lite-server": "^2.3.0",
60 | "node-sass": "^4.5.2",
61 | "node-sass-tilde-importer": "^1.0.0",
62 | "node-watch": "^0.5.2",
63 | "protractor": "~5.1.2",
64 | "rollup": "^0.62.0",
65 | "run-sequence": "^1.2.2",
66 | "rxjs": "~6.2.1",
67 | "systemjs": "^0.20.12",
68 | "ts-node": "~3.2.0",
69 | "tslint": "~5.7.0",
70 | "typescript": "~2.7.2",
71 | "zone.js": "^0.8.26"
72 | },
73 | "engines": {
74 | "node": ">=6.0.0"
75 | },
76 | "dependencies": {
77 | "@types/slick-carousel": "^1.6.32",
78 | "slick-carousel": "^1.8.1"
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/playground/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ngx-slick Playground
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | Loading AppComponent content here ...
29 |
30 |
31 |
--------------------------------------------------------------------------------
/playground/index.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This is only for local test
3 | */
4 | import {BrowserModule} from '@angular/platform-browser';
5 | import {NgModule} from '@angular/core';
6 | import {Component} from '@angular/core';
7 | import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
8 |
9 | import {SlickModule} from 'ngx-slick';
10 |
11 | @Component({
12 | selector: 'app',
13 | template: `
14 |
15 |
16 |

17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | `
25 | })
26 | class AppComponent {
27 | slides = [
28 | {img: 'http://placehold.it/350x150/000000'},
29 | {img: 'http://placehold.it/350x150/111111'},
30 | {img: 'http://placehold.it/350x150/333333'},
31 | {img: 'http://placehold.it/350x150/666666'}
32 | ];
33 | slideConfig = {
34 | dots: true,
35 | speed: 300,
36 | slidesToShow: 2,
37 | slidesToScroll: 2
38 | };
39 |
40 | addSlide() {
41 | this.slides.push({img: 'http://placehold.it/350x150/777777'});
42 | }
43 |
44 | removeSlide() {
45 | this.slides.length = this.slides.length - 1;
46 | }
47 |
48 | slickInit(e) {
49 | console.log('slick initialized');
50 | }
51 | afterChange(e) {
52 | console.log('afterChange');
53 | }
54 | }
55 |
56 | @NgModule({
57 | bootstrap: [AppComponent],
58 | declarations: [AppComponent],
59 | imports: [BrowserModule, SlickModule]
60 | })
61 | class AppModule {
62 | }
63 |
64 | platformBrowserDynamic().bootstrapModule(AppModule);
65 |
--------------------------------------------------------------------------------
/playground/systemjs-angular-loader.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var templateUrlRegex = /templateUrl\s*:(\s*['"`](.*?)['"`]\s*)/gm;
4 | var stylesRegex = /styleUrls *:(\s*\[[^\]]*?\])/g;
5 | var stringRegex = /(['`"])((?:[^\\]\\\1|.)*?)\1/g;
6 |
7 | module.exports.translate = function (load){
8 | if (load.source.indexOf('moduleId') !== -1) {
9 | return load;
10 | }
11 |
12 | // eslint-disable-next-line
13 | var url = document.createElement('a');
14 | url.href = load.address;
15 |
16 | var basePathParts = url.pathname.split('/');
17 |
18 | basePathParts.pop();
19 | var basePath = basePathParts.join('/');
20 |
21 | // eslint-disable-next-line
22 | var baseHref = document.createElement('a');
23 | baseHref.href = this.baseURL;
24 | baseHref = baseHref.pathname;
25 |
26 | if (!baseHref.startsWith('/base/')) { // it is not karma
27 | basePath = basePath.replace(baseHref, '');
28 | }
29 |
30 | load.source = load.source
31 | .replace(templateUrlRegex, function (match, quote, sourceUrl){
32 | var resolvedUrl = sourceUrl;
33 |
34 | if (sourceUrl.startsWith('.')) {
35 | resolvedUrl = basePath + sourceUrl.substr(1);
36 | }
37 |
38 | return 'templateUrl: "' + resolvedUrl + '"';
39 | })
40 | .replace(stylesRegex, function (match, relativeUrls) {
41 | var urls = [];
42 |
43 | while ((match = stringRegex.exec(relativeUrls)) !== null) {
44 | if (match[2].startsWith('.')) {
45 | urls.push('"' + basePath + match[2].substr(1) + '"');
46 | } else {
47 | urls.push('"' + match[2] + '"');
48 | }
49 | }
50 |
51 | return 'styleUrls: [' + urls.join(', ') + ']';
52 | });
53 |
54 | return load;
55 | };
56 |
--------------------------------------------------------------------------------
/playground/systemjs.config.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | /**
3 | * System configuration for Angular samples
4 | * Adjust as necessary for your application needs.
5 | */
6 | (function () {
7 | System.config({
8 | paths: {
9 | // paths serve as alias
10 | 'npm:': '../node_modules/'
11 | },
12 | // map tells the System loader where to look for things
13 | map: {
14 | // our app is within the app folder
15 | app: 'app',
16 |
17 | // angular bundles
18 | '@angular/core': 'npm:@angular/core/bundles/core.umd.js',
19 | '@angular/common': 'npm:@angular/common/bundles/common.umd.js',
20 | '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js',
21 | '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js',
22 | '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js',
23 | '@angular/http': 'npm:@angular/http/bundles/http.umd.js',
24 | '@angular/router': 'npm:@angular/router/bundles/router.umd.js',
25 | '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js',
26 |
27 | // other libraries
28 | rxjs: 'npm:rxjs',
29 | 'angular-in-memory-web-api': 'npm:angular-in-memory-web-api/bundles/in-memory-web-api.umd.js',
30 | 'ngx-slick': '../dist'
31 | },
32 | // packages tells the System loader how to load when no filename and/or no extension
33 | packages: {
34 | '.': {
35 | defaultExtension: 'js'
36 | },
37 | app: {
38 | defaultExtension: 'js',
39 | meta: {
40 | './*.js': {
41 | loader: 'systemjs-angular-loader.js'
42 | }
43 | }
44 | },
45 | rxjs: { defaultExtension: 'js', main: "index.js" },
46 | "rxjs-compat": {defaultExtension: 'js', main: "index.js"},
47 | "rxjs/operators": {"main": "index.js", "defaultExtension": "js"},
48 | "rxjs/internal-compatibility": {"main": "index.js", "defaultExtension": "js"},
49 | "rxjs/testing": {"main": "index.js", "defaultExtension": "js"},
50 | 'rxjs/ajax': {main: 'index.js', defaultExtension: 'js'},
51 | 'rxjs/webSocket': {main: 'index.js', defaultExtension: 'js'},
52 | 'ngx-slick': {
53 | main: 'ngx-slick.umd.js',
54 | defaultExtension: 'js'
55 | }
56 | }
57 | });
58 | })(this);
59 |
--------------------------------------------------------------------------------
/playground/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "../.playground",
4 | "target": "es5",
5 | "module": "commonjs",
6 | "moduleResolution": "node",
7 | "sourceMap": true,
8 | "emitDecoratorMetadata": true,
9 | "experimentalDecorators": true,
10 | "lib": [ "es2015", "dom" ],
11 | "noImplicitAny": true,
12 | "suppressImplicitAnyIndexErrors": true
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | import {NgModule, ModuleWithProviders} from '@angular/core';
2 | import {CommonModule} from '@angular/common';
3 | import {SlickComponent, SlickItemDirective} from './slick.component';
4 |
5 | export * from './slick.component';
6 |
7 | @NgModule({
8 | imports: [
9 | CommonModule
10 | ],
11 | declarations: [
12 | SlickComponent,
13 | SlickItemDirective,
14 | ],
15 | exports: [
16 | SlickComponent,
17 | SlickItemDirective,
18 | ]
19 | })
20 | export class SlickModule {
21 | static forRoot(): ModuleWithProviders {
22 | return {
23 | ngModule: SlickModule,
24 | };
25 | }
26 | }
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/src/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "ngx-slick",
3 | "version": "0.2.1",
4 | "repository": {
5 | "type": "git",
6 | "url": "https://github.com/devmark/ngx-slick"
7 | },
8 | "author": {
9 | "name": "Mark",
10 | "email": "hc.devmark@gmail.com"
11 | },
12 | "keywords": [
13 | "angular"
14 | ],
15 | "license": "MIT",
16 | "bugs": {
17 | "url": "https://github.com/devmark/ngx-slick/issues"
18 | },
19 | "main": "ngx-slick.umd.js",
20 | "module": "ngx-slick.js",
21 | "jsnext:main": "ngx-slick.js",
22 | "typings": "ngx-slick.d.ts",
23 | "peerDependencies": {
24 | "@angular/core": "^6.0.0",
25 | "@angular/common": "^6.0.0",
26 | "@angular/forms": "^6.0.0",
27 | "rxjs": "^6.0.0",
28 | "zone.js": "^0.8.4"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/slick.component.ts:
--------------------------------------------------------------------------------
1 | import {
2 | Component, Input, Output, EventEmitter, NgZone, forwardRef, AfterViewInit,
3 | OnDestroy, Directive, ElementRef, Host
4 | } from '@angular/core';
5 | import {NG_VALUE_ACCESSOR} from '@angular/forms';
6 |
7 | declare const jQuery: any;
8 |
9 | /**
10 | * Slick component
11 | */
12 | @Component({
13 | selector: 'ngx-slick',
14 | exportAs: 'slick-modal',
15 | providers: [
16 | {
17 | provide: NG_VALUE_ACCESSOR,
18 | useExisting: forwardRef(() => SlickComponent),
19 | multi: true
20 | }
21 | ],
22 | template: '',
23 | })
24 | export class SlickComponent implements AfterViewInit, OnDestroy {
25 |
26 | @Input() config: any;
27 | @Output() afterChange: EventEmitter = new EventEmitter();
28 | @Output() beforeChange: EventEmitter = new EventEmitter();
29 | @Output() breakpoint: EventEmitter = new EventEmitter();
30 | @Output() destroy: EventEmitter = new EventEmitter();
31 | @Output() init: EventEmitter = new EventEmitter();
32 | public slides: any = [];
33 | public $instance: any;
34 | private initialized: Boolean = false;
35 |
36 | /**
37 | * Constructor
38 | */
39 | constructor(private el: ElementRef, private zone: NgZone) {
40 |
41 | }
42 |
43 | /**
44 | * On component destroy
45 | */
46 | ngOnDestroy() {
47 | this.unslick();
48 | }
49 |
50 | /**
51 | * On component view init
52 | */
53 | ngAfterViewInit() {
54 | }
55 |
56 | /**
57 | * init slick
58 | */
59 | initSlick() {
60 | const self = this;
61 |
62 | this.zone.runOutsideAngular(() => {
63 | jQuery(this.el.nativeElement)[0].innerHTML = '';
64 | this.$instance = jQuery(this.el.nativeElement);
65 | this.$instance.on('init', (event, slick) => {
66 | this.zone.run(() => {
67 | this.init.emit({event, slick});
68 | });
69 | });
70 |
71 | this.$instance.slick(this.config);
72 | this.initialized = true;
73 |
74 | this.$instance.on('afterChange', (event, slick, currentSlide) => {
75 | self.zone.run(() => {
76 | self.afterChange.emit({event, slick, currentSlide});
77 | });
78 | });
79 |
80 | this.$instance.on('beforeChange', (event, slick, currentSlide, nextSlide) => {
81 | self.zone.run(() => {
82 | self.beforeChange.emit({event, slick, currentSlide, nextSlide});
83 | });
84 | });
85 |
86 | this.$instance.on('breakpoint', (event, slick, breakpoint) => {
87 | self.zone.run(() => {
88 | self.breakpoint.emit({event, slick, breakpoint});
89 | });
90 | });
91 |
92 | this.$instance.on('destroy', (event, slick) => {
93 | self.zone.run(() => {
94 | self.destroy.emit({event, slick});
95 | });
96 | });
97 | });
98 | }
99 |
100 | addSlide(slickItem: SlickItemDirective) {
101 | if (!this.initialized) {
102 | this.initSlick();
103 | }
104 | this.slides.push(slickItem);
105 |
106 | this.zone.run(() => {
107 | this.$instance.slick('slickAdd', slickItem.el.nativeElement);
108 | });
109 | }
110 |
111 | removeSlide(slickItem: SlickItemDirective) {
112 | const idx = this.slides.indexOf(slickItem);
113 |
114 | this.zone.run(() => {
115 | this.$instance.slick('slickRemove', idx);
116 | });
117 |
118 | this.slides = this.slides.filter(s => s !== slickItem);
119 | }
120 |
121 | /**
122 | * Slick Method
123 | */
124 | public slickGoTo(index: number) {
125 | this.zone.run(() => {
126 | this.$instance.slick('slickGoTo', index);
127 | });
128 | }
129 |
130 | public slickNext() {
131 | this.zone.run(() => {
132 | this.$instance.slick('slickNext');
133 | });
134 | }
135 |
136 |
137 | public slickPrev() {
138 | this.zone.run(() => {
139 | this.$instance.slick('slickPrev');
140 | });
141 | }
142 |
143 | public slickPause() {
144 | this.zone.run(() => {
145 | this.$instance.slick('slickPause');
146 | });
147 | }
148 |
149 | public slickPlay() {
150 | this.zone.run(() => {
151 | this.$instance.slick('slickPlay');
152 | });
153 | }
154 |
155 | public unslick() {
156 | if (this.$instance) {
157 | this.zone.run(() => {
158 | this.$instance.slick('unslick');
159 | });
160 | }
161 | this.initialized = false;
162 | }
163 |
164 | }
165 |
166 | @Directive({
167 | selector: '[ngxSlickItem]',
168 | })
169 | export class SlickItemDirective implements AfterViewInit, OnDestroy {
170 | constructor(public el: ElementRef, @Host() private carousel: SlickComponent) {
171 | }
172 |
173 | ngAfterViewInit() {
174 | this.carousel.addSlide(this);
175 | }
176 |
177 | ngOnDestroy() {
178 | this.carousel.removeSlide(this);
179 | }
180 | }
181 |
--------------------------------------------------------------------------------
/src/tsconfig.es5.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "declaration": true,
4 | "module": "es2015",
5 | "target": "es5",
6 | "baseUrl": ".",
7 | "stripInternal": true,
8 | "emitDecoratorMetadata": true,
9 | "experimentalDecorators": true,
10 | "moduleResolution": "node",
11 | "outDir": "../build",
12 | "rootDir": ".",
13 | "lib": [
14 | "es2015",
15 | "dom"
16 | ],
17 | "skipLibCheck": true,
18 | "types": []
19 | },
20 | "angularCompilerOptions": {
21 | "annotateForClosureCompiler": true,
22 | "strictMetadataEmit": true,
23 | "skipTemplateCodegen": true,
24 | "flatModuleOutFile": "ngx-slick.js",
25 | "flatModuleId": "ngx-slick"
26 | },
27 | "files": [
28 | "./index.ts"
29 | ]
30 | }
31 |
--------------------------------------------------------------------------------
/src/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./tsconfig.es5.json",
3 | "compilerOptions": {
4 | "emitDecoratorMetadata": true,
5 | "experimentalDecorators": true,
6 | "outDir": "../out-tsc/spec",
7 | "module": "commonjs",
8 | "target": "es6",
9 | "baseUrl": "",
10 | "types": [
11 | "jest",
12 | "node"
13 | ]
14 | },
15 | "files": [
16 | "**/*.spec.ts"
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/tools/gulp/inline-resources.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | // https://github.com/filipesilva/angular-quickstart-lib/blob/master/inline-resources.js
3 | 'use strict';
4 |
5 | const fs = require('fs');
6 | const path = require('path');
7 | const glob = require('glob');
8 | const sass = require('node-sass');
9 | const tildeImporter = require('node-sass-tilde-importer');
10 |
11 | /**
12 | * Simple Promiseify function that takes a Node API and return a version that supports promises.
13 | * We use promises instead of synchronized functions to make the process less I/O bound and
14 | * faster. It also simplifies the code.
15 | */
16 | function promiseify(fn) {
17 | return function () {
18 | const args = [].slice.call(arguments, 0);
19 | return new Promise((resolve, reject) => {
20 | fn.apply(this, args.concat([function (err, value) {
21 | if (err) {
22 | reject(err);
23 | } else {
24 | resolve(value);
25 | }
26 | }]));
27 | });
28 | };
29 | }
30 |
31 | const readFile = promiseify(fs.readFile);
32 | const writeFile = promiseify(fs.writeFile);
33 |
34 | /**
35 | * Inline resources in a tsc/ngc compilation.
36 | * @param projectPath {string} Path to the project.
37 | */
38 | function inlineResources(projectPath) {
39 |
40 | // Match only TypeScript files in projectPath.
41 | const files = glob.sync('**/*.ts', {cwd: projectPath});
42 |
43 | // For each file, inline the templates and styles under it and write the new file.
44 | return Promise.all(files.map(filePath => {
45 | const fullFilePath = path.join(projectPath, filePath);
46 | return readFile(fullFilePath, 'utf-8')
47 | .then(content => inlineResourcesFromString(content, url => {
48 | // Resolve the template url.
49 | return path.join(path.dirname(fullFilePath), url);
50 | }))
51 | .then(content => writeFile(fullFilePath, content))
52 | .catch(err => {
53 | console.error('An error occured: ', err);
54 | });
55 | }));
56 | }
57 |
58 | /**
59 | * Inline resources from a string content.
60 | * @param content {string} The source file's content.
61 | * @param urlResolver {Function} A resolver that takes a URL and return a path.
62 | * @returns {string} The content with resources inlined.
63 | */
64 | function inlineResourcesFromString(content, urlResolver) {
65 | // Curry through the inlining functions.
66 | return [
67 | inlineTemplate,
68 | inlineStyle,
69 | removeModuleId
70 | ].reduce((content, fn) => fn(content, urlResolver), content);
71 | }
72 |
73 | /**
74 | * Inline the templates for a source file. Simply search for instances of `templateUrl: ...` and
75 | * replace with `template: ...` (with the content of the file included).
76 | * @param content {string} The source file's content.
77 | * @param urlResolver {Function} A resolver that takes a URL and return a path.
78 | * @return {string} The content with all templates inlined.
79 | */
80 | function inlineTemplate(content, urlResolver) {
81 | return content.replace(/templateUrl:\s*(['"])([^\1]+?\.html)\1/g, function (fullMatch, quote, templateUrl) {
82 | const templateFile = urlResolver(templateUrl);
83 | const templateContent = fs.readFileSync(templateFile, 'utf-8');
84 | const shortenedTemplate = templateContent
85 | .replace(/([\n\r]\s*)+/gm, ' ')
86 | .replace(/"/g, '\\"');
87 | return `template: "${shortenedTemplate}"`;
88 | });
89 | }
90 |
91 |
92 | /**
93 | * Inline the styles for a source file. Simply search for instances of `styleUrls: [...]` and
94 | * replace with `styles: [...]` (with the content of the file included).
95 | * @param urlResolver {Function} A resolver that takes a URL and return a path.
96 | * @param content {string} The source file's content.
97 | * @return {string} The content with all styles inlined.
98 | */
99 | function inlineStyle(content, urlResolver) {
100 | return content.replace(/styleUrls\s*:\s*(\[[\s\S]*?\])/gm, function (m, styleUrls) {
101 | const urls = eval(styleUrls);
102 | return 'styles: ['
103 | + urls.map(styleUrl => {
104 | const styleFile = urlResolver(styleUrl);
105 | const originContent = fs.readFileSync(styleFile, 'utf-8');
106 | const styleContent = styleFile.endsWith('.scss') ? buildSass(originContent, styleFile) : originContent;
107 | const shortenedStyle = styleContent
108 | .replace(/([\n\r]\s*)+/gm, ' ')
109 | .replace(/"/g, '\\"');
110 | return `"${shortenedStyle}"`;
111 | })
112 | .join(',\n')
113 | + ']';
114 | });
115 | }
116 |
117 | /**
118 | * build sass content to css
119 | * @param content {string} the css content
120 | * @param sourceFile {string} the scss file sourceFile
121 | * @return {string} the generated css, empty string if error occured
122 | */
123 | function buildSass(content, sourceFile) {
124 | try {
125 | const result = sass.renderSync({
126 | data: content,
127 | file: sourceFile,
128 | importer: tildeImporter
129 | });
130 | return result.css.toString()
131 | } catch (e) {
132 | console.error('\x1b[41m');
133 | console.error('at ' + sourceFile + ':' + e.line + ":" + e.column);
134 | console.error(e.formatted);
135 | console.error('\x1b[0m');
136 | return "";
137 | }
138 | }
139 |
140 | /**
141 | * Remove every mention of `moduleId: module.id`.
142 | * @param content {string} The source file's content.
143 | * @returns {string} The content with all moduleId: mentions removed.
144 | */
145 | function removeModuleId(content) {
146 | return content.replace(/\s*moduleId:\s*module\.id\s*,?\s*/gm, '');
147 | }
148 |
149 | module.exports = inlineResources;
150 | module.exports.inlineResourcesFromString = inlineResourcesFromString;
151 |
152 | // Run inlineResources if module is being called directly from the CLI with arguments.
153 | if (require.main === module && process.argv.length > 2) {
154 | console.log('Inlining resources from project:', process.argv[2]);
155 | return inlineResources(process.argv[2]);
156 | }
157 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": "./src",
4 | "experimentalDecorators": true,
5 | "moduleResolution": "node",
6 | "rootDir": "./src",
7 | "lib": [
8 | "es2015",
9 | "dom"
10 | ],
11 | "skipLibCheck": true,
12 | "types": []
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rulesDirectory": [
3 | "node_modules/codelyzer"
4 | ],
5 | "rules": {
6 | "class-name": true,
7 | "comment-format": [
8 | true,
9 | "check-space"
10 | ],
11 | "curly": true,
12 | "eofline": true,
13 | "forin": true,
14 | "indent": [
15 | true,
16 | "spaces"
17 | ],
18 | "label-position": true,
19 | "max-line-length": [
20 | true,
21 | 140
22 | ],
23 | "member-access": false,
24 | "member-ordering": [
25 | true,
26 | "static-before-instance",
27 | "variables-before-functions"
28 | ],
29 | "no-arg": true,
30 | "no-bitwise": true,
31 | "no-console": [
32 | true,
33 | "debug",
34 | "info",
35 | "time",
36 | "timeEnd",
37 | "trace"
38 | ],
39 | "no-construct": true,
40 | "no-debugger": true,
41 | "no-duplicate-variable": true,
42 | "no-empty": false,
43 | "no-eval": true,
44 | "no-inferrable-types": true,
45 | "no-shadowed-variable": true,
46 | "no-string-literal": false,
47 | "no-switch-case-fall-through": true,
48 | "no-trailing-whitespace": true,
49 | "no-unused-expression": true,
50 | "no-unused-variable": true,
51 | "no-use-before-declare": true,
52 | "no-var-keyword": true,
53 | "object-literal-sort-keys": false,
54 | "one-line": [
55 | true,
56 | "check-open-brace",
57 | "check-catch",
58 | "check-else",
59 | "check-whitespace"
60 | ],
61 | "quotemark": [
62 | true,
63 | "single"
64 | ],
65 | "radix": true,
66 | "semicolon": [
67 | true,
68 | "always"
69 | ],
70 | "triple-equals": [
71 | true,
72 | "allow-null-check"
73 | ],
74 | "typedef-whitespace": [
75 | true,
76 | {
77 | "call-signature": "nospace",
78 | "index-signature": "nospace",
79 | "parameter": "nospace",
80 | "property-declaration": "nospace",
81 | "variable-declaration": "nospace"
82 | }
83 | ],
84 | "variable-name": false,
85 | "whitespace": [
86 | true,
87 | "check-branch",
88 | "check-decl",
89 | "check-operator",
90 | "check-separator",
91 | "check-type"
92 | ],
93 | "directive-selector": [true, "attribute", "", "camelCase"],
94 | "component-selector": [true, "element", "", "kebab-case"],
95 | "use-input-property-decorator": true,
96 | "use-output-property-decorator": true,
97 | "use-host-property-decorator": true,
98 | "no-input-rename": true,
99 | "no-output-rename": true,
100 | "use-life-cycle-interface": true,
101 | "use-pipe-transform-interface": true,
102 | "component-class-suffix": true,
103 | "directive-class-suffix": true
104 | }
105 | }
106 |
--------------------------------------------------------------------------------