Customization#

Start with the zero-effort default and adopt customization only as far as you need.

EffortControlWhat you useBest for
DefaultNoneLowHaapiStepper + HaapiStepperStepUIgetting HAAPI flows running out of the box
Styles customizationVery lowLook onlyCSS classes (.haapi-stepper-*)restyling the default UI
Render interceptorsLowMediumHaapiStepperStepUI + interceptor propstweaking the default UI
UI compositionHighFullHaapiStepper + useHaapiStepper hook + UI componentscustom layout, grouping, complex/behaviour
MixedMixedFulla combination of the abovethe default UI with localized custom parts

Default — works from scratch#

Renders the complete HAAPI flow UI.

Styles customization#

The UI components emit plain .haapi-stepper-* CSS class names — restyle the default UI just by overriding those classes in your own stylesheet, no code changes needed.

CSS customization#

The HAAPI UI components are styled via plain CSS class names — no CSS-in-JS, no inline styles. The components only emit class names; the actual rules live in a stylesheet shipped alongside the host application’s global stylesheet. For example, in the case of the haapi-react-app, in haapi-react-app/src/shared/util/css/styles.css.

Importing CSS styles#

Import the stylesheet once from the consuming application’s entry point (e.g. main.tsx):

import './shared/util/css/styles.css';

By default, the rules in styles.css compose utility classes from Curity CSS Library (imported at the top of the file) using PostCSS @extend — e.g. .haapi-stepper-button { @extend .button, .button-medium, .button-primary, .w100, .mt2; }. The components themselves only know about the .haapi-stepper-* class names, so consumers are free to back those classes with anything they like.

Overriding or extending the defaults#

Because the components emit static class names, consumers can:

  • Override / Extend: define rules for the same class names — or append additional CSS — in a separate stylesheet imported after styles.css.
  • Replace: skip the default import entirely and provide your own definitions for the classes listed below — written in plain CSS, or composed from any third-party library, for example Tailwind CSS.

The Curity utility composition shown above is just how this project chose to implement the defaults; it is not a contract. Nothing in the components requires @curity/ui-kit-css, PostCSS, or @extend.

