@visma-swno/customer-onboarding-wizard
v1.1.2
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"
customerName="Corebis AS"
taskId="task-12345"
locale="en-US"
step="welcome"
adminUrl="https://admin.example.com/customer/user-access"
landingPageUrl="https://example.com/landing"
userName="Joe Doe"
userEmail="[email protected]">
</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) |
| customerName | String | '' | No | Customer/company name appended to the wizard header as Set up your company: {customerName}. Supplied by the host app; when empty the header renders the plain title with no trailing colon. |
| 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-consultants, 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. |
| landingPageUrl | String | '' | No | Absolute http/https URL to redirect to when the user clicks "Close" on the completion step. Relative paths and other schemes are ignored and the wizard closes without redirecting. "Save and close" (and Escape) on the other steps only close the wizard — they never redirect. |
| userName | String | '' | Yes | Display name of the logged-in user. Set via the userName HTML attribute (e.g. [attr.userName]="userName" in Angular). The component does not call any profile API. |
| userEmail | String | '' | No | Email of the logged-in user. Set via the userEmail HTML attribute (e.g. [attr.userEmail]="userEmail" in Angular). When provided, highlights the current user's row in the Administrators step. |
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 after first render (after host property bindings are applied)
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
code?: string; // Structured backend error code, when present
messageParameters?: string[]; // Ordered values for the code's translated template
}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
- When the response carries a structured
{ code, messageParameters }body, composes the message from the translated template for thatcode(ignoring the backend's untranslatedmessage);SCREAMING_SNAKE_CASEparameters likeCONSULTANTare themselves translated, ids/names are inserted verbatim. Unmapped codes fall back to the status-based message. - 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');Passing a non-null token also re-loads the current step's own data with the
new token — the company step's customer/subscriptions, the administrator list, or
the consultant list, whichever the current step owns. For a 401 → refresh cycle
whose failed request was one of those loads, calling updateToken(newToken) is
enough to re-render the view, and the subsequent retry() is redundant.
For any other failed request — a user lookup, or a save/confirm mutation such
as adding administrators or consultants — updateToken() does not re-issue it. In
those cases you must still await retry() (as shown in the http-error handler
above) to complete the original operation; updateToken() only refreshes the
token used by that retry.
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.
