@teamvortexsoftware/vortex-angular-19
v0.0.16
Published
Vortex Components
Readme
Vortex Angular Component
High-performance Angular component for Vortex invitations with seamless integration for Angular 19
🚀 Quick Start
npm install @teamvortexsoftware/vortex-angular-19Basic Usage
import { Component } from '@angular/core';
import { VortexInvite } from '@teamvortexsoftware/vortex-angular-19';
@Component({
selector: 'app-my-component',
standalone: true,
imports: [VortexInvite],
template: `
<vortex-invite
[componentId]="componentId"
[jwt]="jwt"
[isLoading]="isLoading"
[scope]="workspace.id"
[scopeType]="'workspace'"
(invite)="handleInvite($event)"
/>
`,
})
export class MyComponent {
componentId = 'my-widget';
jwt = 'eyJhbGciOiJIUzI1NiIs...';
isLoading = false;
workspace = { id: 'ws-123', name: 'Engineering' };
handleInvite(data: any) {
console.log('Invitation sent:', data);
}
}📋 Component API Reference
Inputs
| Prop | Type | Required | Description | Docs |
| ------------------------- | ------------------------ | -------- | ------------------------------- | ------------------------------------------------------------------------------------------- |
| componentId | string | ✅ | Component identifier | docs |
| jwt | string | ✅ | JWT token for authentication | docs |
| scope | string | ✅ | Scope identifier (e.g., team ID)| docs |
| scopeType | string | ✅ | Scope type (e.g., "team") | docs |
| isLoading | boolean | ❌ | Loading state indicator | docs |
| onEvent | function | ❌ | Event handler for widget events | docs |
| onSubmit | function | ❌ | Form submission handler | |
| onInvite | function | ❌ | Invitation completion handler | docs |
| onError | function | ❌ | Error handler | |
| emailValidationFunction | function | ❌ | Custom email validation | docs |
| analyticsSegmentation | Record<string, any> | ❌ | Analytics tracking data | |
| userEmailsInGroup | string[] | ❌ | Pre-populated email list | docs |
| templateVariables | Record<string, string> | ❌ | Template variables | docs |
| googleAppClientId | string | ❌ | Google integration client ID | docs |
| googleAppApiKey | string | ❌ | Google integration API key | docs |
| |
Outputs
| Output | Type | Description |
| -------- | ---------------------------------------------- | ------------------------------- |
| ready | EventEmitter<CustomEvent> | Emitted when component is ready |
| submit | EventEmitter<{ formData: any; result: any }> | Emitted on form submission |
| invite | EventEmitter<any> | Emitted when invitation is sent |
| error | EventEmitter<any> | Emitted on error |
| event | EventEmitter<any> | Emitted for widget events |
📖 Advanced Examples
With Custom Event Handlers
import { Component } from '@angular/core';
import { VortexInvite } from '@teamvortexsoftware/vortex-angular-19';
@Component({
selector: 'app-advanced-invite',
standalone: true,
imports: [VortexInvite],
template: `
<vortex-invite
[componentId]="'advanced-widget'"
[jwt]="jwt"
[isLoading]="isLoading"
[scope]="'team-123'"
[scopeType]="'team'"
(invite)="onInvite($event)"
(error)="onError($event)"
(event)="onEvent($event)"
/>
`,
})
export class AdvancedInviteComponent {
jwt = '...';
isLoading = false;
onInvite(data: any) {
console.log('Invitation sent:', data);
this.trackAnalyticsEvent('invitation_sent', data);
}
onError(error: any) {
console.error('Invitation error:', error);
this.showErrorToast(error.message);
}
onEvent(event: any) {
console.log('Widget event:', event);
}
trackAnalyticsEvent(eventName: string, data: any) {
// Your analytics implementation
}
showErrorToast(message: string) {
// Your error implementation
}
}With Custom Email Validation
import { Component } from '@angular/core';
import { VortexInvite } from '@teamvortexsoftware/vortex-angular-19';
import { EmailGroupMembershipCheckFunction } from '@teamvortexsoftware/vortex-types';
@Component({
selector: 'app-validated-invite',
standalone: true,
imports: [VortexInvite],
template: `
<vortex-invite
[componentId]="'validated-widget'"
[jwt]="jwt"
[scope]="'team-123'"
[scopeType]="'team'"
[emailValidationFunction]="emailValidator"
(invite)="handleInvite($event)"
/>
`,
})
export class ValidatedInviteComponent {
jwt = '...';
emailValidator: EmailGroupMembershipCheckFunction = async (emails: string[]) => {
const isValid = await this.validateEmailsInSystem(emails);
return {
isValid,
errorMessage: isValid ? undefined : 'Emails not found in system',
};
};
async validateEmailsInSystem(emails: string[]): Promise<boolean> {
// Your validation logic
return true;
}
handleInvite(data: any) {
console.log('Invitation sent:', data);
}
}With Template Variables
import { Component } from '@angular/core';
import { VortexInvite } from '@teamvortexsoftware/vortex-angular-19';
@Component({
selector: 'app-templated-invite',
standalone: true,
imports: [VortexInvite],
template: `
<vortex-invite
[componentId]="'templated-widget'"
[jwt]="jwt"
[scope]="'team-123'"
[scopeType]="'team'"
[templateVariables]="templateVars"
(invite)="handleInvite($event)"
/>
`,
})
export class TemplatedInviteComponent {
jwt = '...';
templateVars = {
companyName: 'Acme Corp',
userName: 'John Doe',
customMessage: 'Join our team!',
};
handleInvite(data: any) {
console.log('Invitation sent:', data);
}
}With Analytics Segmentation
import { Component } from '@angular/core';
import { VortexInvite } from '@teamvortexsoftware/vortex-angular-19';
@Component({
selector: 'app-analytics-invite',
standalone: true,
imports: [VortexInvite],
template: `
<vortex-invite
[componentId]="'analytics-widget'"
[jwt]="jwt"
[scope]="'team-123'"
[scopeType]="'team'"
[analyticsSegmentation]="analyticsData"
(invite)="handleInvite($event)"
/>
`,
})
export class AnalyticsInviteComponent {
jwt = '...';
analyticsData = {
source: 'dashboard',
campaign: 'summer-2024',
userType: 'premium',
};
handleInvite(data: any) {
console.log('Invitation sent with analytics:', data);
}
}With Google Contacts Integration
import { Component } from '@angular/core';
import { VortexInvite } from '@teamvortexsoftware/vortex-angular-19';
@Component({
selector: 'app-google-invite',
standalone: true,
imports: [VortexInvite],
template: `
<vortex-invite
[componentId]="'google-widget'"
[jwt]="jwt"
[scope]="'team-123'"
[scopeType]="'team'"
[googleAppClientId]="googleClientId"
[googleAppApiKey]="googleApiKey"
(invite)="handleInvite($event)"
/>
`,
})
export class GoogleInviteComponent {
jwt = '...';
googleClientId = 'your-google-client-id';
googleApiKey = 'your-google-api-key';
handleInvite(data: any) {
console.log('Invitation sent from Google Contacts:', data);
}
}🛠️ TypeScript Support
Full TypeScript support with exported types:
import { VortexInvite } from '@teamvortexsoftware/vortex-angular-19';
import type { EmailGroupMembershipCheckFunction } from '@teamvortexsoftware/vortex-types';
@Component({
selector: 'app-typed-invite',
standalone: true,
imports: [VortexInvite],
template: `
<vortex-invite
[componentId]="componentId"
[jwt]="jwt"
[scope]="'team-123'"
[scopeType]="'team'"
[emailValidationFunction]="validator"
/>
`,
})
export class TypedInviteComponent {
componentId: string = 'my-widget';
jwt: string = '...';
validator: EmailGroupMembershipCheckFunction = async (emails) => {
return { isValid: true };
};
}🚨 Error Handling
The component gracefully handles all scenarios:
- ✅ Component Ready: Waits for web component to be defined before syncing props
- ✅ Missing Props: Safe defaults applied for optional properties
- ✅ Validation Errors: Emitted through the
erroroutput - ✅ Network Errors: Handled internally with error emission
Error Handling Example
@Component({
selector: 'app-error-handling',
standalone: true,
imports: [VortexInvite],
template: `
<vortex-invite
[componentId]="componentId"
[jwt]="jwt"
[scope]="'team-123'"
[scopeType]="'team'"
(error)="handleError($event)"
(invite)="handleSuccess($event)"
/>
@if (errorMessage) {
<div class="error-toast">{{ errorMessage }}</div>
}
`,
})
export class ErrorHandlingComponent {
componentId = 'my-widget';
jwt = '...';
errorMessage = '';
handleError(error: any) {
this.errorMessage = error?.message || 'An error occurred';
console.error('Widget error:', error);
// Clear error after 5 seconds
setTimeout(() => {
this.errorMessage = '';
}, 5000);
}
handleSuccess(data: any) {
this.errorMessage = '';
console.log('Success:', data);
}
}🔧 Best Practices
1. Standalone Components (Recommended)
import { Component } from '@angular/core';
import { VortexInvite } from '@teamvortexsoftware/vortex-angular-19';
@Component({
selector: 'app-invite',
standalone: true,
imports: [VortexInvite],
template: `
<vortex-invite
[componentId]="componentId"
[jwt]="jwt"
[scope]="'team-123'"
[scopeType]="'team'"
(invite)="handleInvite($event)"
/>
`,
})
export class InviteComponent {
componentId = 'my-widget';
jwt = '...';
handleInvite(data: any) {
console.log('Invitation sent:', data);
}
}2. Module-Based (Legacy)
import { NgModule } from '@angular/core';
import { VortexInvite } from '@teamvortexsoftware/vortex-angular-19';
@NgModule({
imports: [VortexInvite],
declarations: [MyComponent],
})
export class MyModule {}3. Reactive State Management
import { Component, signal } from '@angular/core';
import { VortexInvite } from '@teamvortexsoftware/vortex-angular-19';
@Component({
selector: 'app-reactive-invite',
standalone: true,
imports: [VortexInvite],
template: `
<vortex-invite
[componentId]="componentId()"
[jwt]="jwt()"
[isLoading]="isLoading()"
[scope]="scope()"
[scopeType]="scopeType()"
(invite)="handleInvite($event)"
/>
`,
})
export class ReactiveInviteComponent {
componentId = signal('my-widget');
jwt = signal('...');
isLoading = signal(false);
scope = signal('team-123');
scopeType = signal('team');
handleInvite(data: any) {
console.log('Invitation sent:', data);
this.isLoading.set(false);
}
}🔍 Change Detection
The component uses ChangeDetectionStrategy.OnPush for optimal performance and automatically syncs props when inputs change.
🎯 Key Features
- 🎯 Standalone Component - Works with Angular 19 standalone components
- 🔄 Automatic Prop Syncing - Inputs are automatically synced to the web component
- ⚡ OnPush Change Detection - Optimized performance
- 🛡️ Type Safety - Full TypeScript support with exported types
- 🚀 Lazy Loading - Web component is loaded on-demand
- 📦 Zero Configuration - Works out of the box
- 🔒 Safe Imports - CUSTOM_ELEMENTS_SCHEMA for web component support
📦 What's Included
- Angular 19 compatible component wrapper
- Web component bundled inline (no separate script loading needed)
- Full TypeScript definitions
- Support for all widget features:
- Email invitations
- Group management
- Custom validation
- Analytics tracking
- Template variables
- Google Contacts integration
Need help? Contact support or check the documentation at docs.vortex.software.
