Theming

Apply your app theme to the Nabla SDK

Many aspects of the UI components can be changed and customized. For example, it's possible to change:

  • Colors
  • Text appearances
  • Backgrounds of views
  • Icons

Customize global colors, icons, backgrounds, and fonts

Our UI components uses a multi-level theme system. The first level is the global NablaTheme that is used by all UI components. Overriding NablaTheme.Colors or NablaTheme.Fonts will apply the changes to every component of our SDK. But you can also change the values for each component individually.

You can modify the NablaTheme from anywhere, but typically you want to do it before displaying any UI on your app.

Here's an example of how to customize NablaTheme attributes that Nabla UI components will use:

NablaTheme.Colors.Background.base = UIColor(red: 0.95, green: 0.96, blue: 0.98, alpha: 1.00)
NablaTheme.Colors.Text.base = UIColor(red: 0.15, green: 0.16, blue: 0.18, alpha: 1.00)
NablaTheme.Colors.Text.accent = UIColor(red: 0.44, green: 0.47, blue: 0.49, alpha: 1.00)
NablaTheme.Colors.Fill.base = UIColor(red: 0.91, green: 0.94, blue: 1.00, alpha: 1.00)
NablaTheme.Colors.Stroke.accent = UIColor(red: 0.00, green: 0.60, blue: 1.00, alpha: 1.00)
NablaTheme.Colors.Stroke.danger = UIColor(red: 0.67, green: 0.71, blue: 0.82, alpha: 1.00)
NablaTheme.Colors.ButtonBackground.base = UIColor(red: 1.00, green: 1.00, blue: 1.00, alpha: 1.00)
NablaTheme.Colors.ButtonBackground.baseDisabled = UIColor(red: 0.00, green: 0.48, blue: 1.00, alpha: 1.00)

NablaTheme.Button.base = NablaViews.PrimaryButton.Theme(
    backgroundColor: UIColor(red: 0.15, green: 0.16, blue: 0.18, alpha: 1.00),
    highlightedBackgroundColor: UIColor(red: 0.44, green: 0.47, blue: 0.49, alpha: 1.00),
    disabledBackgroundColor: UIColor(red: 0.44, green: 0.47, blue: 0.49, alpha: 1.00),
    textColor: UIColor(red: 0.91, green: 0.94, blue: 1.00, alpha: 1.00),
    highlightedTextColor: UIColor(red: 0.87, green: 0.69, blue: 1.00, alpha: 1.00),
    disabledTextColor: UIColor(red: 0.87, green: 0.69, blue: 1.00, alpha: 1.00),
    font: .systemFont(ofSize: 16),
    cornerRadius: 8
)

NablaTheme.Fonts.body = .systemFont(ofSize: 16)

Semantic colors and dark mode support

The basics

By default, our NablaTheme uses different colors for the light and dark modes. We use adaptive colors with semantic names.

Semantic naming means that colors' name describe the usage of the color, not its value. This is why the "default blue" is called Colors.Background.accent or Colors.Text.accent (or any other .accent) and not Colors.blue.

Adaptive means that values will be different if your user has enabled the dark mode or not. For example Colors.Text.accent will be #007AFF for light mode and #0A84FF for dark mode (it matches with UIColor.systemBlue).

Colors are grouped by intended usage:

  • Background for colors used to fill the "empty" space on screen.
  • Text for colors used on labels (can also be applied to icons when coupled to some text).
  • Fill for colors used to fill surfaces inside UI elements (example: the inside of a checkbox when checked).
  • Stroke for colors used to draw shapes of UI elements, mostly borders or separators (example: the border of a checkbox).
  • ButtonBackground for colors used to fill buttons. Similar to Fill colors, but with more granularity to support multiple states (highlighted, disabled...).
  • ButtonText for colors used on button titles (or icons), Similar to Text colors, but with more granularity to support multiple states (highlighted, disabled...).

Then we have patterns for generic names:

  • base describe the "default" case, often a shade of grey in either light and dark mode.
  • accent is the main color theme of the app. Not always the exact same color, but a shade of it. Think of it as the "primary color".
  • subdued suffix is a less intense ton of the color it is added to. In light mode, it means the color will be brighter, but darker in dark mode.
  • disabled & highlighted suffixes describe the corresponding states of a UIControl.
  • on prefix means that such color should be used for elements appearing on top of the said color. Example: ButtonText.onAccent will be used on ButtonBackground.accent.
  • danger is used for errors or destructive actions.

To override NablaTheme.Colors with your own adaptive colors, you can use an xcassetcatalog and set the "Appearances" property to "Any, Light, Dark". More for information, visit Apple's documentation.

You can then override our semantic colors directly:

NablaTheme.Colors.Text.accent = UIColor(named: "myPrimaryColor")

Example

Below is a detailed example of how our theme is applied to the time slot picker screen:

  1. TimeSlotPickerViewTheme.backgroundColor, defaults to NablaTheme.Colors.Background.underCard
  2. TimeSlotPickerViewTheme.CellTheme.ButtonThem.selectedBackgroundColor, defaults to NablaTheme.Colors.Fill.accent
  3. TimeSlotPickerViewTheme.CellTheme.ButtonTheme.selectedTextColor, defaults to NablaTheme.Colors.Text.onAccent
  4. TimeSlotPickerViewTheme.CellTheme.ButtonTheme.borderColor, defaults to NablaTheme.Colors.Stroke.subdued
  5. TimeSlotPickerViewTheme.CellTheme.ButtonTheme.textColor, defaults to NablaTheme.Colors.Text.subdued
  6. TimeSlotPickerViewTheme.CellTheme.titleColor, defaults to NablaTheme.Colors.Text.base
  7. TimeSlotPickerViewTheme.CellTheme.subtitleColor, defaults to NablaTheme.Colors.Text.subdued
  8. TimeSlotPickerViewTheme.CellTheme.backgroundColor, defaults to NablaTheme.Colors.Fill.card
  9. and 10. are part of TimeSlotPickerViewTheme.button which default to NablaTheme.Button.accent

Additional theme attributes

In addition to global attributes, Nabla UI components have some specific shared elements that you can customize. Here's how you can use them:

NablaTheme.Shared.loadingViewIndicatorTintColor = UIColor(red: 0.15, green: 0.16, blue: 0.18, alpha: 1.00)

Here's the list of available attributes:

Theme attributeDescriptionDefault value
NablaTheme.Shared.loadingViewIndicatorTintColorTint color used for the loading indicator.Colors.Stroke.accent

AvatarView

Theme attributeDescriptionDefault value
NablaTheme.AvatarView.backgroundColorBackground color used to display the avatar of someone who doesn't have a profile picture.Colors.Fill.base
NablaTheme.AvatarView.tintColorColor used to tint the initials or the default icon in the avatar of someone who doesn't have a profile picture.Colors.Text.subdued
NablaTheme.AvatarView.defaultIconDefault image used in the avatar view when we don't have a profile picture nor the initials.UIImage(systemName: "person")

Module-specific theming

You can find module-specific theme attributes in their own section: