@beeq/angular 1.8.0-beta.9 → 1.8.0

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.
Files changed (79) hide show
  1. package/README.md +32 -15
  2. package/eslint.config.js +45 -0
  3. package/jest.config.ts +21 -0
  4. package/ng-package.json +8 -0
  5. package/package.json +20 -39
  6. package/project.json +41 -0
  7. package/scripts/fix-value-accessor-path.ts +94 -0
  8. package/src/beeq.module.ts +41 -0
  9. package/src/directives/angular-component-lib/utils.ts +65 -0
  10. package/src/directives/boolean-value-accessor.ts +27 -0
  11. package/src/directives/components.ts +2621 -0
  12. package/src/directives/index.ts +47 -0
  13. package/src/directives/number-value-accessor.ts +29 -0
  14. package/src/directives/radio-value-accessor.ts +24 -0
  15. package/src/directives/select-value-accessor.ts +24 -0
  16. package/src/directives/text-value-accessor.ts +24 -0
  17. package/src/directives/value-accessor.ts +39 -0
  18. package/src/index.ts +15 -0
  19. package/src/test-setup.ts +1 -0
  20. package/standalone/ng-package.json +5 -0
  21. package/standalone/src/directives/angular-component-lib/utils.ts +65 -0
  22. package/standalone/src/directives/boolean-value-accessor.ts +27 -0
  23. package/standalone/src/directives/components.ts +1479 -0
  24. package/standalone/src/directives/index.ts +47 -0
  25. package/standalone/src/directives/number-value-accessor.ts +29 -0
  26. package/standalone/src/directives/radio-value-accessor.ts +24 -0
  27. package/standalone/src/directives/select-value-accessor.ts +24 -0
  28. package/standalone/src/directives/text-value-accessor.ts +24 -0
  29. package/standalone/src/directives/value-accessor.ts +39 -0
  30. package/{index.d.ts → standalone/src/index.ts} +4 -1
  31. package/tsconfig.json +19 -0
  32. package/tsconfig.lib.json +12 -0
  33. package/tsconfig.lib.prod.json +18 -0
  34. package/tsconfig.spec.json +10 -0
  35. package/beeq.module.d.ts +0 -15
  36. package/directives/angular-component-lib/utils.d.ts +0 -9
  37. package/directives/boolean-value-accessor.d.ts +0 -9
  38. package/directives/components.d.ts +0 -784
  39. package/directives/index.d.ts +0 -2
  40. package/directives/number-value-accessor.d.ts +0 -9
  41. package/directives/radio-value-accessor.d.ts +0 -8
  42. package/directives/select-value-accessor.d.ts +0 -8
  43. package/directives/text-value-accessor.d.ts +0 -8
  44. package/directives/value-accessor.d.ts +0 -18
  45. package/esm2022/beeq-angular.mjs +0 -5
  46. package/esm2022/beeq.module.mjs +0 -59
  47. package/esm2022/directives/angular-component-lib/utils.mjs +0 -59
  48. package/esm2022/directives/boolean-value-accessor.mjs +0 -38
  49. package/esm2022/directives/components.mjs +0 -1221
  50. package/esm2022/directives/index.mjs +0 -46
  51. package/esm2022/directives/number-value-accessor.mjs +0 -40
  52. package/esm2022/directives/radio-value-accessor.mjs +0 -35
  53. package/esm2022/directives/select-value-accessor.mjs +0 -35
  54. package/esm2022/directives/text-value-accessor.mjs +0 -35
  55. package/esm2022/directives/value-accessor.mjs +0 -42
  56. package/esm2022/index.mjs +0 -14
  57. package/esm2022/standalone/beeq-angular-standalone.mjs +0 -5
  58. package/esm2022/standalone/directives/angular-component-lib/utils.mjs +0 -59
  59. package/esm2022/standalone/directives/boolean-value-accessor.mjs +0 -38
  60. package/esm2022/standalone/directives/components.mjs +0 -1349
  61. package/esm2022/standalone/directives/number-value-accessor.mjs +0 -40
  62. package/esm2022/standalone/directives/radio-value-accessor.mjs +0 -35
  63. package/esm2022/standalone/directives/select-value-accessor.mjs +0 -35
  64. package/esm2022/standalone/directives/text-value-accessor.mjs +0 -35
  65. package/esm2022/standalone/directives/value-accessor.mjs +0 -42
  66. package/esm2022/standalone/index.mjs +0 -10
  67. package/fesm2022/beeq-angular-standalone.mjs +0 -1578
  68. package/fesm2022/beeq-angular-standalone.mjs.map +0 -1
  69. package/fesm2022/beeq-angular.mjs +0 -1545
  70. package/fesm2022/beeq-angular.mjs.map +0 -1
  71. package/standalone/directives/angular-component-lib/utils.d.ts +0 -9
  72. package/standalone/directives/boolean-value-accessor.d.ts +0 -9
  73. package/standalone/directives/components.d.ts +0 -784
  74. package/standalone/directives/number-value-accessor.d.ts +0 -9
  75. package/standalone/directives/radio-value-accessor.d.ts +0 -8
  76. package/standalone/directives/select-value-accessor.d.ts +0 -8
  77. package/standalone/directives/text-value-accessor.d.ts +0 -8
  78. package/standalone/directives/value-accessor.d.ts +0 -18
  79. package/standalone/index.d.ts +0 -6
