Theming (UI Layer)#
Every prebuilt screen ships with sensible defaults — Roboto on iOS, the Curity color palette, sane spacing — but most apps want their brand. Theming lets you override colors, images, fonts, and component-level styles without touching framework code. Each platform uses its native theming mechanism: a plist on iOS, XML styles on Android. When you can’t reach what you need by overriding styles, drop down to UI Extensibility and swap the view controller / fragment outright.
Overview#
Four theming surfaces, with native mechanisms on each platform. Pick the surface that matches what you want to change.
| Surface | What it controls | iOS mechanism | Android mechanism |
|---|---|---|---|
| Colors | Background, primary, accent, per-component color attributes | Asset-Catalog color sets named after the framework key | colorPrimary / colorAccent and hui*Color styleables in themes.xml |
| Images / Icons | Authenticator icons, illustrations, drawables embedded in components | Asset-Catalog image sets named after the framework key | Drawables in res/drawable/ referenced via hui* styleables |
| Fonts | Body, heading, button, callout typography | fontName key in a custom plist; system or bundled .ttf | android:fontFamily on the app theme, per-component TextAppearance |
| Component-Level Styling | Per-component sizing, corner radii, padding, borders | Component-keyed dictionaries in the plist | Custom style definitions extending the framework’s component styleables |
Configuration#
Pick your platform; each section lists the surface, the code, and the per-key conventions.
Colors#
IdsvrHaapiUIKit reads colors from the application’s Asset Catalog by name. Declare a color with the same name as a framework key (for example, hui_background) and IdsvrHaapiUIKit picks yours up automatically — no builder call required.
- In your app’s
Assets.xcassets, add a Color Set. - Name it the same as the framework key you want to override (
hui_background,hui_primary, etc.). - Configure the color values (Any Appearance / Dark Appearance).
Images and Icons#
Same pattern as colors. Add an Image Set in your Asset Catalog named identically to the framework key (for example, hui_ic_authenticator_user). The framework picks up the app-side asset at runtime.
Fonts#
The default font is Roboto. Override it by supplying a plist and naming it on HaapiUIKitApplicationBuilder:
<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>fontName</key>
<string>Baskerville</string>
</dict>
</plist>HaapiUIKitApplicationBuilder(haapiUIKitConfiguration: haapiUIKitConfiguration)
.setThemingPlistFileName("MyCustom") // refers to MyCustom.plist
.build()For a system font, set fontName to any iOS-supported font name. For a custom font, ship the .ttf files in your target and set fontName to the title-case family name (for example, "IBM Plex Mono" for files prefixed IBMPlexMono). Launch logs confirm whether the custom font registered.
Component-Level Styling#
Each themable component (e.g., ActionableButton.Primary, InputTextField.Curity, MessageView.Error) reads a typed style definition from the same plist used for fontName. Add a top-level dictionary keyed by the component name and supply the supported keys:
<plist version="1.0">
<dict>
<key>fontName</key>
<string>IBM Plex Mono</string>
<key>ActionableButton.Primary</key>
<dict>
<key>backgroundColorName</key>
<string>my_primary_button_background</string>
<key>cornerRadius</key>
<integer>12</integer>
</dict>
</dict>
</plist>Each component’s supported keys are documented in its theming reference page in the IdsvrHaapiUIKit autodoc. Misspelled keys or wrong value types cause a runtime crash with a descriptive log message — keep the console open the first time you test a new override.
Colors#
Override colors by extending Theme.Haapi.Ui.Widget.BaseTheme in your app’s themes.xml and setting Material color attributes:
<style name="AppTheme" parent="@style/Theme.Haapi.Ui.Widget.BaseTheme">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>Component-level color attributes (e.g., huiInputTextViewStrokeColor) live on the per-component styleables; override them with a custom style and point the theme attribute at it.
Images and Icons#
Override drawables by name in your app’s res/drawable/ directory. For images that are part of a component styleable, override the component’s style attribute (for example, huiSpinnerTextViewSelectorBackground) and point at your custom drawable.
Fonts#
Set fonts via standard Android text-appearance overrides on the app theme:
<style name="AppTheme" parent="@style/Theme.Haapi.Ui.Widget.BaseTheme">
<item name="android:fontFamily">@font/my_custom_font</item>
</style>For component-specific overrides, define a custom TextAppearance style and point the relevant huiTextAppearance… attribute at it.
Component-Level Styling#
Define a custom style extending the component’s base, and point the theme attribute at it:
<style name="AppTheme" parent="@style/Theme.Haapi.Ui.Widget.BaseTheme">
<item name="huiInputTextViewStyle">@style/InputTextView.Custom</item>
<item name="huiSpinnerTextViewStyle">@style/SpinnerTextView.Custom</item>
</style>
<style name="InputTextView.Custom" parent="Haapi.Android.Ui.Widget.InputTextView.Curity">
<item name="huiInputTextViewBoxBackgroundColor">@android:color/holo_green_light</item>
<item name="huiInputTextViewStrokeColor">@android:color/holo_orange_dark</item>
</style>
<style name="SpinnerTextView.Custom" parent="">
<item name="huiSpinnerTextViewSelectorBackground">@drawable/custom_button_shape</item>
<item name="huiSpinnerTextViewItemLayout">@layout/custom_spinner_item</item>
</style>Alternatively, apply a theme specifically to HaapiFlowActivity in AndroidManifest.xml if you want themed authentication separate from your app’s normal theme:
<activity android:name="se.curity.identityserver.haapi.android.ui.widget.HaapiFlowActivity"
android:theme="@style/Custom.Activity.Theme" /> Localizable Strings#
The framework ships English strings keyed by short identifiers (hui_back, hui_webauth_passkeys_not_supported, etc.). Override any string by declaring the same key in your app’s localization resources.
- iOS — add the key/value pair to your
Localizable.stringsfor each locale you support. - Android — add the key/value pair to your
res/values/strings.xml(and locale-suffixed variants for each locale).
Theming errors are validated at runtime, not at compile time, and the failure modes differ by platform:
- iOS — plist parsing happens at app launch. A malformed plist or a key/value type mismatch crashes the app before the configuration is consumed. After every plist change, run on a clean device once and check the launch logs for theming-related warnings before shipping.
- Android — style and styleable references are resolved when the framework inflates each screen. A missing drawable, a wrong parent class, or a misspelled
hui*attribute crashes the activity the first time the user reaches the affected screen (login screen, BankID screen, polling screen). Test every flow path that uses the customized components, not just the first one you can reach.
How to implement this: UI Extensibility · Configuration · iOS UIKit · Android UIWidget