Skip to content

feat: expose BannerInitCustomization for banner styling overrides - #226

Merged
uc-brunosilva merged 1 commit into
masterfrom
feature/banner-init-customization
Jul 15, 2026
Merged

feat: expose BannerInitCustomization for banner styling overrides#226
uc-brunosilva merged 1 commit into
masterfrom
feature/banner-init-customization

Conversation

@uc-brunosilva

@uc-brunosilva uc-brunosilva commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

User description

Summary

  • Bridges the native BannerInitCustomization/PurposeListStyle model (available since Usercentrics core SDK 2.28.0, already pinned in this repo) into the React Native SDK.
  • Exposed as bannerCustomization on UsercentricsOptions (init-time, passed to Usercentrics.initialize) and as initCustomization on BannerSettings (show-time, passed to showFirstLayer/showSecondLayer) — both share the same BannerInitCustomization TS type, mirroring the native SDK's design.
  • All fields are optional/nullable end-to-end (TS → Android Kotlin → iOS Swift): unset fields are omitted rather than defaulted to 0/false/"", since null means "inherit from the layer below" in the native SDK.
  • Deprecation notice mirrored in TSDoc on the new model, bannerCustomization, and initCustomization, matching the native SDK's own @Deprecated annotation (still fully functional, no removal date, no replacement API yet).

Changes

  • TypeScript: new BannerInitCustomization class + PurposeListStyle enum (src/models/BannerInitCustomization.tsx), wired into UsercentricsOptions and BannerSettings.
  • Android (Kotlin): new BannerInitCustomizationExtensions.kt (ReadableMap → native object, enum parsing), getFloatOrNull helper added, wired into UserOptionsExtensions.kt and BannerSettingsExtensions.kt.
  • iOS (Swift): new BannerInitCustomization+Dict.swift (NSDictionary → native object, boxing raw values into KotlinInt/KotlinFloat/KotlinBoolean), wired into UsercentricsOptions+Dict.swift and BannerSettings+Dict.swift.

Test plan

  • tsc --noEmit clean
  • npx jest src/__tests__/index.test.ts — 34/34 passing (2 new tests added)
  • ./gradlew :react-native-usercentrics:testDebugUnitTest — full Android bridge suite passing (4 new tests added)
  • iOS react-native-usercentrics pod target builds successfully against Usercentrics/UsercentricsUI 2.28.0
  • xcodebuild test on sampleTests — 12/12 relevant cases passing (5 new tests added: BannerInitCustomizationDictTests + additions to BannerSettingsDictTests)

🤖 Generated with Claude Code


CodeAnt-AI Description

Expose banner styling overrides in React Native

What Changed

  • You can now pass banner appearance overrides when setting up the app and when showing the banner.
  • The new banner styling options include spacing, font sizes, button colors, header spacing, and purpose list style.
  • Banner settings now accept the same init-time styling overrides used during app setup.
  • Empty or missing styling fields are left unset, so the native banner keeps its default appearance.
  • Added tests that cover full mapping, missing values, nested banner settings, and style enum handling on both platforms.

Impact

✅ Custom banner styling at app launch
✅ Custom banner styling when showing the banner
✅ Fewer missing-style regressions

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

Summary by CodeRabbit

  • New Features

    • Added banner initialization customization options for padding, typography, colors, buttons, tabs, headers, and language controls.
    • Added support for customization through banner settings and global configuration.
    • Added boxed and flat purpose-list styles.
    • Exposed the new customization models for React Native use.
  • Bug Fixes

    • Ensured banner customization settings are correctly passed to Android and iOS.
  • Tests

    • Added coverage for customization mapping, nested settings, optional values, and platform integration.

Bridges the native BannerInitCustomization/PurposeListStyle model (already
shipped in Usercentrics core SDK 2.28.0) into the RN SDK as bannerCustomization
on UsercentricsOptions (init-time) and initCustomization on BannerSettings
(show-time), across TypeScript, Android, and iOS.
@codeant-ai

codeant-ai Bot commented Jul 14, 2026

Copy link
Copy Markdown

CodeAnt AI is reviewing your PR.

@codeant-ai

codeant-ai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

Banner customization

Layer / File(s) Summary
Customization model contracts
src/models/BannerInitCustomization.tsx, src/models/BannerSettings.tsx, src/models/UsercentricsOptions.tsx, src/models/index.tsx
Adds the deprecated customization model, PurposeListStyle, optional settings properties, constructor parameters, and barrel export.
Native customization mapping
android/src/main/java/com/usercentrics/reactnative/extensions/*, ios/Extensions/*
Maps customization fields from React Native maps and dictionaries, including enum conversion and propagation through banner settings and user options.
Cross-platform mapping validation
android/src/test/..., sample/ios/sampleTests/*, src/__tests__/index.test.ts
Tests field mapping, omitted values, enum parsing, nested customization, and JavaScript-to-native bridge calls.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ReactNative as React Native
  participant NativeBridge as Native bridge
  participant BannerSettings as BannerSettings
  participant UsercentricsOptions as UsercentricsOptions
  ReactNative->>NativeBridge: pass initCustomization and bannerCustomization
  NativeBridge->>BannerSettings: map initCustomization
  NativeBridge->>UsercentricsOptions: map bannerCustomization
  BannerSettings-->>ReactNative: preserve customization in showFirstLayer
  UsercentricsOptions-->>ReactNative: preserve customization in configure
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: exposing BannerInitCustomization for banner styling and banner setup overrides.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/banner-init-customization

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install timed out. The project may have too many dependencies for the sandbox.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codeant-ai codeant-ai Bot added the size:XL This PR changes 500-999 lines, ignoring generated files label Jul 14, 2026
@pantoaibot

pantoaibot Bot commented Jul 14, 2026

Copy link
Copy Markdown

PR Summary:

Add BannerInitCustomization support to native and JS layers so banner-style overrides can be passed via options or BannerSettings.

  • Core

    • New JS model: BannerInitCustomization + PurposeListStyle enum; exported from models index.
    • BannerSettings and UsercentricsOptions models extended to carry optional banner/init customization (marked deprecated in comments).
    • Add mapping/parsing logic across platforms to convert incoming dictionaries/maps into BannerInitCustomization objects.
  • Android

    • New BannerInitCustomizationExtensions.kt: ReadableMap -> BannerInitCustomization mapping (including purposeListStyle enum).
    • BannerSettingsExtensions.kt: now reads "initCustomization" from BannerSettings map and maps it.
    • UserOptionsExtensions.kt: now reads "bannerCustomization" into options.bannerCustomization.
    • ReadableMapExtensions.kt: added getFloatOrNull helper.
    • New unit tests: BannerInitCustomizationExtensionsTest to validate mapping and nested inclusion in options.
  • iOS

    • New BannerInitCustomization+Dict.swift: NSDictionary -> BannerInitCustomization initializer and PurposeListStyle enum mapping.
    • BannerSettings+Dict.swift: reads "initCustomization" and passes into BannerSettings initializer.
    • UsercentricsOptions+Dict.swift: now reads "bannerCustomization" into options.bannerCustomization.
    • Added unit tests in sample project: BannerInitCustomizationDictTests and updated BannerSettingsDictTests.
  • JS tests

    • Updated tests to verify configure/showFirstLayer honor BannerInitCustomization in UsercentricsOptions and BannerSettings.
  • Notes / compatibility

    • The feature is additive; no breaking API changes expected (new fields are optional).
    • The banner/init customization API is annotated deprecated in JS models — preferred to configure appearance via dashboard.
    • Key names:
      • BannerSettings mapping uses "initCustomization".
      • UsercentricsOptions uses "bannerCustomization".
    • No dependency updates.

Reviewed by Panto AI

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Expose BannerInitCustomization for init/show-time banner styling overrides

✨ Enhancement 🧪 Tests 🕐 40+ Minutes

Grey Divider

AI Description

• Add BannerInitCustomization + PurposeListStyle to the RN public TypeScript API.
• Bridge bannerCustomization (init) and initCustomization (show) into Android/iOS native SDKs.
• Preserve native semantics by omitting unset fields (nullable end-to-end) with test coverage.
Diagram

graph TD
  A["RN app (TS)"] --> B["BannerInitCustomization model"] --> C["RNUsercentricsModule"]
  C --> D["Android ReadableMap mappers"] --> N["Usercentrics core SDK"]
  C --> F["iOS NSDictionary mappers"] --> N
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Use plain TS types (interface) instead of a class constructor
  • ➕ Less boilerplate and no need to default everything to undefined
  • ➕ More idiomatic for RN option objects (structural typing)
  • ➖ Harder to attach consistent TSDoc/deprecation guidance to a single exported symbol
  • ➖ May be a breaking/behavioral change if consumers rely on the class today/future
2. Generate bridge mappers from a shared field schema
  • ➕ Reduces drift risk across TS/Kotlin/Swift when fields are added/renamed
  • ➕ Makes exhaustive mapping and tests easier to keep in sync
  • ➖ Introduces build/tooling complexity and a new source-of-truth artifact
  • ➖ Overkill unless this model changes frequently

Recommendation: The PR’s approach (explicit per-platform mapping + tests) is appropriate for a one-off bridge of a wide but stable native model, and it correctly preserves the native “null means inherit” behavior by omitting unset fields. If this customization surface expands further, consider a small shared schema/codegen to prevent TS/Android/iOS field-list drift.

Files changed (15) +564 / -6

Enhancement (11) +262 / -6
BannerInitCustomizationExtensions.ktAdd ReadableMap → BannerInitCustomization mapper and enum parsing +45/-0

Add ReadableMap → BannerInitCustomization mapper and enum parsing

• Introduces a Kotlin extension to build a native BannerInitCustomization from a React Native ReadableMap, mapping every supported field as nullable. Adds a String-to-PurposeListStyle parser that returns null for unknown values.

android/src/main/java/com/usercentrics/reactnative/extensions/BannerInitCustomizationExtensions.kt

BannerSettingsExtensions.ktSupport initCustomization in BannerSettings bridge mapping +1/-0

Support initCustomization in BannerSettings bridge mapping

• Extends bannerSettingsFromMap to read an initCustomization map and convert it to a native BannerInitCustomization. This enables show-time styling overrides via showFirstLayer/showSecondLayer settings.

android/src/main/java/com/usercentrics/reactnative/extensions/BannerSettingsExtensions.kt

ReadableMapExtensions.ktAdd getFloatOrNull helper for nullable numeric mapping +4/-0

Add getFloatOrNull helper for nullable numeric mapping

• Adds getFloatOrNull built on top of getDoubleOrNull to support BannerInitCustomization.lineSpacingMultiplier without defaulting. Keeps numeric handling consistent with other nullable getters.

android/src/main/java/com/usercentrics/reactnative/extensions/ReadableMapExtensions.kt

UserOptionsExtensions.ktMap bannerCustomization into UsercentricsOptions (Android) +4/-0

Map bannerCustomization into UsercentricsOptions (Android)

• Extends usercentricsOptionsFromMap to parse an optional bannerCustomization object and assign it to options.bannerCustomization. Preserves nullability by only setting the field when the map is present.

android/src/main/java/com/usercentrics/reactnative/extensions/UserOptionsExtensions.kt

BannerInitCustomization+Dict.swiftAdd NSDictionary → BannerInitCustomization initializer and enum parsing (iOS) +53/-0

Add NSDictionary → BannerInitCustomization initializer and enum parsing (iOS)

• Introduces a convenience initializer that converts an NSDictionary into a native BannerInitCustomization, boxing scalar values into KotlinInt/KotlinFloat/KotlinBoolean as required by the SDK bindings. Adds PurposeListStyle.from(enumString:) that safely returns nil on unknown/absent values.

ios/Extensions/BannerInitCustomization+Dict.swift

BannerSettings+Dict.swiftWire initCustomization into BannerSettings dictionary initializer (iOS) +6/-1

Wire initCustomization into BannerSettings dictionary initializer (iOS)

• Updates BannerSettings(from:) to import Usercentrics and build an optional BannerInitCustomization from initCustomization in the dictionary. Passes the resulting value into the BannerSettings initializer to support show-time overrides.

ios/Extensions/BannerSettings+Dict.swift

UsercentricsOptions+Dict.swiftWire bannerCustomization into UsercentricsOptions initialization (iOS) +4/-0

Wire bannerCustomization into UsercentricsOptions initialization (iOS)

• Extends UsercentricsOptions.initialize(from:) to read bannerCustomization and construct a BannerInitCustomization when present. Keeps behavior consistent with Android by not populating the field when absent.

ios/Extensions/UsercentricsOptions+Dict.swift

BannerInitCustomization.tsxIntroduce BannerInitCustomization and PurposeListStyle in TypeScript +125/-0

Introduce BannerInitCustomization and PurposeListStyle in TypeScript

• Adds a new exported PurposeListStyle enum and BannerInitCustomization class mirroring the native SDK fields. Marks the model deprecated in TSDoc and keeps all properties optional to preserve native inheritance semantics.

src/models/BannerInitCustomization.tsx

BannerSettings.tsxExpose initCustomization on BannerSettings (deprecated) +8/-2

Expose initCustomization on BannerSettings (deprecated)

• Adds initCustomization?: BannerInitCustomization to BannerSettings, including deprecation TSDoc matching native guidance. Updates the constructor signature to accept and store initCustomization.

src/models/BannerSettings.tsx

UsercentricsOptions.tsxExpose bannerCustomization on UsercentricsOptions (deprecated) +11/-3

Expose bannerCustomization on UsercentricsOptions (deprecated)

• Adds bannerCustomization?: BannerInitCustomization to UsercentricsOptions with deprecation TSDoc. Extends the options constructor to accept and assign bannerCustomization alongside existing initialization fields.

src/models/UsercentricsOptions.tsx

index.tsxExport BannerInitCustomization model from the public models barrel +1/-0

Export BannerInitCustomization model from the public models barrel

• Adds BannerInitCustomization to the models index exports so consumers can import it from the package model entrypoint.

src/models/index.tsx

Tests (4) +302 / -0
BannerInitCustomizationExtensionsTest.ktAdd Android unit tests for BannerInitCustomization mapping behavior +107/-0

Add Android unit tests for BannerInitCustomization mapping behavior

• Adds tests covering full-field mapping, omission of unset fields (nulls rather than defaults), enum parsing behavior, and nested mapping via usercentricsOptionsFromMap. Validates bridge correctness for both init-time and parsing semantics.

android/src/test/java/com/usercentrics/reactnative/extensions/BannerInitCustomizationExtensionsTest.kt

BannerInitCustomizationDictTests.swiftAdd iOS tests for BannerInitCustomization dictionary mapping +104/-0

Add iOS tests for BannerInitCustomization dictionary mapping

• Adds XCTest coverage for full-field mapping, omission of unset fields, nil dictionary handling, enum parsing, and bannerCustomization mapping via UsercentricsOptions.initialize(from:). Ensures iOS bridge semantics match native expectations.

sample/ios/sampleTests/BannerInitCustomizationDictTests.swift

BannerSettingsDictTests.swiftAdd iOS test for BannerSettings initCustomization mapping +15/-0

Add iOS test for BannerSettings initCustomization mapping

• Imports Usercentrics and adds a test verifying BannerSettings(from:) correctly maps initCustomization into a BannerInitCustomization with expected values. Confirms show-time customization support on iOS.

sample/ios/sampleTests/BannerSettingsDictTests.swift

index.test.tsAdd JS-side tests for passing bannerCustomization/initCustomization through calls +76/-0

Add JS-side tests for passing bannerCustomization/initCustomization through calls

• Adds Jest tests ensuring BannerInitCustomization can be attached to UsercentricsOptions.bannerCustomization and BannerSettings.initCustomization and is passed through to the mocked native module. Validates the new public API surface is wired into call sites.

src/tests/index.test.ts

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider

Great, no issues found!

Qodo reviewed your code and found no material issues that require review

Grey Divider

Qodo Logo

Comment thread ios/Extensions/BannerInitCustomization+Dict.swift
@codeant-ai

codeant-ai Bot commented Jul 14, 2026

Copy link
Copy Markdown

CodeAnt AI finished reviewing your PR.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/models/BannerInitCustomization.tsx (1)

12-38: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Fix formatting to comply with project guidelines.
Multiple TypeScript files in this PR use double quotes or include semicolons. As per path instructions for **/*.{ts,tsx}, Prettier formatting must be used with single quotes and no semicolons.

  • src/models/BannerInitCustomization.tsx#L12-L38: remove semicolons from the property declarations.
  • src/models/BannerInitCustomization.tsx#L1-L4: replace double quotes with single quotes in the enum values.
  • src/models/BannerSettings.tsx#L2-L2: replace double quotes with single quotes and remove the semicolon.
  • src/models/BannerSettings.tsx#L110-L114: remove the semicolon from the initCustomization declaration.
  • src/models/index.tsx#L1-L1: remove the trailing semicolon.
  • src/__tests__/index.test.ts#L92-L134: remove semicolons and replace double quotes with single quotes in the testConfigureBridgeWithBannerCustomization test.
  • src/__tests__/index.test.ts#L227-L255: remove semicolons and replace double quotes with single quotes in the testShowFirstLayerWithInitCustomization test.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/models/BannerInitCustomization.tsx` around lines 12 - 38, Apply the
