diff --git a/package-lock.json b/package-lock.json
index 0941c1390..4a98aa5af 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12367,7 +12367,6 @@
"version": "4.12.3",
"resolved": "https://registry.npmjs.org/@stencil/core/-/core-4.12.3.tgz",
"integrity": "sha512-9XkE9i2aXPlApMNeq3tbVHKx0eAfDc7QGyIl6t5NMuQFTOGL5Xd1soF38d+hCIDpUoUUtY7jXWg+iFrlrMzQhg==",
- "dev": true,
"bin": {
"stencil": "bin/stencil"
},
@@ -17797,9 +17796,9 @@
"optional": true
},
"node_modules/bare-fs": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.1.5.tgz",
- "integrity": "sha512-5t0nlecX+N2uJqdxe9d18A98cp2u9BETelbjKpiVgQqzzmVNFYWEAjQHqS+2Khgto1vcwhik9cXucaj5ve2WWA==",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.2.0.tgz",
+ "integrity": "sha512-+VhW202E9eTVGkX7p+TNXtZC4RTzj9JfJW7PtfIbZ7mIQ/QT9uOafQTx7lx2n9ERmWsXvLHF4hStAFn4gl2mQw==",
"dev": true,
"optional": true,
"dependencies": {
@@ -42723,12 +42722,13 @@
"version": "1.0.1",
"license": "Apache-2.0",
"dependencies": {
- "@beeq/core": "*",
+ "@beeq/core": "^1.0.1",
"tslib": "^2.6.2"
},
"peerDependencies": {
"@angular/common": ">=14.0.0",
- "@angular/core": ">=14.0.0"
+ "@angular/core": ">=14.0.0",
+ "@stencil/core": ">=4.0.0"
}
},
"packages/beeq-react": {
@@ -42736,7 +42736,7 @@
"version": "1.0.1",
"license": "Apache-2.0",
"dependencies": {
- "@beeq/core": "*"
+ "@beeq/core": "^1.0.1"
},
"peerDependencies": {
"react": ">=18.0.0",
@@ -42758,7 +42758,7 @@
"version": "1.0.1",
"license": "Apache-2.0",
"dependencies": {
- "@beeq/core": "*",
+ "@beeq/core": "^1.0.1",
"tslib": "^2.3.0"
},
"peerDependencies": {
diff --git a/packages/beeq-angular/README.md b/packages/beeq-angular/README.md
index c845bdae5..629854ef1 100644
--- a/packages/beeq-angular/README.md
+++ b/packages/beeq-angular/README.md
@@ -118,15 +118,11 @@ To enable two-way binding and the use of [ngModel] within BEEQ form components,
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
-import { BeeQModule, BooleanValueAccessor, TextValueAccessor } from '@beeq/angular';
import { AppComponent } from './app.component';
-/** 💡 More Value Accessors will be exported later and should be included as well */
-const VALUE_ACCESSORS = [BooleanValueAccessor, TextValueAccessor];
-
@NgModule({
- declarations: [AppComponent, ...VALUE_ACCESSORS],
+ declarations: [AppComponent],
imports: [BeeQModule.forRoot(), BrowserModule, FormsModule],
providers: [],
bootstrap: [AppComponent],
@@ -135,6 +131,22 @@ const VALUE_ACCESSORS = [BooleanValueAccessor, TextValueAccessor];
export class AppModule {}
```
+> 🙋🏼♂️ If you are using `@beeq/angular` v1.0.1 or below, **you also need to import the values accessors**, as shown below:
+
+```ts
+...
+import { BeeQModule, BooleanValueAccessor, TextValueAccessor } from '@beeq/angular';
+...
+const VALUE_ACCESSORS = [BooleanValueAccessor, TextValueAccessor];
+
+@NgModule({
+ declarations: [AppComponent, ...VALUE_ACCESSORS],
+ imports: [BeeQModule.forRoot(), BrowserModule, FormsModule],
+ ...
+})
+export class AppModule {}
+```
+
### Usage
```html
@@ -176,3 +188,36 @@ export class AppComponent {
}
}
```
+
+### Using BEEQ components in Angular standalone
+
+You can also use BEEQ components in Angular standalone. To do so, you will need to import the components from `@beeq/angular/standalone` and use them as you would use any other Angular component.
+
+```ts
+import { Component } from '@angular/core';
+import { FormsModule } from '@angular/forms';
+import { BqButton, BqCard, BqInput } from '@beeq/angular/standalone';
+
+@Component({
+ selector: 'app-component',
+ standalone: true,
+ imports: [BqButton, BqCard, BqInput],
+ template: `
+
+
+
+
+ Subscribe me!
+
+ `,
+ styles: [],
+ schemas: [],
+})
+export class AppComponent2 {
+ emailValue = 'BEEQ Design System';
+
+ onInputChange(event: CustomEvent<{ value: string }>) {
+ console.log('emailValue', event.detail.value);
+ }
+}
+```
diff --git a/packages/beeq-angular/package.json b/packages/beeq-angular/package.json
index 11ecaea57..07e787ce3 100644
--- a/packages/beeq-angular/package.json
+++ b/packages/beeq-angular/package.json
@@ -7,7 +7,7 @@
"module": "dist/esm2015/index.js",
"types": "index.d.ts",
"dependencies": {
- "@beeq/core": "*",
+ "@beeq/core": "^1.0.1",
"tslib": "^2.6.2"
},
"peerDependencies": {
diff --git a/packages/beeq-angular/project.json b/packages/beeq-angular/project.json
index 4c0149246..583247900 100644
--- a/packages/beeq-angular/project.json
+++ b/packages/beeq-angular/project.json
@@ -11,14 +11,14 @@
"executor": "@nx/angular:package",
"outputs": ["{workspaceRoot}/dist/beeq-angular"],
"options": {
- "project": "packages/beeq-angular/ng-package.json"
+ "project": "{projectRoot}/ng-package.json"
},
"configurations": {
"production": {
- "tsConfig": "packages/beeq-angular/tsconfig.lib.prod.json"
+ "tsConfig": "{projectRoot}/tsconfig.lib.prod.json"
},
"development": {
- "tsConfig": "packages/beeq-angular/tsconfig.lib.json"
+ "tsConfig": "{projectRoot}/tsconfig.lib.json"
}
},
"defaultConfiguration": "production"
diff --git a/packages/beeq-angular/src/beeq.module.ts b/packages/beeq-angular/src/beeq.module.ts
index 3606d6936..2305e0b71 100644
--- a/packages/beeq-angular/src/beeq.module.ts
+++ b/packages/beeq-angular/src/beeq.module.ts
@@ -1,19 +1,41 @@
-import { CommonModule } from '@angular/common';
-import { ModuleWithProviders, NgModule } from '@angular/core';
+import { CommonModule, DOCUMENT } from '@angular/common';
+import { APP_INITIALIZER, ModuleWithProviders, NgModule, NgZone } from '@angular/core';
import { defineCustomElements } from '@beeq/core/dist/loader';
import { DIRECTIVES } from './directives';
+import { BooleanValueAccessor } from './directives/boolean-value-accessor';
+import { NumericValueAccessor } from './directives/number-value-accessor';
+import { RadioValueAccessor } from './directives/radio-value-accessor';
+import { SelectValueAccessor } from './directives/select-value-accessor';
+import { TextValueAccessor } from './directives/text-value-accessor';
+
+const DECLARATIONS = [
+ ...DIRECTIVES,
+ // ngModel Accessors
+ BooleanValueAccessor,
+ NumericValueAccessor,
+ RadioValueAccessor,
+ SelectValueAccessor,
+ TextValueAccessor,
+];
@NgModule({
imports: [CommonModule],
- declarations: [...DIRECTIVES],
- exports: [...DIRECTIVES],
+ declarations: DECLARATIONS,
+ exports: DECLARATIONS,
})
export class BeeQModule {
static forRoot(): ModuleWithProviders {
- defineCustomElements();
return {
ngModule: BeeQModule,
+ providers: [
+ {
+ provide: APP_INITIALIZER,
+ useFactory: () => defineCustomElements,
+ multi: true,
+ deps: [DOCUMENT, NgZone],
+ },
+ ],
};
}
}
diff --git a/packages/beeq-angular/src/index.ts b/packages/beeq-angular/src/index.ts
index de4b639e4..5beb5c85a 100644
--- a/packages/beeq-angular/src/index.ts
+++ b/packages/beeq-angular/src/index.ts
@@ -2,6 +2,9 @@
/* DIRECTIVES */
/* -------------------------------------------------------------------------- */
export { BooleanValueAccessor } from './directives/boolean-value-accessor';
+export { NumericValueAccessor } from './directives/number-value-accessor';
+export { RadioValueAccessor } from './directives/radio-value-accessor';
+export { SelectValueAccessor } from './directives/select-value-accessor';
export { TextValueAccessor } from './directives/text-value-accessor';
export * from './directives/components';
diff --git a/packages/beeq-angular/standalone/ng-package.json b/packages/beeq-angular/standalone/ng-package.json
new file mode 100644
index 000000000..c781f0df4
--- /dev/null
+++ b/packages/beeq-angular/standalone/ng-package.json
@@ -0,0 +1,5 @@
+{
+ "lib": {
+ "entryFile": "src/index.ts"
+ }
+}
diff --git a/packages/beeq-angular/standalone/src/index.ts b/packages/beeq-angular/standalone/src/index.ts
new file mode 100644
index 000000000..a92280940
--- /dev/null
+++ b/packages/beeq-angular/standalone/src/index.ts
@@ -0,0 +1,5 @@
+/* -------------------------------------------------------------------------- */
+/* DIRECTIVES */
+/* -------------------------------------------------------------------------- */
+// @ts-ignore
+export * from './directives/components';
diff --git a/packages/beeq-angular/tsconfig.lib.json b/packages/beeq-angular/tsconfig.lib.json
index 719ef60dc..c5acfc4a1 100644
--- a/packages/beeq-angular/tsconfig.lib.json
+++ b/packages/beeq-angular/tsconfig.lib.json
@@ -8,5 +8,5 @@
"types": []
},
"exclude": ["src/test-setup.ts", "**/*.spec.ts", "jest.config.ts", "**/*.test.ts"],
- "include": ["**/*.ts"]
+ "include": ["src/index.ts", "standalone/src/index.ts"]
}
diff --git a/packages/beeq-angular/tsconfig.lib.prod.json b/packages/beeq-angular/tsconfig.lib.prod.json
index 2dac8b1d1..6affae4f9 100644
--- a/packages/beeq-angular/tsconfig.lib.prod.json
+++ b/packages/beeq-angular/tsconfig.lib.prod.json
@@ -1,7 +1,8 @@
{
"extends": "./tsconfig.lib.json",
"compilerOptions": {
- "declarationMap": false
+ "declarationMap": false,
+ "removeComments": false
},
"angularCompilerOptions": {
"annotateForClosureCompiler": true,
diff --git a/packages/beeq-react/package.json b/packages/beeq-react/package.json
index 6e63f6d41..2d7a4213d 100644
--- a/packages/beeq-react/package.json
+++ b/packages/beeq-react/package.json
@@ -7,7 +7,7 @@
"module": "./src/index.js",
"types": "./src/index.d.ts",
"dependencies": {
- "@beeq/core": "*"
+ "@beeq/core": "^1.0.1"
},
"peerDependencies": {
"react": ">=18.0.0",
diff --git a/packages/beeq-react/tsconfig.json b/packages/beeq-react/tsconfig.json
index 61eb6796d..e2084856c 100644
--- a/packages/beeq-react/tsconfig.json
+++ b/packages/beeq-react/tsconfig.json
@@ -5,7 +5,8 @@
"allowJs": false,
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
- "declaration": true
+ "declaration": true,
+ "removeComments": false
},
"files": [],
"include": [],
diff --git a/packages/beeq-vue/package.json b/packages/beeq-vue/package.json
index 04cddf8aa..46a2e578c 100644
--- a/packages/beeq-vue/package.json
+++ b/packages/beeq-vue/package.json
@@ -7,7 +7,7 @@
"module": "./src/index.js",
"types": "./src/index.d.ts",
"dependencies": {
- "@beeq/core": "*",
+ "@beeq/core": "^1.0.1",
"tslib": "^2.3.0"
},
"peerDependencies": {
diff --git a/packages/beeq-vue/tsconfig.lib.json b/packages/beeq-vue/tsconfig.lib.json
index 19b4921cd..04cb4d8e4 100644
--- a/packages/beeq-vue/tsconfig.lib.json
+++ b/packages/beeq-vue/tsconfig.lib.json
@@ -2,6 +2,7 @@
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
+ "removeComments": false,
"types": ["node"]
},
"include": ["src/**/*.ts"],
diff --git a/packages/beeq/project.json b/packages/beeq/project.json
index f6541f0d4..5816e3fa0 100644
--- a/packages/beeq/project.json
+++ b/packages/beeq/project.json
@@ -76,6 +76,7 @@
"{options.outputPath}",
"{projectRoot}/custom-elements.json",
"{workspaceRoot}/packages/beeq-angular/src/directives",
+ "{workspaceRoot}/packages/beeq-angular/standalone/src/directives",
"{workspaceRoot}/packages/beeq-react/src/react-component-lib",
"{workspaceRoot}/packages/beeq-vue/src/components.ts"
],
diff --git a/packages/beeq/src/components/input/bq-input.tsx b/packages/beeq/src/components/input/bq-input.tsx
index d29018cd6..dd4fd7d1b 100644
--- a/packages/beeq/src/components/input/bq-input.tsx
+++ b/packages/beeq/src/components/input/bq-input.tsx
@@ -246,7 +246,7 @@ export class BqInput {
this.debounceBqInput?.cancel();
if (!isHTMLElement(ev.target, 'input')) return;
- this.value = ev.target.value;
+ this.value = this.type === 'number' ? Number(ev.target.value) : ev.target.value;
this.debounceBqInput = debounce(() => {
this.bqInput.emit({ value: this.value, el: this.el });
@@ -258,7 +258,7 @@ export class BqInput {
if (this.disabled) return;
if (!isHTMLElement(ev.target, 'input')) return;
- this.value = ev.target.value;
+ this.value = this.type === 'number' ? Number(ev.target.value) : ev.target.value;
this.bqChange.emit({ value: this.value, el: this.el });
};
diff --git a/packages/beeq/src/tools/angular-value-accessor-config.ts b/packages/beeq/src/tools/angular-value-accessor-config.ts
index 1b25272b3..1d52b9398 100644
--- a/packages/beeq/src/tools/angular-value-accessor-config.ts
+++ b/packages/beeq/src/tools/angular-value-accessor-config.ts
@@ -1,14 +1,41 @@
import { ValueAccessorConfig } from '@stencil/angular-output-target';
+/**
+ * This lets you define which components should be integrated with ngModel (i.e. form components).
+ * It lets you set what the target prop is (i.e. value), which event will cause the target prop to change.
+ */
export const angularValueAccessorBindings: ValueAccessorConfig[] = [
{
+ // Boolean
elementSelectors: ['bq-checkbox', 'bq-switch'],
event: 'bqChange',
targetAttr: 'checked',
type: 'boolean',
},
{
- elementSelectors: ['bq-input', 'bq-radio-group', 'bq-select', 'bq-slider', 'bq-textarea'],
+ // Number
+ elementSelectors: ['bq-input[type="number"]', 'bq-slider'],
+ event: 'bqChange',
+ targetAttr: 'value',
+ type: 'number',
+ },
+ {
+ // Radio
+ elementSelectors: ['bq-radio-group'],
+ event: 'bqChange',
+ targetAttr: 'value',
+ type: 'radio',
+ },
+ {
+ // Select
+ elementSelectors: ['bq-select'],
+ event: 'bqChange',
+ targetAttr: 'value',
+ type: 'select',
+ },
+ {
+ // Text
+ elementSelectors: ['bq-input:not[type="number"]', 'bq-textarea'],
event: 'bqChange',
targetAttr: 'value',
type: 'text',
diff --git a/packages/beeq/stencil.config.ts b/packages/beeq/stencil.config.ts
index 9d8b6f25f..b4b6900b9 100644
--- a/packages/beeq/stencil.config.ts
+++ b/packages/beeq/stencil.config.ts
@@ -16,10 +16,12 @@ const tailwindOpts: PluginConfigOpts = {
stripComments: true,
};
-const componentCorePackage = '@beeq/core';
+const namespace = 'beeq';
+const componentCorePackage = `@${namespace}/core`;
+const customElementsDir = 'dist/components';
export const config: Config = {
- namespace: 'beeq',
+ namespace,
taskQueue: 'async',
buildDist: true,
enableCache: true,
@@ -50,7 +52,8 @@ export const config: Config = {
{ type: 'dist-hydrate-script', dir: 'dist/hydrate' },
{
type: 'dist-custom-elements',
- customElementsExportBehavior: 'auto-define-custom-elements',
+ customElementsExportBehavior: 'single-export-module',
+ dir: customElementsDir,
minify: true,
},
{
@@ -63,19 +66,35 @@ export const config: Config = {
},
angular({
componentCorePackage,
+ outputType: 'component', // Generate many component wrappers tied to a single Angular module (lazy/hydrated approach)
directivesProxyFile: resolve(__dirname, '../beeq-angular/src/directives/components.ts').replace(/\\/g, '/'),
directivesArrayFile: resolve(__dirname, '../beeq-angular/src/directives/index.ts').replace(/\\/g, '/'),
valueAccessorConfigs: angularValueAccessorBindings,
+ customElementsDir,
+ }),
+ angular({
+ componentCorePackage,
+ outputType: 'standalone', // Generate a component with the standalone flag set to true.
+ directivesProxyFile: resolve(__dirname, '../beeq-angular/standalone/src/directives/components.ts').replace(
+ /\\/g,
+ '/',
+ ),
+ directivesArrayFile: resolve(__dirname, '../beeq-angular/standalone/src/directives/index.ts').replace(/\\/g, '/'),
+ valueAccessorConfigs: angularValueAccessorBindings,
+ customElementsDir,
}),
react({
componentCorePackage,
proxiesFile: resolve(__dirname, '../beeq-react/src/components.ts').replace(/\\/g, '/'),
- includeDefineCustomElements: true,
+ includeImportCustomElements: true,
+ customElementsDir,
}),
vue({
componentCorePackage,
proxiesFile: resolve(__dirname, '../beeq-vue/src/components.ts').replace(/\\/g, '/'),
componentModels: vueComponentModels,
+ includeImportCustomElements: true,
+ customElementsDir,
}),
],
extras: {
diff --git a/packages/beeq/tsconfig.lib.json b/packages/beeq/tsconfig.lib.json
index 4c555c60f..0204e1d38 100644
--- a/packages/beeq/tsconfig.lib.json
+++ b/packages/beeq/tsconfig.lib.json
@@ -3,7 +3,8 @@
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"types": ["node"],
- "composite": true
+ "composite": true,
+ "removeComments": false
},
"exclude": [
"**/*.spec.ts",