@stackline/angular-multiselect-dropdown 2.0.5 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,13 +6,13 @@
6
6
  [![npm downloads](https://img.shields.io/npm/dt/@stackline/angular-multiselect-dropdown.svg?style=flat-square)](https://www.npmjs.com/package/@stackline/angular-multiselect-dropdown)
7
7
  [![npm monthly](https://img.shields.io/npm/dm/@stackline/angular-multiselect-dropdown.svg?style=flat-square)](https://www.npmjs.com/package/@stackline/angular-multiselect-dropdown)
8
8
  [![license](https://img.shields.io/npm/l/@stackline/angular-multiselect-dropdown.svg?style=flat-square)](https://github.com/alexandroit/angular-multiselect-dropdown/blob/master/LICENSE)
9
- [![Angular 2](https://img.shields.io/badge/Angular-2.x-red?style=flat-square&logo=angular)](https://alexandro.net/docs/angular/multiselect/angular-2/)
9
+ [![Angular 4](https://img.shields.io/badge/Angular-4.x-red?style=flat-square&logo=angular)](https://alexandro.net/docs/angular/multiselect/angular-4/)
10
10
  [![TypeScript](https://img.shields.io/badge/TypeScript-2.4-blue?style=flat-square&logo=typescript)](https://www.typescriptlang.org)
11
11
  [![GitHub stars](https://img.shields.io/github/stars/alexandroit/angular-multiselect-dropdown.svg?style=flat-square)](https://github.com/alexandroit/angular-multiselect-dropdown/stargazers)
12
12
 
13
- **[Documentation & Live Demos](https://alexandro.net/docs/angular/multiselect/)** | **[Angular 2 Demo](https://alexandro.net/docs/angular/multiselect/angular-2/)** | **[npm](https://www.npmjs.com/package/@stackline/angular-multiselect-dropdown)** | **[Issues](https://github.com/alexandroit/angular-multiselect-dropdown/issues)** | **[Repository](https://github.com/alexandroit/angular-multiselect-dropdown)**
13
+ **[Documentation & Live Demos](https://alexandro.net/docs/angular/multiselect/)** | **[Angular 4 Demo](https://alexandro.net/docs/angular/multiselect/angular-4/)** | **[npm](https://www.npmjs.com/package/@stackline/angular-multiselect-dropdown)** | **[Issues](https://github.com/alexandroit/angular-multiselect-dropdown/issues)** | **[Repository](https://github.com/alexandroit/angular-multiselect-dropdown)**
14
14
 
15
- **Latest tested npm release:** `2.0.5` for Angular `2.x`
15
+ **Latest tested npm release:** `4.0.1` for Angular `4.x`
16
16
 
17
17
  ---
18
18
 
@@ -24,15 +24,15 @@
24
24
 
25
25
  The original `angular2-multiselect-dropdown` package became difficult to keep current across multiple Angular generations. This maintained package keeps the classic API and template structure intact, introduces the new primary selector `<angular-multiselect>`, preserves the legacy alias `<angular2-multiselect>`, and publishes the project line by line so older applications can keep a predictable upgrade path.
26
26
 
27
- The repository contains the full documentation matrix from Angular 2 through Angular 21. The current public npm release is `2.0.5` for Angular 2.x applications.
27
+ The repository contains the full documentation matrix from Angular 2 through Angular 21. The current public npm release is `4.0.1` for Angular 4.x applications.
28
28
 
29
- The Angular 2 package is compatible with Angular 2.x and was tested in a real Angular 2.4.10 application before publication.
29
+ The Angular 4 package is compatible with Angular 4.x and was tested in a real Angular 4.4.7 application before npm publication.
30
30
 
31
31
  ## Features
32
32
 
33
33
  | Feature | Supported |
34
34
  | :--- | :---: |
35
- | Angular 2 tested published release line | ✅ |
35
+ | Angular 4 tested published release line | ✅ |
36
36
  | Multi-select and single-select modes | ✅ |
37
37
  | Search and filter | ✅ |
38
38
  | Group by field | ✅ |
@@ -54,12 +54,13 @@ The Angular 2 package is compatible with Angular 2.x and was tested in a real An
54
54
  4. [Setup](#setup)
55
55
  5. [Custom CSS and SCSS Themes](#custom-css-and-scss-themes)
56
56
  6. [Basic Usage](#basic-usage)
57
- 7. [Custom Templates](#custom-templates)
58
- 8. [Forms Integration](#forms-integration)
59
- 9. [Lazy Loading and Remote Data](#lazy-loading-and-remote-data)
60
- 10. [Events](#events)
61
- 11. [Run Locally](#run-locally)
62
- 12. [License](#license)
57
+ 7. [Official Angular 4 Test Matrix](#official-angular-4-test-matrix)
58
+ 8. [Custom Templates](#custom-templates)
59
+ 9. [Forms Integration](#forms-integration)
60
+ 10. [Lazy Loading and Remote Data](#lazy-loading-and-remote-data)
61
+ 11. [Events](#events)
62
+ 12. [Run Locally](#run-locally)
63
+ 13. [License](#license)
63
64
 
64
65
  ## Rename Note
65
66
 
@@ -98,10 +99,10 @@ Each package family only installs on its matching Angular family. Framework majo
98
99
  ## Installation
99
100
 
100
101
  ```bash
101
- npm install @stackline/angular-multiselect-dropdown@2.0.5
102
+ npm install @stackline/angular-multiselect-dropdown@4.0.1 --save-exact
102
103
  ```
103
104
 
104
- Install `2.0.5` for Angular 2.x applications. This patch keeps the tested Angular 2 behavior, makes `<angular-multiselect>` the documented standard selector, and keeps `<angular2-multiselect>` only as a legacy compatibility alias.
105
+ Install `4.0.1` for Angular 4.x applications. This line keeps the tested Angular 4 behavior, makes `<angular-multiselect>` the documented standard selector, and keeps `<angular2-multiselect>` only as a legacy compatibility alias.
105
106
 
106
107
  ## Setup
107
108
 
@@ -155,20 +156,30 @@ Use the `css` file when you want a plain compiled starter that can be copied and
155
156
 
156
157
  ```ts
157
158
  dropdownList = [
158
- { id: 1, itemName: 'India' },
159
- { id: 2, itemName: 'Singapore' },
160
- { id: 3, itemName: 'Australia' },
161
- { id: 4, itemName: 'Canada' }
159
+ { id: 1, itemName: 'Brazil' },
160
+ { id: 2, itemName: 'Canada' },
161
+ { id: 3, itemName: 'Portugal' },
162
+ { id: 4, itemName: 'United States' },
163
+ { id: 5, itemName: 'Argentina' },
164
+ { id: 6, itemName: 'Germany' },
165
+ { id: 7, itemName: 'Japan' },
166
+ { id: 8, itemName: 'South Africa' }
162
167
  ];
163
168
 
164
- selectedItems = [{ id: 2, itemName: 'Singapore' }];
169
+ selectedItems = [{ id: 2, itemName: 'Canada' }];
165
170
 
166
171
  dropdownSettings = {
167
172
  singleSelection: false,
168
- text: 'Select Countries',
169
- selectAllText: 'Select All',
170
- unSelectAllText: 'UnSelect All',
173
+ text: 'Classic basic',
174
+ selectAllText: 'Select all',
175
+ unSelectAllText: 'Clear all',
171
176
  enableSearchFilter: true,
177
+ searchPlaceholderText: 'Search',
178
+ badgeShowLimit: 4,
179
+ maxHeight: 260,
180
+ showCheckbox: true,
181
+ noDataLabel: 'No data',
182
+ theme: 'classic',
172
183
  tagToBody: false
173
184
  };
174
185
  ```
@@ -185,6 +196,41 @@ dropdownSettings = {
185
196
  </angular-multiselect>
186
197
  ```
187
198
 
199
+ ## Official Angular 4 Test Matrix
200
+
201
+ The published Angular 4 release was tested in a real Angular `4.4.7` application with `@stackline/angular-multiselect-dropdown@4.0.1`. The docs now use the same examples from that test app.
202
+
203
+ Switch between skins through the settings object:
204
+
205
+ ```ts
206
+ settings = {
207
+ text: 'Classic basic',
208
+ theme: 'classic'
209
+ };
210
+
211
+ materialSettings = {
212
+ text: 'Material basic',
213
+ theme: 'material'
214
+ };
215
+ ```
216
+
217
+ The same twelve scenarios are validated for both `classic` and `material`:
218
+
219
+ | # | Scenario | Main settings tested |
220
+ | :---: | :--- | :--- |
221
+ | 01 | Basic multi | `{ enableSearchFilter: false }` |
222
+ | 02 | Search + select all | Search, select all, clear all, events |
223
+ | 03 | Single without checkbox | `{ singleSelection: true, showCheckbox: false, enableCheckAll: false }` |
224
+ | 04 | Multi without checkbox | `{ showCheckbox: false, enableCheckAll: false }` |
225
+ | 05 | Selection limit | `{ limitSelection: 2, badgeShowLimit: 2 }` |
226
+ | 06 | Badge overflow | `{ badgeShowLimit: 2, maxHeight: 220 }` |
227
+ | 07 | Grouped by region | `{ groupBy: 'region', maxHeight: 220 }` |
228
+ | 08 | Disabled with value | `{ disabled: true }` |
229
+ | 09 | Empty data | `{ noDataLabel: 'No records found' }` |
230
+ | 10 | Long list with scroll | `{ maxHeight: 120, badgeShowLimit: 3 }` |
231
+ | 11 | Local lazy loading | `{ lazyLoading: true, maxHeight: 120, badgeShowLimit: 3 }` |
232
+ | 12 | Item + chip template | `<c-badge>` and `<c-item>` custom templates |
233
+
188
234
  ## Custom Templates
189
235
 
190
236
  ```html
@@ -264,10 +310,6 @@ The classic output contract is preserved:
264
310
  ```bash
265
311
  npm install
266
312
  npm run docs:sync
267
- npm run build-package
268
- cd docs-src/angular-21
269
- npm install --ignore-scripts
270
- npm run build
271
313
  ```
272
314
 
273
315
  ## License
@@ -0,0 +1 @@
1
+ export * from './src/app/angular2-multiselect-dropdown/multiselect.component';
package/gulpfile.js ADDED
@@ -0,0 +1,68 @@
1
+ const gulp = require('gulp');
2
+ const sass = require('node-sass');
3
+ const inlineTemplates = require('gulp-inline-ng2-template');
4
+ const exec = require('child_process').exec;
5
+
6
+ /**
7
+ * Inline templates configuration.
8
+ * @see https://github.com/ludohenin/gulp-inline-ng2-template
9
+ */
10
+ const INLINE_TEMPLATES = {
11
+ SRC: './src/app/angular2-multiselect-dropdown/**/*.ts',
12
+ DIST: './tmp/src-inlined',
13
+ CONFIG: {
14
+ base: '/src/app/angular2-multiselect-dropdown',
15
+ target: 'es6',
16
+ useRelativePaths: true,
17
+ styleProcessor: compileSass
18
+ }
19
+ };
20
+
21
+ /**
22
+ * Inline external HTML and SCSS templates into Angular component files.
23
+ * @see: https://github.com/ludohenin/gulp-inline-ng2-template
24
+ */
25
+ gulp.task('inline-templates', () => {
26
+ return gulp.src(INLINE_TEMPLATES.SRC)
27
+ .pipe(inlineTemplates(INLINE_TEMPLATES.CONFIG))
28
+ .pipe(gulp.dest(INLINE_TEMPLATES.DIST));
29
+ });
30
+
31
+ /**
32
+ * Build ESM by running npm task.
33
+ * This is a temporary solution until ngc is supported --watch mode.
34
+ * @see: https://github.com/angular/angular/issues/12867
35
+ */
36
+ gulp.task('build:esm', ['inline-templates'], (callback) => {
37
+ exec('npm run ngcompile', function (error, stdout, stderr) {
38
+ console.log(stdout, stderr);
39
+ callback(error)
40
+ });
41
+ });
42
+
43
+ /**
44
+ * Implements ESM build watch mode.
45
+ * This is a temporary solution until ngc is supported --watch mode.
46
+ * @see: https://github.com/angular/angular/issues/12867
47
+ */
48
+ gulp.task('build:esm:watch', ['build:esm'], () => {
49
+ gulp.watch('src/**/*', ['build:esm']);
50
+ });
51
+
52
+ gulp.task('copy', () => {
53
+ return gulp.src(['package.json','LICENSE','README.md'])
54
+ .pipe(gulp.dest('dist/'));
55
+ });
56
+
57
+ /**
58
+ * Compile SASS to CSS.
59
+ * @see https://github.com/ludohenin/gulp-inline-ng2-template
60
+ * @see https://github.com/sass/node-sass
61
+ */
62
+ function compileSass(path, ext, file, callback) {
63
+ let compiledCss = sass.renderSync({
64
+ data: file,
65
+ outputStyle: 'compressed',
66
+ });
67
+ callback(null, compiledCss.css);
68
+ }
@@ -0,0 +1,119 @@
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const glob = require('glob');
6
+
7
+
8
+ /**
9
+ * Simple Promiseify function that takes a Node API and return a version that supports promises.
10
+ * We use promises instead of synchronized functions to make the process less I/O bound and
11
+ * faster. It also simplifies the code.
12
+ */
13
+ function promiseify(fn) {
14
+ return function () {
15
+ const args = [].slice.call(arguments, 0);
16
+ return new Promise((resolve, reject) => {
17
+ fn.apply(this, args.concat([function (err, value) {
18
+ if (err) {
19
+ reject(err);
20
+ } else {
21
+ resolve(value);
22
+ }
23
+ }]));
24
+ });
25
+ };
26
+ }
27
+
28
+ const readFile = promiseify(fs.readFile);
29
+ const writeFile = promiseify(fs.writeFile);
30
+
31
+ /**
32
+ * Inline resources in a tsc/ngc compilation.
33
+ * @param projectPath {string} Path to the project.
34
+ */
35
+ function inlineResources(projectPath) {
36
+
37
+ // Match only TypeScript files in projectPath.
38
+ const files = glob.sync('**/*.ts', {cwd: projectPath});
39
+
40
+ // For each file, inline the templates and styles under it and write the new file.
41
+ return Promise.all(files.map(filePath => {
42
+ const fullFilePath = path.join(projectPath, filePath);
43
+ return readFile(fullFilePath, 'utf-8')
44
+ .then(content => inlineResourcesFromString(content, url => {
45
+ // Resolve the template url.
46
+ return path.join(path.dirname(fullFilePath), url);
47
+ }))
48
+ .then(content => writeFile(fullFilePath, content))
49
+ .catch(err => {
50
+ console.error('An error occured: ', err);
51
+ });
52
+ }));
53
+ }
54
+
55
+ /**
56
+ * Inline resources from a string content.
57
+ * @param content {string} The source file's content.
58
+ * @param urlResolver {Function} A resolver that takes a URL and return a path.
59
+ * @returns {string} The content with resources inlined.
60
+ */
61
+ function inlineResourcesFromString(content, urlResolver) {
62
+ // Curry through the inlining functions.
63
+ return [
64
+ inlineTemplate,
65
+ inlineStyle
66
+ ].reduce((content, fn) => fn(content, urlResolver), content);
67
+ }
68
+
69
+ /**
70
+ * Inline the templates for a source file. Simply search for instances of `templateUrl: ...` and
71
+ * replace with `template: ...` (with the content of the file included).
72
+ * @param content {string} The source file's content.
73
+ * @param urlResolver {Function} A resolver that takes a URL and return a path.
74
+ * @return {string} The content with all templates inlined.
75
+ */
76
+ function inlineTemplate(content, urlResolver) {
77
+ return content.replace(/templateUrl:\s*'([^']+?\.html)'/g, function (m, templateUrl) {
78
+ const templateFile = urlResolver(templateUrl);
79
+ const templateContent = fs.readFileSync(templateFile, 'utf-8');
80
+ const shortenedTemplate = templateContent
81
+ .replace(/([\n\r]\s*)+/gm, ' ')
82
+ .replace(/"/g, '\\"');
83
+ return `template: "${shortenedTemplate}"`;
84
+ });
85
+ }
86
+
87
+
88
+ /**
89
+ * Inline the styles for a source file. Simply search for instances of `styleUrls: [...]` and
90
+ * replace with `styles: [...]` (with the content of the file included).
91
+ * @param urlResolver {Function} A resolver that takes a URL and return a path.
92
+ * @param content {string} The source file's content.
93
+ * @return {string} The content with all styles inlined.
94
+ */
95
+ function inlineStyle(content, urlResolver) {
96
+ return content.replace(/styleUrls:\s*(\[[\s\S]*?\])/gm, function (m, styleUrls) {
97
+ const urls = eval(styleUrls);
98
+ return 'styles: ['
99
+ + urls.map(styleUrl => {
100
+ const styleFile = urlResolver(styleUrl);
101
+ const styleContent = fs.readFileSync(styleFile, 'utf-8');
102
+ const shortenedStyle = styleContent
103
+ .replace(/([\n\r]\s*)+/gm, ' ')
104
+ .replace(/"/g, '\\"');
105
+ return `"${shortenedStyle}"`;
106
+ })
107
+ .join(',\n')
108
+ + ']';
109
+ });
110
+ }
111
+
112
+ module.exports = inlineResources;
113
+ module.exports.inlineResourcesFromString = inlineResourcesFromString;
114
+
115
+ // Run inlineResources if module is being called directly from the CLI with arguments.
116
+ if (require.main === module && process.argv.length > 2) {
117
+ console.log('Inlining resources from project:', process.argv[2]);
118
+ return inlineResources(process.argv[2]);
119
+ }