project’s Prettier style across all listed sites: remove semicolons from
BannerInitCustomization property declarations, BannerSettings.initCustomization,
models/index.tsx, and both specified tests; replace double-quoted enum values,
imports, and test strings with single quotes. Update
src/models/BannerInitCustomization.tsx ranges 1-4 and 12-38,
src/models/BannerSettings.tsx ranges 2 and 110-114, src/models/index.tsx range
1, and src/__tests__/index.test.ts ranges 92-134 and 227-255.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/models/BannerInitCustomization.tsx`:
- Around line 12-38: Apply the project’s Prettier style across all listed sites:
remove semicolons from BannerInitCustomization property declarations,
BannerSettings.initCustomization, models/index.tsx, and both specified tests;
replace double-quoted enum values, imports, and test strings with single quotes.
Update src/models/BannerInitCustomization.tsx ranges 1-4 and 12-38,
src/models/BannerSettings.tsx ranges 2 and 110-114, src/models/index.tsx range
1, and src/__tests__/index.test.ts ranges 92-134 and 227-255.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b9c5d4fc-8752-4a33-95e9-17f4dcf5a3ff

📥 Commits

Reviewing files that changed from the base of the PR and between ae95d6e and 24d910a.

⛔ Files ignored due to path filters (1)
  • sample/ios/Podfile.lock is excluded by !**/*.lock
📒 Files selected for processing (15)
  • android/src/main/java/com/usercentrics/reactnative/extensions/BannerInitCustomizationExtensions.kt
  • android/src/main/java/com/usercentrics/reactnative/extensions/BannerSettingsExtensions.kt
  • android/src/main/java/com/usercentrics/reactnative/extensions/ReadableMapExtensions.kt
  • android/src/main/java/com/usercentrics/reactnative/extensions/UserOptionsExtensions.kt
  • android/src/test/java/com/usercentrics/reactnative/extensions/BannerInitCustomizationExtensionsTest.kt
  • ios/Extensions/BannerInitCustomization+Dict.swift
  • ios/Extensions/BannerSettings+Dict.swift
  • ios/Extensions/UsercentricsOptions+Dict.swift
  • sample/ios/sampleTests/BannerInitCustomizationDictTests.swift
  • sample/ios/sampleTests/BannerSettingsDictTests.swift
  • src/__tests__/index.test.ts
  • src/models/BannerInitCustomization.tsx
  • src/models/BannerSettings.tsx
  • src/models/UsercentricsOptions.tsx
  • src/models/index.tsx

@uc-brunosilva
uc-brunosilva merged commit fbca38d into master Jul 15, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL This PR changes 500-999 lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants