@visma-swno/customer-onboarding-wizard
v1.0.10
Published
A modern Web Component built with Lit for managing customer onboarding workflows.
Keywords
Readme
Customer Onboarding Wizard
A modern Web Component built with Lit for managing customer onboarding workflows.
Features
- 🚀 Built with Lit and TypeScript
- 📦 Bundled with Vite
- ✅ Fully tested with Vitest
- 🎨 Customizable with CSS variables
- 🔧 Type-safe with TypeScript strict mode
- 📱 Responsive and accessible
Installation
npm install @visma-swno/customer-onboarding-wizardUsage
Basic Usage
<vsn-customer-onboarding-wizard
baseUrl="https://api.example.com"
customerId="customer-67890"
taskId="task-12345"
locale="en-US"
step="welcome"
adminUrl="https://admin.example.com/customer/user-access">
</vsn-customer-onboarding-wizard>With Module Import
import '@visma-swno/customer-onboarding-wizard';
// Or import specific components
import { CustomerOnboardingWizard } from '@visma-swno/customer-onboarding-wizard';Properties
| Property | Type | Default | Required | Description |
|----------|------|---------|----------|-------------|
| baseUrl | String | '' | Yes | Base URL for API calls (e.g., 'https://api.example.com') |
| taskId | String | '' | No | Onboarding task ID. Required for saving progress (save and close) and completing the wizard; omitting it skips those API calls |
| customerId | String | '' | Yes | Customer ID used to load company information in Step 1 (Company) |
| locale | String | 'en-US' | No | Locale for translations. Accepted values: en-US, en-GB (mapped to en-US), da-DK, fi-FI, nb-NO, nl-NL, sv-SE |
| step | String | 'welcome' | No | Initial step to navigate to: welcome, company, administrators, partner-access, complete |
| adminUrl | String | '' | No | Absolute http/https URL to redirect to after task cleanup when the user clicks "Go to Admin" on the completion step. Relative paths and other schemes are ignored and the wizard closes without redirecting. |
CSS Custom Properties
Customize the appearance using CSS variables:
vsn-customer-onboarding-wizard {
/* Parent application should load font files and set this variable */
--font-family: Inter, ui-sans-serif, system-ui, sans-serif;
}Available CSS Variables
| Variable | Default | Description |
|----------|---------|-------------|
| --font-family | System fonts fallback | Required: Parent application should provide font files and set this variable to avoid duplicate font loading |
Font Configuration
Important: This component does NOT bundle font files. The parent application must:
- Load font files (e.g., Inter font via
@font-faceor CDN) - Set the
--font-familyCSS variable
<style>
/* Load fonts in parent application */
@font-face {
font-family: 'Inter';
src: url('/fonts/Inter-Regular.woff2') format('woff2');
font-weight: 400;
}
@font-face {
font-family: 'Inter';
src: url('/fonts/Inter-Medium.woff2') format('woff2');
font-weight: 500;
}
@font-face {
font-family: 'Inter';
src: url('/fonts/Inter-SemiBold.woff2') format('woff2');
font-weight: 600;
}
/* Set font variable for component */
vsn-customer-onboarding-wizard {
--font-family: Inter, ui-sans-serif, system-ui, sans-serif;
}
</style>
<vsn-customer-onboarding-wizard baseUrl="https://api.example.com"></vsn-customer-onboarding-wizard>Font Requirements:
- Font weights needed: 400 (Regular), 500 (Medium), 600 (SemiBold)
- Recommended font: Inter (see
fonts/README.mdfor download links)
Events
The component emits custom events for host application integration:
request-token
Emitted: Once during component initialization
Purpose: Request OAuth2 access token from host application
Detail:
{
callback: (token: string | null) => void
}Usage:
document.addEventListener('request-token', async (event) => {
const token = sessionStorage.getItem('accessToken');
event.detail.callback(token);
});http-error
Emitted: Only for authentication/authorization errors (401, 403)
Purpose: Allow host application to handle auth errors (e.g., refresh token on 401, redirect on 403)
Note: All other errors (400, 422, 500, network errors) are automatically displayed by the component via an internal error banner. No handling required by host application.
Detail:
{
status: number; // 401 or 403 only
statusText: string; // HTTP status text
message: string; // Error message
endpoint: string; // Failed endpoint
method: string; // HTTP method
retry: () => Promise<any>; // Retry callback
}Usage:
document.addEventListener('http-error', async (event) => {
const { status, retry } = event.detail;
if (status === 401) {
// Refresh token
const newToken = await fetchNewToken();
// Update component token
document.querySelector('vsn-customer-onboarding-wizard').updateToken(newToken);
// Retry failed request
await retry();
}
if (status === 403) {
// Handle permission denied
window.location.href = '/access-denied';
}
});error-message (Internal)
Emitted: For validation errors, server errors, and network errors
Purpose: Component listens to this event internally and displays a translated error banner
Detail:
{
status: number; // HTTP status code or 0 for network errors
errorKey: string; // Translation key (e.g., 'serverError', 'validationError')
endpoint: string; // Failed endpoint
method: string; // HTTP method
}Handled Automatically: Host application does not need to listen to this event. The component:
- Displays a red error banner at the top of the wizard
- Automatically translates error title and message to the user's selected language
- Supports 6 translation sets: da-DK, en-US, fi-FI, nb-NO, nl-NL, sv-SE (
en-GBis accepted and served usingen-UStranslations) - Banner remains visible until the user manually dismisses it by clicking the X button
- Allows users to report errors to support
Public Methods
updateToken(token: string | null)
Update the authentication token. Call this method after refreshing the token.
const wizard = document.querySelector('vsn-customer-onboarding-wizard');
wizard.updateToken('new-access-token');Development
See DEVELOPER-GUIDE.md for development instructions.
Testing
See TESTING-SETUP.md for testing documentation.
Browser Support
- Chrome/Edge (latest)
- Firefox (latest)
- Safari (latest)
License
ISC
Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
