Skip to main content

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.

Loading playground…

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.

Loading playground…

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-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:

Loading playground…

💡 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:

Loading playground…

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.

Loading playground…