Available CSS classes
ClassUsed byPurpose
.haapi-stepper-selectorHaapiStepperSelectorUISelector action container
.haapi-stepper-authenticator-buttonHaapiStepperFormSubmitButtonAuthenticator-selector option button (applied automatically when the action carries authenticatorType); combine with .button-<authenticatorType> (e.g. .button-google) to get the per-authenticator icon color
.haapi-stepper-messagesHaapiStepperMessagesUIMessages container
.haapi-stepper-form-field-text-inputHaapiStepperTextFormFieldUIText input fields
.haapi-stepper-form-field-text-labelHaapiStepperTextFormFieldUIForm field labels
.haapi-stepper-form-field-checkbox-inputHaapiStepperCheckboxFormFieldUICheckbox inputs
.haapi-stepper-form-field-checkbox-labelHaapiStepperCheckboxFormFieldUICheckbox-specific labels
.haapi-stepper-form-field-select-inputHaapiStepperSelectFormFieldUISelect inputs
.haapi-stepper-form-field-select-labelHaapiStepperSelectFormFieldUISelect-specific labels
.haapi-stepper-form-field-password-wrapperHaapiStepperPasswordFormFieldUIPassword input container
.haapi-stepper-form-field-password-labelHaapiStepperPasswordFormFieldUIPassword label
.haapi-stepper-form-field-password-inputHaapiStepperPasswordFormFieldUIPassword input
.haapi-stepper-form-field-password-visibility-toggleHaapiStepperPasswordFormFieldUIPassword visibility toggle button
.haapi-stepper-buttonHaapiStepperFormUIPrimary submit buttons
.haapi-stepper-button-outlineHaapiStepperFormUIOutline/cancel buttons
.haapi-stepper-wellWellStyled content container
.haapi-stepper-linksHaapiStepperLinksUILinks container
.haapi-stepper-linkHaapiStepperLinkUILink element
.haapi-stepper-link-qr-codeHaapiStepperLinkUIQR code link figure wrapper
.haapi-stepper-link-qr-code-titleHaapiStepperLinkUIQR code link figcaption
.haapi-stepper-link-qr-code-buttonHaapiStepperLinkUIQR code link expand button
.haapi-stepper-link-qr-code-dialogHaapiStepperQrCodeLinkDialogFullscreen QR code dialog
.haapi-stepper-link-qr-code-dialog-close-buttonHaapiStepperQrCodeLinkDialogButton wrapping the expanded QR code image; closes the dialog when clicked
.haapi-stepper-link-qr-code-dialog-imageHaapiStepperQrCodeLinkDialogFullscreen QR code dialog image
.haapi-stepper-actionsHaapiStepperActionsUIActions container
.haapi-stepper-headingHaapiStepperMessagesUIHeading messages
.haapi-stepper-userNameHaapiStepperMessagesUIUser name display
.haapi-stepper-userCodeHaapiStepperMessagesUIUser code display (e.g. recovery codes)
.haapi-stepper-polling-progressHaapiStepperClientOperationUIRemaining polling time indicator (e.g. recovery codes)
.haapi-stepper-webauthn-registration-attachment-iconHaapiStepperWebAuthnRegistrationAttachmentCardAttachment card icon
.haapi-stepper-webauthn-registration-attachment-titleHaapiStepperWebAuthnRegistrationAttachmentCardAttachment card option label
.haapi-stepper-webauthn-registration-attachment-descriptionHaapiStepperWebAuthnRegistrationAttachmentCardAttachment card option description
.haapi-stepper-step-symbolStepSymbolStep symbol container (the illustrative icon above the step content)
.haapi-stepper-step-symbol-imageStepSymbolStep symbol image
.haapi-stepper-consent-logosUserConsentViewNameBuiltInUIContainer for user consent logos
.haapi-stepper-error-boundary-fallbackDefaultErrorFallbackError boundary fallback container
.haapi-validation-errors-containerHaapiStepperFormValidationErrorInputWrapperWrapper around a form field that has validation errors. Receives the .has-errors modifier class while errors are visible
.haapi-validation-errorsHaapiStepperFormValidationErrorInputWrapperInner container that holds the list of validation error messages
.haapi-validation-errorHaapiStepperFormValidationErrorInputWrapperA single validation error entry (also gets the utility classes .red .py1)
.haapi-validation-error-descriptionHaapiStepperFormValidationErrorInputWrapperValidation error message text

Customize with render interceptors#

Render interceptors are the programmatic way to customize the default step UI elements — loader, error, step, actions (form, client operation, selector), links, messages, and form fields.

Each is a function that receives the HaapiStepper API data for the target UI element (currentStep, loading, error, nextStep…) and returns either a React element to replace the default UI element, the API data to render the default UI element, or null to skip the element from being rendered:

💡 Design pattern note: always return or pass through the API data.

  • To override: return your custom element.
  • To delegate to the default renderer: return the API data ({ currentStep, history, loading, error, nextStep }), optionally modified.
  • To remove an element: return null.

Customize with UI composition#

The declarative path to build UIs from scratch. Use it for what the API doesn’t expose as elements — grouping (fieldsets/tabs), cross-element layouts, inserting your own elements, and behaviour customizations (tabs, multi-step wizards). Best for layout and complex customizations.

Each HAAPI entity has a corresponding UI component (HaapiStepperActionsUI, HaapiStepperMessagesUI, HaapiStepperLinksUI…). HaapiStepper still runs the flow:

Mixed — combine the default with your own UI#

Render interceptors and UI composition aren’t exclusive — mix them wherever it helps. For example, return UI building blocks from a render interceptor to restructure part of the default UI while keeping everything else: a form render interceptor that re-lays-out the same fields, a step interceptor that swaps one step’s UI, or the headless HaapiStepper driving a mix of building blocks, plain HTML and third-party components.

Was this helpful?