@xplortech/apollo-angular
v2.12.0
Published
Angular bindings for Apollo design system web components
Readme
Apollo Angular
Angular bindings for the Apollo design system (@xplortech/apollo-core web components). Use this package in Angular apps for typed inputs, RxJS-backed outputs, and [(ngModel)] / reactive forms on form controls.
Installation
Published as @xplortech/apollo-angular on the public npm registry (same scope as @xplortech/apollo-core and @xplortech/apollo-react).
npm install @xplortech/apollo-angular @xplortech/apollo-corePeer dependencies: Angular 19+, RxJS 7+, and TypeScript 5+.
Import styles once in your app (path may vary with your bundler):
// e.g. in styles.css / styles.scss
@import '@xplortech/apollo-angular/css/apollo.css';Usage
The package ships standalone Angular component wrappers (Angular 14+, the default since v17). Custom elements register automatically when you import any wrapper — there is no APP_INITIALIZER setup required.
Standalone components
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { TextValueAccessor, XplButton, XplInput } from '@xplortech/apollo-angular';
@Component({
selector: 'app-root',
standalone: true,
// FormsModule + TextValueAccessor enable [(ngModel)] on xpl-input.
imports: [FormsModule, XplButton, XplInput, TextValueAccessor],
template: `
<xpl-input [(ngModel)]="email" label="Email" type="email"></xpl-input>
<xpl-button variant="primary" (click)="save()">Save</xpl-button>
`,
})
export class AppComponent {
email = '';
save() {}
}NgModule consumers
If your app still uses NgModule, import DIRECTIVES (the full array of wrappers) or individual wrappers into the imports array:
import { NgModule } from '@angular/core';
import { DIRECTIVES } from '@xplortech/apollo-angular';
@NgModule({
declarations: [AppComponent],
imports: [...DIRECTIVES],
})
export class AppModule {}Forms ([(ngModel)] and reactive forms)
These wrappers integrate as Angular ControlValueAccessor implementations:
| Component | Form value | Update event (internal) | Value accessor |
|---------------|---------------|-------------------------|-----------------------|
| XplInput | value | valueChange | TextValueAccessor |
| XplCheckbox | checked | checkboxChange | BooleanValueAccessor|
| XplRadio | selectedValue | radioChange | RadioValueAccessor |
| XplToggle | checked | toggleChange | BooleanValueAccessor|
| XplSelect | selectedValues | changeEvent | SelectValueAccessor |
Standalone imports: each form control's value accessor is a separate standalone directive. To use
[(ngModel)]orformControlNameyou must import the matching value accessor alongside the component (see below), or import the fullDIRECTIVESarray (which includes every wrapper and every value accessor).NgModuleconsumers that import...DIRECTIVESget form binding automatically.
Template-driven forms
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import {
BooleanValueAccessor,
TextValueAccessor,
XplCheckbox,
XplInput,
XplToggle,
} from '@xplortech/apollo-angular';
@Component({
selector: 'app-profile',
standalone: true,
imports: [
FormsModule,
XplCheckbox,
XplInput,
XplToggle,
// Value accessors register NG_VALUE_ACCESSOR on the hosts above.
TextValueAccessor,
BooleanValueAccessor,
],
template: `
<xpl-input [(ngModel)]="name" label="Name"></xpl-input>
<xpl-checkbox [(ngModel)]="agreed" label="I agree"></xpl-checkbox>
<xpl-toggle [(ngModel)]="enabled">Enabled</xpl-toggle>
`,
})
export class ProfileComponent {
name = '';
agreed = false;
enabled = false;
}Reactive forms
import { Component } from '@angular/core';
import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
import {
BooleanValueAccessor,
TextValueAccessor,
XplInput,
XplToggle,
} from '@xplortech/apollo-angular';
@Component({
selector: 'app-settings',
standalone: true,
imports: [
ReactiveFormsModule,
XplInput,
XplToggle,
TextValueAccessor,
BooleanValueAccessor,
],
template: `
<form [formGroup]="form">
<xpl-input formControlName="name" label="Name"></xpl-input>
<xpl-toggle formControlName="enabled">Enabled</xpl-toggle>
</form>
`,
})
export class SettingsComponent {
form = this.fb.group({ name: '', enabled: false });
constructor(private fb: FormBuilder) {}
}Tip: to avoid importing individual value accessors, import the whole
DIRECTIVESarray in a standalone component'simports— it registers every wrapper and value accessor at once.
Specialized input types: <xpl-input type="date">, type="time", type="phone", type="color", and type="file" all work with [(ngModel)]. Internally, xpl-input renders a sub-component (e.g. xpl-input-date) and forwards its events. Prefer <xpl-input type="date" [(ngModel)]="val"> over using the sub-components directly.
Events and complex props
Stencil @Event() names are exposed as Angular @Output() EventEmitters and emit CustomEvent instances. Use .detail to read the payload:
<xpl-table
[data]="rows"
[columns]="cols"
(tableSelect)="onSelect($event.detail)"
></xpl-table>Pass objects and arrays directly as [propName] bindings — Angular forwards them as DOM properties:
<xpl-table [data]="rows" [columns]="cols"></xpl-table>Further reading
- Apollo repo
- Core components and behavior:
@xplortech/apollo-core/ Storybook in this monorepo - Stencil Angular output target docs
