Skip to content
The mobile SDKs are available on request. Email support@grona.ai to get access.

Theming

This page matches Grona’s components to your app and describes their accessibility on iOS. You pass a GronaTheme in your options once, at launch. Every banner, progress bar, offer and message then uses your fonts, colours and corner radius. Decisions you render yourself are not affected, because your own views draw them.

AcmeTheme.swift
import Grona
import UIKit
let acmeTheme = GronaTheme(
regularFont: UIFont(name: "AcmeSans-Regular", size: 15),
boldFont: UIFont(name: "AcmeSans-Bold", size: 15),
primary: UIColor(red: 0.04, green: 0.25, blue: 0.55, alpha: 1),
onPrimary: .white,
accent: UIColor(red: 1.00, green: 0.76, blue: 0.20, alpha: 1),
cornerRadius: 12
)

Pass it as theme: acmeTheme in your GronaOptions. Every parameter is optional.

Parameter Default Used for
regularFont nil, the system font Body text. Grona takes the typeface from the font and sets each text size itself.
boldFont nil, the bold version of the regular font Titles, labels and buttons
primary #054B3A Banner background, the progress bar’s fill before a tier is met, and icon colour in messages
onPrimary #FFFFFF Text on banners
accent #6FCF97 Banner accents, the progress bar’s fill once a tier is met, and the tint of offers and message icons
surface #FFFFFF Background of progress bars, and the base of offer and message backgrounds
text #1A1C1A Body text on progress bars, offers and messages
mutedText #6B706C Secondary text, such as footnotes
cornerRadius 14 Corner radius of component cards, in points. Values are kept between 0 and 32.

How campaign styles combine with your theme

Section titled “How campaign styles combine with your theme”

A campaign can set its own background, text and accent colours for one component, for example a weekend breakfast banner in a seasonal colour. Those override your theme for that component only. Everything else comes from your theme.

Whatever the source, the SDK checks text against its background. When the preferred text colour does not reach WCAG AA contrast on that background, the SDK uses white or near-black text, whichever reads better.

The theme is fixed for the life of the process. Grona resolves each colour once, the first time it draws a component, in the appearance of that slot, and keeps the result. A colour with a dark variant, such as an asset catalogue colour, therefore follows the appearance your app has when Grona first draws. It does not change if the shopper switches appearance while the app runs. Choose colours that read in both appearances, as Theming and accessibility advises.

This is what the iOS components do in this version.

  • Readable contrast. Before drawing, the SDK checks each text colour against its background. If titles, body text or button labels would fall below a contrast ratio of 4.5:1 (WCAG AA), it switches them to white or near-black, whichever reads better. Eyebrows and progress footnotes use a 3:1 threshold. This applies to your theme and to per-campaign colours.
  • Dynamic Type. Text follows the shopper’s text size setting. The SDK scales your fonts with UIFontMetrics and updates them when the setting changes.
  • Line limits. Each text field has a line limit, the same as on Android, for example three lines for a banner title and four for body text. Text that runs over ends with an ellipsis, so at the largest text sizes long copy is cut off.
  • Touch targets. The banner’s call-to-action button has a touch target of at least 44 by 44 points.
  • VoiceOver. Icons, the banner image and the progress bar graphic are not accessibility elements. VoiceOver reads the text and the button.
  • Reduce Motion. The reveal and collapse animations and the progress bar fill are skipped when Reduce Motion is on.
  • Right-to-left layouts. Components lay out with leading and trailing edges, and the progress bar fills from the leading edge, so they mirror in right-to-left languages.
  • No overlay filter. iOS does not let other apps draw over yours, so the components have no equivalent of Android’s filter for taps that pass through another app’s overlay.

The SDK sets no custom accessibility labels on components, and draws no dismiss control on them. For what your campaigns and app should do, see Theming and accessibility.

  • The theme is fixed at Grona.start. There is no call to change it while the app runs.
  • Components are UIKit views. GronaSlot wraps them for SwiftUI, so SwiftUI environment values such as .font, .tint or .foregroundStyle do not reach them.