package/README.md CHANGED
@@ -4,24 +4,18 @@ An Angular-specific wrapper on top of BEEQ web components that enables NG_VALUE_
4
4
 
5
5
  ## Package installation
6
6
 
7
- - install the package
8
-
9
- ```
10
- npm install @beeq/angular
11
- ```
12
-
13
- - update the package
7
+ > [!TIP]
8
+ > Please always refer to the [official BEEQ documentation](https://www.beeq.design/3d466e231/p/359a26-for-developers/b/08eb89) for more information about the installation.
14
9
 
15
- ```
16
- npm install @beeq/angular@latest
17
- ```
18
-
19
- if the `@beeq/core` package is added to your `package.json` should update both
10
+ - install the package
20
11
 
21
12
  ```
22
13
  npm install @beeq/{core,angular}
23
14
  ```
24
15
 
16
+ > [!NOTE]
17
+ > Make sure that you have installed the `@beeq/core` package.
18
+
25
19
  ## Setup
26
20
 
27
21
  ### Call `defineCustomElements`
@@ -43,7 +37,10 @@ applyPolyfills().then(() => {
43
37
 
44
38
  ### Add BEEQ styles and assets
45
39
 
46
- > ❗️The icons SVG are shipped in a separate folder. Projects will need to include `node_modules/@beeq/core/dist/beeq/svg` in their build and try to make it in a certain way that it respond to: `http://<domain>/svg`
40
+ > [!TIP]
41
+ > BEEQ uses SVG icons and these assets are shipped in a separate folder. You can use the `setBasePath` method to set the path to the icons. Make sure that your project bundle the icons in a way that they are accessible from the browser.
42
+
43
+ You can move the icons from the node_modules folder to your assets folder and set the path like this:
47
44
 
48
45
  ```json
49
46
  /** angular.json */
@@ -65,7 +62,7 @@ applyPolyfills().then(() => {
65
62
  {
66
63
  "glob": "**/*",
67
64
  "input": "node_modules/@beeq/core/dist/beeq/svg",
68
- "output": "/svg/"
65
+ "output": "assets/svg/"
69
66
  }
70
67
  ],
71
68
  "styles": [
@@ -81,6 +78,25 @@ applyPolyfills().then(() => {
81
78
  }
82
79
  ```
83
80
 
81
+ ```js
82
+ // main.ts
83
+ import { setBasePath } from '@beeq/core';
84
+
85
+ setBasePath('/assets/svg/');
86
+ ```
87
+
88
+ But you can also use a different icons library or a CDN (*no need to move the icons to your assets folder via angular.json*):
89
+
90
+ ```js
91
+ import { setBasePath } from '@beeq/core';
92
+
93
+ // Using heroicons library
94
+ setBasePath('https://cdn.jsdelivr.net/npm/heroicons@2.1.5/24/outline');
95
+ ```
96
+
97
+ > [!CAUTION]
98
+ > When using a different icons library, make sure you use the correct icon names provided by the library or the CDN.
99
+
84
100
  BEEQ styles can be also imported into your application's main style file:
85
101
 
86
102
  ```css
@@ -112,7 +128,8 @@ export class AppModule {}
112
128
 
113
129
  To enable two-way binding and the use of [ngModel] within BEEQ form components, you will need to add the Value Accessors in your module declarations, along with `@angular/forms`.
114
130
 
115
- > ❗️❗️ *Please notice that* **you might need to disable** `aot` *for enabling two-way data binding**. Details: https://github.com/ionic-team/stencil-ds-output-targets/issues/317*
131
+ > [!CAUTION]
132
+ > *Please notice that* **you might need to disable** `aot` *for enabling two-way data binding**. Details: https://github.com/ionic-team/stencil-ds-output-targets/issues/317*
116
133
 
117
134
  ```ts
118
135
  import { NgModule } from '@angular/core';
@@ -0,0 +1,45 @@
1
+ const { fixupPluginRules } = require('@eslint/compat');
2
+ const nxESLint = require('@nx/eslint-plugin');
3
+ const angularESLint = require('@angular-eslint/eslint-plugin');
4
+ const jsoncParser = require('jsonc-eslint-parser');
5
+
6
+ /** @type { import("eslint").Linter.Config[] } */
7
+ module.exports = [
8
+ {
9
+ files: ['*.ts'],
10
+ plugins: {
11
+ '@angular-eslint': fixupPluginRules(angularESLint),
12
+ },
13
+ rules: {
14
+ '@angular-eslint/component-selector': [
15
+ 'error',
16
+ {
17
+ type: 'element',
18
+ prefix: 'bq',
19
+ style: 'kebab-case',
20
+ },
21
+ ],
22
+ '@angular-eslint/component-class-suffix': 'off',
23
+ '@angular-eslint/directive-class-suffix': 'off',
24
+ '@angular-eslint/directive-selector': 'off',
25
+ '@angular-eslint/no-host-metadata-property': 'off',
26
+ },
27
+ },
28
+ {
29
+ files: ['**/package.json', '**/project.json'],
30
+ languageOptions: {
31
+ parser: jsoncParser,
32
+ },
33
+ plugins: {
34
+ '@nx': nxESLint,
35
+ },
36
+ rules: {
37
+ '@nx/dependency-checks': [
38
+ 'error',
39
+ {
40
+ ignoredDependencies: ['@beeq/core', '@stencil/core', 'tslib'],
41
+ },
42
+ ],
43
+ },
44
+ },
45
+ ];
package/jest.config.ts ADDED
@@ -0,0 +1,21 @@
1
+ export default {
2
+ displayName: 'beeq-angular',
3
+ preset: '../../jest.preset.js',
4
+ setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
5
+ globals: {
6
+ 'ts-jest': {
7
+ tsconfig: '<rootDir>/tsconfig.spec.json',
8
+ stringifyContentPathRegex: '\\.(html|svg)$',
9
+ },
10
+ },
11
+ coverageDirectory: '../../coverage/packages/beeq-angular',
12
+ transform: {
13
+ '^.+\\.(ts|mjs|js|html)$': 'jest-preset-angular',
14
+ },
15
+ transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'],
16
+ snapshotSerializers: [
17
+ 'jest-preset-angular/build/serializers/no-ng-attributes',
18
+ 'jest-preset-angular/build/serializers/ng-snapshot',
19
+ 'jest-preset-angular/build/serializers/html-comment',
20
+ ],
21
+ };
@@ -0,0 +1,8 @@
1
+ {
2
+ "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
3
+ "dest": "../../dist/beeq-angular",
4
+ "lib": {
5
+ "entryFile": "src/index.ts"
6
+ },
7
+ "allowedNonPeerDependencies": ["@beeq/core", "jsonc-parser"]
8
+ }
package/package.json CHANGED
@@ -1,40 +1,21 @@
1
1
  {
2
- "name": "@beeq/angular",
3
- "version": "1.8.0-beta.9",
4
- "license": "Apache-2.0",
5
- "description": "Angular specific wrapper for BEEQ Design System components",
6
- "main": "dist/esm2015/index.js",
7
- "module": "fesm2022/beeq-angular.mjs",
8
- "types": "index.d.ts",
9
- "dependencies": {
10
- "@beeq/core": "^1.8.0-beta.9",
11
- "tslib": "^2.6.3"
12
- },
13
- "peerDependencies": {
14
- "@angular/common": ">=14.0.0",
15
- "@angular/core": ">=14.0.0"
16
- },
17
- "repository": {
18
- "type": "git",
19
- "url": "https://github.com/Endava/BEEQ"
20
- },
21
- "typings": "index.d.ts",
22
- "exports": {
23
- "./package.json": {
24
- "default": "./package.json"
25
- },
26
- ".": {
27
- "types": "./index.d.ts",
28
- "esm2022": "./esm2022/beeq-angular.mjs",
29
- "esm": "./esm2022/beeq-angular.mjs",
30
- "default": "./fesm2022/beeq-angular.mjs"
31
- },
32
- "./standalone": {
33
- "types": "./standalone/index.d.ts",
34
- "esm2022": "./esm2022/standalone/beeq-angular-standalone.mjs",
35
- "esm": "./esm2022/standalone/beeq-angular-standalone.mjs",
36
- "default": "./fesm2022/beeq-angular-standalone.mjs"
37
- }
38
- },
39
- "sideEffects": false
40
- }
2
+ "name": "@beeq/angular",
3
+ "version": "1.8.0",
4
+ "license": "Apache-2.0",
5
+ "description": "Angular specific wrapper for BEEQ Design System components",
6
+ "main": "dist/esm2015/index.js",
7
+ "module": "dist/esm2015/index.js",
8
+ "types": "index.d.ts",
9
+ "dependencies": {
10
+ "@beeq/core": "^1.8.0",
11
+ "tslib": "^2.6.3"
12
+ },
13
+ "peerDependencies": {
14
+ "@angular/common": ">=14.0.0",
15
+ "@angular/core": ">=14.0.0"
16
+ },
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "https://github.com/Endava/BEEQ"
20
+ }
21
+ }
package/project.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "beeq-angular",
3
+ "$schema": "../../node_modules/nx/schemas/project-schema.json",
4
+ "sourceRoot": "packages/beeq-angular/src",
5
+ "projectType": "library",
6
+ "tags": ["wrapper", "angular", "publishable"],
7
+ "prefix": "beeq",
8
+ "implicitDependencies": ["beeq"],
9
+ "targets": {
10
+ "prebuild": {
11
+ "executor": "nx:run-commands",
12
+ "options": {
13
+ "commands": ["tsx packages/beeq-angular/scripts/fix-value-accessor-path.ts"]
14
+ },
15
+ "dependsOn": [{ "dependencies": true, "target": "build" }]
16
+ },
17
+ "build": {
18
+ "executor": "@nx/angular:package",
19
+ "outputs": ["{workspaceRoot}/dist/beeq-angular"],
20
+ "options": {
21
+ "project": "{projectRoot}/ng-package.json"
22
+ },
23
+ "configurations": {
24
+ "production": {
25
+ "tsConfig": "{projectRoot}/tsconfig.lib.prod.json"
26
+ },
27
+ "development": {
28
+ "tsConfig": "{projectRoot}/tsconfig.lib.json"
29
+ }
30
+ },
31
+ "defaultConfiguration": "production",
32
+ "dependsOn": [{ "target": "prebuild" }]
33
+ },
34
+ "lint": {
35
+ "executor": "@nx/eslint:lint",
36
+ "options": {
37
+ "lintFilePatterns": ["{projectRoot}/**/*.ts", "{projectRoot}/package.json", "{projectRoot}/project.json"]
38
+ }
39
+ }
40
+ }
41
+ }
@@ -0,0 +1,94 @@
1
+ import { resolve } from 'path';
2
+ import { promises as fs } from 'fs';
3
+
4
+ ['module', 'standalone'].forEach((type) => {
5
+ fixValueAccessorPath(type);
6
+ });
7
+
8
+ /**
9
+ * Fix the value accessor path by moving the file to the correct path
10
+ *
11
+ * @param {string} type - The type of the Angular project (module or standalone)
12
+ */
13
+ async function fixValueAccessorPath(type: string): Promise<void> {
14
+ const angularProjectPath = type === 'module' ? '.' : 'standalone';
15
+
16
+ // Define the folders and files paths
17
+ const basePath = resolve(__dirname, `../${angularProjectPath}/src/directives`).replace(/\\/g, '/');
18
+ const wrongFolderPath = `${basePath}/value-accessor.ts`;
19
+ const backupFolderPath = `${basePath}/value-accessor`;
20
+ const sourceFilePath = `${basePath}/value-accessor/value-accessor.ts`;
21
+ const destinationFilePath = wrongFolderPath;
22
+
23
+ // Check if the wrong file exists
24
+ if (await isDirectory(wrongFolderPath)) {
25
+ console.info(`Renaming wrong Value Accessor file for angular ${type} project...`);
26
+ await renameDirectory(wrongFolderPath, backupFolderPath);
27
+ } else {
28
+ console.info(`No changes required! Wrong folder does not exist for angular ${type} project`);
29
+ return;
30
+ }
31
+
32
+ // Move the file to the correct path
33
+ if (await isDirectory(backupFolderPath)) {
34
+ console.info(`Moving wrong Value Accessor file for angular ${type} project to the correct path...`);
35
+
36
+ try {
37
+ await moveFile(sourceFilePath, destinationFilePath);
38
+ await removeDirectory(backupFolderPath);
39
+ console.info(`File moved successfully for angular ${type} project to the correct path.`);
40
+ } catch (err) {
41
+ console.error(`Error moving the file for angular ${type} project`, err);
42
+ process.exit(1); // Exit the process with a failure code
43
+ }
44
+ } else {
45
+ console.warn(`No changes required! Source folder does not exist for angular ${type} project`);
46
+ }
47
+ }
48
+
49
+ /**
50
+ * Check if a path exists and is a directory
51
+ *
52
+ * @param {string} path - The path to check
53
+ * @returns {Promise<boolean>}
54
+ */
55
+ async function isDirectory(path: string): Promise<boolean> {
56
+ try {
57
+ const stat = await fs.stat(path);
58
+ return stat.isDirectory();
59
+ } catch {
60
+ return false;
61
+ }
62
+ }
63
+
64
+ /**
65
+ * Rename a directory
66
+ *
67
+ * @param {string} oldPath - The current path of the directory
68
+ * @param {string} newPath - The new path of the directory
69
+ * @returns {Promise<void>}
70
+ */
71
+ async function renameDirectory(oldPath: string, newPath: string): Promise<void> {
72
+ await fs.rename(oldPath, newPath);
73
+ }
74
+
75
+ /**
76
+ * Move a file
77
+ *
78
+ * @param {string} source - The source file path
79
+ * @param {string} destination - The destination file path
80
+ * @returns {Promise<void>}
81
+ */
82
+ async function moveFile(source: string, destination: string): Promise<void> {
83
+ await fs.rename(source, destination);
84
+ }
85
+
86
+ /**
87
+ * Remove a directory
88
+ *
89
+ * @param {string} path - The path of the directory to remove
90
+ * @returns {Promise<void>}
91
+ */
92
+ async function removeDirectory(path: string): Promise<void> {
93
+ await fs.rmdir(path);
94
+ }
@@ -0,0 +1,41 @@
1
+ import { CommonModule, DOCUMENT } from '@angular/common';
2
+ import { APP_INITIALIZER, ModuleWithProviders, NgModule, NgZone } from '@angular/core';
3
+ import { defineCustomElements } from '@beeq/core/dist/loader';
4
+
5
+ import { DIRECTIVES } from './directives';
6
+ import { BooleanValueAccessor } from './directives/boolean-value-accessor';
7
+ import { NumericValueAccessor } from './directives/number-value-accessor';
8
+ import { RadioValueAccessor } from './directives/radio-value-accessor';
9
+ import { SelectValueAccessor } from './directives/select-value-accessor';
10
+ import { TextValueAccessor } from './directives/text-value-accessor';
11
+
12
+ const DECLARATIONS = [
13
+ ...DIRECTIVES,
14
+ // ngModel Accessors
15
+ BooleanValueAccessor,
16
+ NumericValueAccessor,
17
+ RadioValueAccessor,
18
+ SelectValueAccessor,
19
+ TextValueAccessor,
20
+ ];
21
+
22
+ @NgModule({
23
+ imports: [CommonModule],
24
+ declarations: DECLARATIONS,
25
+ exports: DECLARATIONS,
26
+ })
27
+ export class BeeQModule {
28
+ static forRoot(): ModuleWithProviders<BeeQModule> {
29
+ return {
30
+ ngModule: BeeQModule,
31
+ providers: [
32
+ {
33
+ provide: APP_INITIALIZER,
34
+ useFactory: () => defineCustomElements,
35
+ multi: true,
36
+ deps: [DOCUMENT, NgZone],
37
+ },
38
+ ],
39
+ };
40
+ }
41
+ }
@@ -0,0 +1,65 @@
1
+ /* eslint-disable */
2
+ /* tslint:disable */
3
+ import { fromEvent } from 'rxjs';
4
+
5
+ export const proxyInputs = (Cmp: any, inputs: string[]) => {
6
+ const Prototype = Cmp.prototype;
7
+ inputs.forEach((item) => {
8
+ Object.defineProperty(Prototype, item, {
9
+ get() {
10
+ return this.el[item];
11
+ },
12
+ set(val: any) {
13
+ this.z.runOutsideAngular(() => (this.el[item] = val));
14
+ },
15
+ /**
16
+ * In the event that proxyInputs is called
17
+ * multiple times re-defining these inputs
18
+ * will cause an error to be thrown. As a result
19
+ * we set configurable: true to indicate these
20
+ * properties can be changed.
21
+ */
22
+ configurable: true,
23
+ });
24
+ });
25
+ };
26
+
27
+ export const proxyMethods = (Cmp: any, methods: string[]) => {
28
+ const Prototype = Cmp.prototype;
29
+ methods.forEach((methodName) => {
30
+ Prototype[methodName] = function () {
31
+ const args = arguments;
32
+ return this.z.runOutsideAngular(() => this.el[methodName].apply(this.el, args));
33
+ };
34
+ });
35
+ };
36
+
37
+ export const proxyOutputs = (instance: any, el: any, events: string[]) => {
38
+ events.forEach((eventName) => (instance[eventName] = fromEvent(el, eventName)));
39
+ };
40
+
41
+ export const defineCustomElement = (tagName: string, customElement: any) => {
42
+ if (customElement !== undefined && typeof customElements !== 'undefined' && !customElements.get(tagName)) {
43
+ customElements.define(tagName, customElement);
44
+ }
45
+ };
46
+
47
+ // tslint:disable-next-line: only-arrow-functions
48
+ export function ProxyCmp(opts: { defineCustomElementFn?: () => void; inputs?: any; methods?: any }) {
49
+ const decorator = function (cls: any) {
50
+ const { defineCustomElementFn, inputs, methods } = opts;
51
+
52
+ if (defineCustomElementFn !== undefined) {
53
+ defineCustomElementFn();
54
+ }
55
+
56
+ if (inputs) {
57
+ proxyInputs(cls, inputs);
58
+ }
59
+ if (methods) {
60
+ proxyMethods(cls, methods);
61
+ }
62
+ return cls;
63
+ };
64
+ return decorator;
65
+ }
@@ -0,0 +1,27 @@
1
+ import { Directive, ElementRef } from '@angular/core';
2
+ import { NG_VALUE_ACCESSOR } from '@angular/forms';
3
+
4
+ import { ValueAccessor } from './value-accessor';
5
+
6
+ @Directive({
7
+ /* tslint:disable-next-line:directive-selector */
8
+ selector: 'bq-checkbox, bq-switch',
9
+ host: {
10
+ '(bqChange)': 'handleChangeEvent($event.target.checked)'
11
+ },
12
+ providers: [
13
+ {
14
+ provide: NG_VALUE_ACCESSOR,
15
+ useExisting: BooleanValueAccessor,
16
+ multi: true
17
+ }
18
+ ]
19
+ })
20
+ export class BooleanValueAccessor extends ValueAccessor {
21
+ constructor(el: ElementRef) {
22
+ super(el);
23
+ }
24
+ override writeValue(value: any) {
25
+ this.el.nativeElement.checked = this.lastValue = value == null ? false : value;
26
+ }
27
+ }