From d64865f8f15cffac900db18631ae78cf5a5e7966 Mon Sep 17 00:00:00 2001 From: Karolina Poplawska Date: Sun, 4 Jan 2026 18:52:15 +0100 Subject: [PATCH 1/4] [PPSDK-292] fix title and checkbox alignment --- .../mobileconsents/sdk/ui/ui/ConsentsScreen.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/ConsentsScreen.kt b/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/ConsentsScreen.kt index e0d6947..d22b1d8 100644 --- a/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/ConsentsScreen.kt +++ b/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/ConsentsScreen.kt @@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding @@ -257,11 +258,14 @@ fun ConsentRow( ) { Text( text = title, - modifier = Modifier.clearAndSetSemantics {}, + modifier = Modifier.weight(1f).clearAndSetSemantics {}, color = MaterialTheme.colorScheme.onSurface, style = MaterialTheme.typography.titleMedium ) onChange(checked) + + Spacer(modifier = Modifier.width(8.dp)) + Switch( checked = checked, onCheckedChange = { From 4ca14e248b2b272cec43d19d4bf5b50e0c3f1878 Mon Sep 17 00:00:00 2001 From: Karolina Poplawska Date: Sun, 4 Jan 2026 22:37:22 +0100 Subject: [PATCH 2/4] [PPSDK-292] extended color customisation, slight code format --- .../sdk/ui/CustomColorScheme.kt | 154 +++++++++++++----- .../sdk/ui/ui/ConsentsActivity.kt | 6 +- .../sdk/ui/ui/ConsentsScreen.kt | 126 +++++++++----- .../sdk/ui/ui/ConsentsWrappingScreen.kt | 26 ++- .../mobileconsents/sdk/ui/ui/CustomUI.kt | 45 ++++- .../mobileconsents/sdk/ui/ui/theme/Theme.kt | 23 ++- .../mobileconsents/ui/MainActivity.kt | 19 ++- .../mobileconsents/ui/ui/theme/Color.kt | 14 ++ 8 files changed, 305 insertions(+), 108 deletions(-) create mode 100644 example/src/main/java/com/cookieinformation/mobileconsents/ui/ui/theme/Color.kt diff --git a/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/CustomColorScheme.kt b/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/CustomColorScheme.kt index 600bfd0..363bc8d 100644 --- a/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/CustomColorScheme.kt +++ b/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/CustomColorScheme.kt @@ -1,9 +1,10 @@ package com.cookieinformation.mobileconsents.sdk.ui -import androidx.compose.material3.ColorScheme import androidx.compose.material3.darkColorScheme import androidx.compose.material3.lightColorScheme import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.toArgb +import com.cookieinformation.mobileconsents.sdk.ui.ui.MaterialColorSchemeWithCustom /** * Customizable colors (based as much as possible on component colors from https://m3.material.io/components) @@ -17,6 +18,14 @@ import androidx.compose.ui.graphics.Color * outline * outlineVariant * primaryContainer + * +//// Additional //// + * primaryButton + * secondaryButton + * topBar + * divider + * checkboxes + * readMore */ data class CustomColorScheme( @@ -28,59 +37,118 @@ data class CustomColorScheme( val onSurfaceVariantColorCode: Int? = null, val surfaceVariantColorCode: Int? = null, val outlineColorCode: Int? = null, - val outlineVariantColorCode: Int? = null -) + val outlineVariantColorCode: Int? = null, + val primaryButton: Int? = null, + val secondaryButton: Int? = null, + val topBar: Int? = null, + val divider: Int? = null, + val checkboxes: Int? = null, + val readMore: Int? = null, +){ + constructor( + primaryColor: Color? = null, + onPrimaryColor: Color? = null, + primaryContainerColor: Color? = null, + surfaceColor: Color? = null, + onSurfaceColor: Color? = null, + onSurfaceVariantColor: Color? = null, + surfaceVariantColor: Color? = null, + outlineColor: Color? = null, + outlineVariantColor: Color? = null, + primaryButton: Color? = null, + secondaryButton: Color? = null, + topBar: Color? = null, + divider: Color? = null, + checkbox: Color? = null, + readMore: Color? = null + ) : this( + primaryColorCode = primaryColor?.toArgb(), + onPrimaryColorCode = onPrimaryColor?.toArgb(), + primaryContainerColorCode = primaryContainerColor?.toArgb(), + surfaceColorCode = surfaceColor?.toArgb(), + onSurfaceColorCode = onSurfaceColor?.toArgb(), + onSurfaceVariantColorCode = onSurfaceVariantColor?.toArgb(), + surfaceVariantColorCode = surfaceVariantColor?.toArgb(), + outlineColorCode = outlineColor?.toArgb(), + outlineVariantColorCode = outlineVariantColor?.toArgb(), + primaryButton = primaryButton?.toArgb(), + secondaryButton = secondaryButton?.toArgb(), + topBar = topBar?.toArgb(), + divider = divider?.toArgb(), + checkboxes = checkbox?.toArgb(), + readMore = readMore?.toArgb() + ) +} -internal fun CustomColorScheme.toLightColorScheme(): ColorScheme { +internal fun CustomColorScheme.toLightColorScheme(): MaterialColorSchemeWithCustom { val lcm = lightColorScheme() - val pc = if (primaryColorCode != null) Color(primaryColorCode) else lcm.primary - val opc = if (onPrimaryColorCode != null) Color(onPrimaryColorCode) else lcm.onPrimary - val pcc = if (primaryContainerColorCode != null) Color(primaryContainerColorCode) else lcm.primaryContainer - val sc = if (surfaceColorCode != null) Color(surfaceColorCode) else lcm.surface - val osc = if (onSurfaceColorCode != null) Color(onSurfaceColorCode) else lcm.onSurface - val osvc = if (onSurfaceVariantColorCode != null) Color(onSurfaceVariantColorCode) else lcm.onSurfaceVariant - val svc = if (surfaceVariantColorCode != null) Color(surfaceVariantColorCode) else lcm.surfaceVariant - val oc = if (outlineColorCode != null) Color(outlineColorCode) else lcm.outline - val ovc = if (outlineVariantColorCode != null) Color(outlineVariantColorCode) else lcm.outlineVariant + val pc = primaryColorCode?.let { Color(it) } ?: lcm.primary + val opc = onPrimaryColorCode?.let { Color(it) } ?: lcm.onPrimary + val pcc = primaryContainerColorCode?.let { Color(it) } ?: lcm.primaryContainer + val sc = surfaceColorCode?.let { Color(it) } ?: lcm.surface + val osc = onSurfaceColorCode?.let { Color(it) } ?: lcm.onSurface + val osvc = onSurfaceVariantColorCode?.let { Color(it) } ?: lcm.onSurfaceVariant + val svc = surfaceVariantColorCode?.let { Color(it) } ?: lcm.surfaceVariant + val oc = outlineColorCode?.let { Color(it) } ?: lcm.outline + val ovc = outlineVariantColorCode?.let { Color(it) } ?: lcm.outlineVariant - return lightColorScheme( - primary = pc, - onPrimary = opc, - primaryContainer = pcc, - surface = sc, - onSurface = osc, - onSurfaceVariant = osvc, - surfaceVariant = svc, - outline = oc, - outlineVariant = ovc + return MaterialColorSchemeWithCustom( + materialColorScheme = + lightColorScheme( + primary = pc, + onPrimary = opc, + primaryContainer = pcc, + surface = sc, + onSurface = osc, + onSurfaceVariant = osvc, + surfaceVariant = svc, + outline = oc, + outlineVariant = ovc + ), + primaryButton = primaryButton?.let { Color(it) } ?: pc, + secondaryButton = secondaryButton?.let { Color(it) } ?: pc, + topBar = topBar?.let { Color(it) } ?: pc, + divider = divider?.let { Color(it) } ?: oc, + checkbox = checkboxes?.let { Color(it) } ?: pc, + readMore = readMore?.let { Color(it) } ?: pc ) + } -internal fun CustomColorScheme.toDarkColorScheme(): ColorScheme { +internal fun CustomColorScheme.toDarkColorScheme(): MaterialColorSchemeWithCustom { val dcm = darkColorScheme() - val pc = if (primaryColorCode != null) Color(primaryColorCode) else dcm.primary - val opc = if (onPrimaryColorCode != null) Color(onPrimaryColorCode) else dcm.onPrimary - val pcc = if (primaryContainerColorCode != null) Color(primaryContainerColorCode) else dcm.primaryContainer - val sc = if (surfaceColorCode != null) Color(surfaceColorCode) else dcm.surface - val osc = if (onSurfaceColorCode != null) Color(onSurfaceColorCode) else dcm.onSurface - val osvc = if (onSurfaceVariantColorCode != null) Color(onSurfaceVariantColorCode) else dcm.onSurfaceVariant - val svc = if (surfaceVariantColorCode != null) Color(surfaceVariantColorCode) else dcm.surfaceVariant - val oc = if (outlineColorCode != null) Color(outlineColorCode) else dcm.outline - val ovc = if (outlineVariantColorCode != null) Color(outlineVariantColorCode) else dcm.outlineVariant + val pc = primaryColorCode?.let { Color(it) } ?: dcm.primary + val opc = onPrimaryColorCode?.let { Color(it) } ?: dcm.onPrimary + val pcc = primaryContainerColorCode?.let { Color(it) } ?: dcm.primaryContainer + val sc = surfaceColorCode?.let { Color(it) } ?: dcm.surface + val osc = onSurfaceColorCode?.let { Color(it) } ?: dcm.onSurface + val osvc = onSurfaceVariantColorCode?.let { Color(it) } ?: dcm.onSurfaceVariant + val svc = surfaceVariantColorCode?.let { Color(it) } ?: dcm.surfaceVariant + val oc = outlineColorCode?.let { Color(it) } ?: dcm.outline + val ovc = outlineVariantColorCode?.let { Color(it) } ?: dcm.outlineVariant - return darkColorScheme( - primary = pc, - onPrimary = opc, - primaryContainer = pcc, - surface = sc, - onSurface = osc, - onSurfaceVariant = osvc, - surfaceVariant = svc, - outline = oc, - outlineVariant = ovc + return MaterialColorSchemeWithCustom( + materialColorScheme = + darkColorScheme( + primary = pc, + onPrimary = opc, + primaryContainer = pcc, + surface = sc, + onSurface = osc, + onSurfaceVariant = osvc, + surfaceVariant = svc, + outline = oc, + outlineVariant = ovc + ), + primaryButton = primaryButton?.let { Color(it) } ?: pc, + secondaryButton = secondaryButton?.let { Color(it) } ?: pc, + topBar = topBar?.let { Color(it) } ?: pc, + divider = divider?.let { Color(it) } ?: oc, + checkbox = checkboxes?.let { Color(it) } ?: pc, + readMore = readMore?.let { Color(it) } ?: pc ) } \ No newline at end of file diff --git a/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/ConsentsActivity.kt b/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/ConsentsActivity.kt index ab9eb2c..ecc79b0 100644 --- a/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/ConsentsActivity.kt +++ b/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/ConsentsActivity.kt @@ -21,12 +21,14 @@ class ConsentsActivity : ComponentActivity() { setContent { AndroidUiSDKTheme( - customerLightColorScheme = CustomUI.lightColorScheme, - customerDarkColorScheme = CustomUI.darkColorScheme, + additionalLightColors = CustomUI.lightColorSchemeWithCustom, + additionalDarkColors = CustomUI.darkColorSchemeWithCustom, typography = CustomUI.typography ) { ConsentsWrappingScreen( viewModel = ConsentsViewModel(application), + additionalLightColors = CustomUI.lightColorSchemeWithCustom, + additionalDarkColors = CustomUI.darkColorSchemeWithCustom, userId = userId ) } diff --git a/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/ConsentsScreen.kt b/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/ConsentsScreen.kt index d22b1d8..a059577 100644 --- a/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/ConsentsScreen.kt +++ b/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/ConsentsScreen.kt @@ -19,7 +19,9 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.Divider +import androidx.compose.material3.DividerDefaults import androidx.compose.material3.FilledIconButton +import androidx.compose.material3.IconButtonDefaults import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedButton import androidx.compose.material3.Switch @@ -63,7 +65,8 @@ fun ConsentsScreen( consents: List, showPolicy: () -> Unit, acceptConsents: (MutableMap) -> Unit, - modifier: Modifier = Modifier + modifier: Modifier = Modifier, + additionalColors: MaterialColorSchemeWithCustom? = null ) { val selectedValues by rememberSaveable { @@ -74,7 +77,6 @@ fun ConsentsScreen( val requiredSectionHeader = stringResource(R.string.required_consents_header) val optionalSectionHeader = stringResource(R.string.optional_consents_header) - Column( modifier = modifier, verticalArrangement = Arrangement.SpaceBetween @@ -108,39 +110,42 @@ fun ConsentsScreen( .verticalScroll(rememberScrollState()) .weight(weight = 1f, fill = true) ) { - PrivacyPolicySection(privacyPolicy, showPolicy) + PrivacyPolicySection(privacyPolicy, showPolicy, additionalColors) val requiredConsents = consents.filter { it.required } val optionalConsents = consents.filter { !it.required } if (requiredConsents.isNotEmpty()) { - SectionHeader(requiredSectionHeader) + SectionHeader(requiredSectionHeader, additionalColors) requiredConsents.forEach { item -> ConsentRow( - item.title, - item.description, - item.required, - item.accepted + title = item.title, + description = item.description, + required = item.required, + accepted = item.accepted, + additionalColors = additionalColors ) { checked -> selectedValues[item.id] = checked } - Divider() + Divider(color = additionalColors?.divider ?: DividerDefaults.color) } } if (optionalConsents.isNotEmpty()) { - SectionHeader(optionalSectionHeader) + SectionHeader(optionalSectionHeader, additionalColors) optionalConsents.forEach { item -> Column { ConsentRow( - item.title, - item.description, - item.required, - item.accepted - ) { checked -> - selectedValues[item.id] = checked - } - Divider() + title = item.title, + description = item.description, + required = item.required, + accepted = item.accepted, + additionalColors = additionalColors, + onChange = { checked -> + selectedValues[item.id] = checked + }, + ) + Divider(color = additionalColors?.divider ?: DividerDefaults.color) } } } @@ -160,6 +165,11 @@ fun ConsentsScreen( .weight(1f, true), onClick = { acceptConsents(selectedValues) }, shape = RoundedCornerShape(20), + colors = IconButtonDefaults.filledIconButtonColors( + containerColor = additionalColors?.primaryButton + ?: MaterialTheme.colorScheme.primary, + contentColor = MaterialTheme.colorScheme.onPrimary + ) ) { Text( stringResource(R.string.accept_selected), @@ -176,6 +186,11 @@ fun ConsentsScreen( .toMutableMap()) }, shape = RoundedCornerShape(20), + colors = IconButtonDefaults.filledIconButtonColors( + containerColor = additionalColors?.secondaryButton + ?: MaterialTheme.colorScheme.primary, + contentColor = MaterialTheme.colorScheme.onPrimary + ) ) { val acceptALlText = stringResource(id = R.string.accept_all) @@ -214,7 +229,7 @@ fun ConsentsScreen( } @Composable -fun SectionHeader(title: String) { +fun SectionHeader(title: String, additionalColors: MaterialColorSchemeWithCustom?) { Text( text = title, color = MaterialTheme.colorScheme.onSurface, @@ -224,7 +239,7 @@ fun SectionHeader(title: String) { .padding(16.dp) .wrapContentHeight() ) - Divider() + Divider(color = additionalColors?.divider ?: DividerDefaults.color) } @Composable @@ -233,6 +248,7 @@ fun ConsentRow( description: String, required: Boolean, accepted: Boolean, + additionalColors: MaterialColorSchemeWithCustom?, onChange: (checked: Boolean) -> Unit ) { var checked by remember { mutableStateOf(required || accepted) } @@ -242,14 +258,15 @@ fun ConsentRow( val itemAccepted = stringResource(id = R.string.item_accepted) val itemRejected = stringResource(id = R.string.item_rejected) - Column(modifier = Modifier - .background(MaterialTheme.colorScheme.surface) - .fillMaxWidth() - .wrapContentHeight() - .padding(horizontal = 16.dp, vertical = 8.dp) - .semantics(mergeDescendants = true) { - contentDescription = "$title \n\n$stringBuilder" - }) + Column( + modifier = Modifier + .background(MaterialTheme.colorScheme.surface) + .fillMaxWidth() + .wrapContentHeight() + .padding(horizontal = 16.dp, vertical = 8.dp) + .semantics(mergeDescendants = true) { + contentDescription = "$title \n\n$stringBuilder" + }) { Row( modifier = Modifier.fillMaxWidth(), @@ -280,10 +297,29 @@ fun ConsentRow( this.stateDescription = "$title $desc" }, enabled = !required, - colors = SwitchDefaults.colors( - disabledCheckedTrackColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.5f), - disabledCheckedThumbColor = MaterialTheme.colorScheme.onPrimary.copy(alpha = 0.5f), - ), + colors = when { + additionalColors?.checkbox != null -> { + val checkboxColor = additionalColors.checkbox + SwitchDefaults.colors( + checkedTrackColor = checkboxColor, + checkedThumbColor = MaterialTheme.colorScheme.onPrimary, + uncheckedTrackColor = checkboxColor.copy(alpha = 0.4f), + uncheckedThumbColor = checkboxColor, + disabledCheckedTrackColor = checkboxColor.copy(alpha = 0.5f), + disabledCheckedThumbColor = MaterialTheme.colorScheme.onPrimary.copy( + alpha = 0.5f + ), + ) + } + else -> { + SwitchDefaults.colors( + disabledCheckedTrackColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.5f), + disabledCheckedThumbColor = MaterialTheme.colorScheme.onPrimary.copy( + alpha = 0.5f + ), + ) + } + } ) } if (containsHtmlTags(description)) { @@ -302,11 +338,17 @@ fun ConsentRow( } @Composable -fun PrivacyPolicySection(policy: UIConsentItem?, showPolicy: () -> Unit) { +fun PrivacyPolicySection( + policy: UIConsentItem?, + showPolicy: () -> Unit, + additionalColors: MaterialColorSchemeWithCustom? +) { policy?.let { - Column(modifier = Modifier - .fillMaxWidth() - .background(MaterialTheme.colorScheme.surface)) { + Column( + modifier = Modifier + .fillMaxWidth() + .background(MaterialTheme.colorScheme.surface) + ) { Text( text = stringResource(id = R.string.privacy_policy_header), modifier = Modifier.padding(vertical = 8.dp, horizontal = 16.dp), @@ -314,10 +356,12 @@ fun PrivacyPolicySection(policy: UIConsentItem?, showPolicy: () -> Unit) { style = MaterialTheme.typography.headlineSmall ) - Text(text = policy.title, + Text( + text = policy.title, style = MaterialTheme.typography.titleMedium, modifier = Modifier.padding(horizontal = 16.dp), - color = MaterialTheme.colorScheme.onSurface) + color = MaterialTheme.colorScheme.onSurface + ) OutlinedButton( contentPadding = PaddingValues(0.dp), modifier = Modifier.padding(horizontal = 16.dp), @@ -334,19 +378,21 @@ fun PrivacyPolicySection(policy: UIConsentItem?, showPolicy: () -> Unit) { ) ), textAlign = TextAlign.Center, + color = additionalColors?.readMore ?: MaterialTheme.colorScheme.onSurface ) // Specify the icon using the icon parameter Image( - colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.primary), + colorFilter = ColorFilter.tint(additionalColors?.readMore ?: MaterialTheme.colorScheme.primary), painter = painterResource(R.drawable.navigate_next), contentDescription = null ) } ) - Divider() + Divider(color = additionalColors?.divider ?: DividerDefaults.color) } } } + fun containsHtmlTags(input: String): Boolean { // This regex pattern looks for strings that contain "<" followed by any characters, // and then ">", indicating the presence of HTML tags. diff --git a/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/ConsentsWrappingScreen.kt b/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/ConsentsWrappingScreen.kt index 4fc3256..c2440a4 100644 --- a/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/ConsentsWrappingScreen.kt +++ b/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/ConsentsWrappingScreen.kt @@ -4,6 +4,7 @@ import android.app.Activity import androidx.activity.ComponentActivity import androidx.activity.compose.BackHandler import androidx.compose.foundation.background +import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.material3.MaterialTheme @@ -35,11 +36,18 @@ enum class AppScreen { fun ConsentsWrappingScreen( viewModel: ConsentsViewModel, navController: NavHostController = rememberNavController(), - userId: String? + userId: String?, + additionalLightColors: MaterialColorSchemeWithCustom?, + additionalDarkColors: MaterialColorSchemeWithCustom? ) { val context = LocalContext.current val coroutineScope = rememberCoroutineScope() + val additionalColors = when { + isSystemInDarkTheme() -> additionalDarkColors + else -> additionalLightColors + } + LaunchedEffect(Unit) { viewModel.getConsents(userId).onFailure { (context as? ComponentActivity)?.finish() @@ -48,11 +56,12 @@ fun ConsentsWrappingScreen( BackHandler(enabled = true) { coroutineScope.launch { - viewModel.canNavigateBack(userId).fold(onFailure = { - if (context is Activity) { - context.finish() - } - }, + viewModel.canNavigateBack(userId).fold( + onFailure = { + if (context is Activity) { + context.finish() + } + }, onSuccess = { if (it) { if (context is Activity) { @@ -82,14 +91,15 @@ fun ConsentsWrappingScreen( consents = consentsUiState.consents.filter { consent -> consent.type != ConsentType.PRIVACY_POLICY }.map { it.toUIConsentItem() }, acceptConsents = { coroutineScope.launch { - viewModel.saveConsents(userId, it) + viewModel.saveConsents(userId, it) }.invokeOnCompletion { (context as? ComponentActivity)?.finish() } }, showPolicy = { navController.navigate(AppScreen.PrivacyPolicy.name) - } + }, + additionalColors = additionalColors ) } composable(route = AppScreen.PrivacyPolicy.name) { diff --git a/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/CustomUI.kt b/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/CustomUI.kt index 6b4e329..0a80933 100644 --- a/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/CustomUI.kt +++ b/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/CustomUI.kt @@ -1,17 +1,41 @@ package com.cookieinformation.mobileconsents.sdk.ui.ui import androidx.compose.material3.ColorScheme +import androidx.compose.material3.Typography +import androidx.compose.ui.graphics.Color + + +data class MaterialColorSchemeWithCustom( + val materialColorScheme: ColorScheme?, + val primaryButton: Color? = null, + val secondaryButton: Color? = null, + val topBar: Color? = null, + val divider: Color? = null, + val checkbox: Color? = null, + val readMore: Color? = null +) object CustomUI { - private var customLightColorScheme: ColorScheme? = null - private var customDarkColorScheme: ColorScheme? = null - private var customTypography: androidx.compose.material3.Typography? = null + private var customLightColorScheme: MaterialColorSchemeWithCustom? = null + private var customDarkColorScheme: MaterialColorSchemeWithCustom? = null + private var customTypography: Typography? = null + fun setCustomUi( lightScheme: ColorScheme? = null, darkScheme: ColorScheme? = null, - typography: androidx.compose.material3.Typography? = null + typography: Typography? = null + ) { + customLightColorScheme = MaterialColorSchemeWithCustom(materialColorScheme = lightScheme) + customDarkColorScheme = MaterialColorSchemeWithCustom(materialColorScheme = darkScheme) + customTypography = typography + } + + fun setCustomUi( + lightScheme: MaterialColorSchemeWithCustom? = null, + darkScheme: MaterialColorSchemeWithCustom? = null, + typography: Typography? = null ) { customLightColorScheme = lightScheme customDarkColorScheme = darkScheme @@ -19,12 +43,17 @@ object CustomUI { } val lightColorScheme: ColorScheme? - get() = customLightColorScheme - + get() = customLightColorScheme?.materialColorScheme val darkColorScheme: ColorScheme? - get() = customDarkColorScheme + get() = customDarkColorScheme?.materialColorScheme - val typography: androidx.compose.material3.Typography? + val typography: Typography? get() = customTypography + + val lightColorSchemeWithCustom: MaterialColorSchemeWithCustom? + get() = customLightColorScheme + + val darkColorSchemeWithCustom: MaterialColorSchemeWithCustom? + get() = customDarkColorScheme } \ No newline at end of file diff --git a/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/theme/Theme.kt b/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/theme/Theme.kt index 65cbdcf..3cda1f3 100644 --- a/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/theme/Theme.kt +++ b/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/theme/Theme.kt @@ -10,10 +10,11 @@ import androidx.compose.material3.darkColorScheme import androidx.compose.material3.lightColorScheme import androidx.compose.runtime.Composable import androidx.compose.runtime.SideEffect -import androidx.compose.ui.graphics.Color +import androidx.compose.runtime.remember import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.platform.LocalView import androidx.core.view.WindowCompat +import com.cookieinformation.mobileconsents.sdk.ui.ui.MaterialColorSchemeWithCustom /** * Customizable colors (based as much as possible on component colors from https://m3.material.io/components) @@ -39,6 +40,8 @@ import androidx.core.view.WindowCompat * labelLarge - Read more, Bottom bar button texts * labelSmall - Powered by Cookie Information, Device identifier * + * additionalLightColors - wrapper for ColorScheme with additional colors + * additionalDarkColors- wrapper for ColorScheme with additional colors */ @Composable @@ -47,18 +50,28 @@ fun AndroidUiSDKTheme( // Dynamic color is available on Android 12+ customerLightColorScheme: ColorScheme? = null, customerDarkColorScheme: ColorScheme? = null, + additionalLightColors: MaterialColorSchemeWithCustom? = null, + additionalDarkColors: MaterialColorSchemeWithCustom? = null, typography: Typography? = null, content: @Composable () -> Unit ) { - val colorScheme = when { - darkTheme -> customerDarkColorScheme ?: darkColorScheme() - else -> customerLightColorScheme ?: lightColorScheme() + + val colorScheme = remember(darkTheme, customerLightColorScheme, customerDarkColorScheme, additionalLightColors, additionalDarkColors) { + when { + darkTheme -> customerDarkColorScheme ?: additionalDarkColors?.materialColorScheme ?: darkColorScheme() + else -> customerLightColorScheme ?: additionalLightColors?.materialColorScheme ?: lightColorScheme() + } } + + val additionalColors = remember(darkTheme, additionalLightColors, additionalDarkColors) { + if (darkTheme) additionalDarkColors else additionalLightColors + } + val view = LocalView.current if (!view.isInEditMode) { SideEffect { val window = (view.context as Activity).window - window.statusBarColor = colorScheme.primary.toArgb() + window.statusBarColor = additionalColors?.topBar?.toArgb() ?: colorScheme.primary.toArgb() WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = !darkTheme } } diff --git a/example/src/main/java/com/cookieinformation/mobileconsents/ui/MainActivity.kt b/example/src/main/java/com/cookieinformation/mobileconsents/ui/MainActivity.kt index 6c05dae..524556d 100644 --- a/example/src/main/java/com/cookieinformation/mobileconsents/ui/MainActivity.kt +++ b/example/src/main/java/com/cookieinformation/mobileconsents/ui/MainActivity.kt @@ -19,6 +19,13 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.cookieinformation.mobileconsents.sdk.ui.ConsentsUISDK +import com.cookieinformation.mobileconsents.sdk.ui.CustomColorScheme +import com.cookieinformation.mobileconsents.ui.ui.theme.BrightOrange +import com.cookieinformation.mobileconsents.ui.ui.theme.Cyan +import com.cookieinformation.mobileconsents.ui.ui.theme.ForestGreen +import com.cookieinformation.mobileconsents.ui.ui.theme.Gold +import com.cookieinformation.mobileconsents.ui.ui.theme.LimeGreen +import com.cookieinformation.mobileconsents.ui.ui.theme.NavyBlue import com.cookieinformation.mobileconsents.ui.ui.theme.SampleAppTheme import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch @@ -28,13 +35,21 @@ class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - + ConsentsUISDK.init( clientID = "91cb67d4-9ebc-4c7e-974f-858d08b7ab7d", clientSecret = "a4fe5c7763ef5d8e395c9ef8c358c1f67c0876b6e7465c59ce9421d6ca67d02ba3d3a37f0351f320a2216878e4ddc570bdf6092a351b24067d536ded36a75946", solutionId = "a7a95d5e-e99b-44ff-8383-b7f6d1b720a8", context = this@MainActivity, - languageCode = "en" + customLightColorScheme = CustomColorScheme( + primaryButton = NavyBlue, + secondaryButton = LimeGreen, + topBar = ForestGreen, + divider = Cyan, + checkbox = BrightOrange, + readMore = Gold + ), + languageCode = "en", ) setContent { diff --git a/example/src/main/java/com/cookieinformation/mobileconsents/ui/ui/theme/Color.kt b/example/src/main/java/com/cookieinformation/mobileconsents/ui/ui/theme/Color.kt new file mode 100644 index 0000000..2ded78c --- /dev/null +++ b/example/src/main/java/com/cookieinformation/mobileconsents/ui/ui/theme/Color.kt @@ -0,0 +1,14 @@ +package com.cookieinformation.mobileconsents.ui.ui.theme + +import androidx.compose.ui.graphics.Color + +val DeepPurple = Color(0xFF673AB7) +val BrightOrange = Color(0xFFFF5722) +val LimeGreen = Color(0xFFCDDC39) +val DeepPink = Color(0xFFE91E63) +val Cyan = Color(0xFF00BCD4) +val Amber = Color(0xFFFFC107) +val NavyBlue = Color(0xFF0D47A1) +val CrimsonRed = Color(0xFFB71C1C) +val ForestGreen = Color(0xFF1B5E20) +val Gold = Color(0xFFFFD700) \ No newline at end of file From 029186454839c3e561b7f615edb3bfd182f7747a Mon Sep 17 00:00:00 2001 From: Karolina Poplawska Date: Mon, 5 Jan 2026 00:23:30 +0100 Subject: [PATCH 3/4] [PPSDK-292] extend custom typography --- .../mobileconsents/sdk/ui/ConsentsUISDK.kt | 2 +- .../mobileconsents/sdk/ui/CustomTypography.kt | 76 +++++++++++++++--- .../sdk/ui/ui/ConsentsActivity.kt | 1 + .../sdk/ui/ui/ConsentsScreen.kt | 53 +++++++----- .../sdk/ui/ui/ConsentsWrappingScreen.kt | 7 +- .../mobileconsents/sdk/ui/ui/CustomUI.kt | 13 ++- .../mobileconsents/ui/MainActivity.kt | 16 ++++ example/src/main/res/font/bbh_bogle.ttf | Bin 0 -> 15656 bytes example/src/main/res/font/dancing_script.ttf | Bin 0 -> 130480 bytes 9 files changed, 131 insertions(+), 37 deletions(-) create mode 100644 example/src/main/res/font/bbh_bogle.ttf create mode 100644 example/src/main/res/font/dancing_script.ttf diff --git a/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ConsentsUISDK.kt b/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ConsentsUISDK.kt index dc9f476..f465d49 100644 --- a/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ConsentsUISDK.kt +++ b/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ConsentsUISDK.kt @@ -43,7 +43,7 @@ object ConsentsUISDK { CustomUI.setCustomUi( customLightColorScheme?.toLightColorScheme(), customDarkColorScheme?.toDarkColorScheme(), - customTypography?.toTypography() + customTypography ) } diff --git a/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/CustomTypography.kt b/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/CustomTypography.kt index 14c935c..26c57d7 100644 --- a/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/CustomTypography.kt +++ b/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/CustomTypography.kt @@ -1,19 +1,48 @@ package com.cookieinformation.mobileconsents.sdk.ui -import android.content.Context -import androidx.annotation.FontRes import androidx.compose.material3.Typography -import androidx.compose.ui.text.font.Font -import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.TextStyle + /** * Customizable typography * - * headlineSmall (Privacy policy headline) - * titleMedium (Privacy policy short, header section text, consent item tile) - * bodyMedium (consent item body (when no html), privacy policy body (when no html)) - * labelLarge - Read more, Bottom bar button texts - * labelSmall - Powered by Cookie Information, Device identifier + * Core Material3 mappings: + * headlineSmall - Privacy Policy headline + * titleMedium - Privacy Policy short, header section text, consent item title + * bodyMedium - Consent item body (when no HTML), Privacy Policy body (when no HTML) + * labelLarge - "Read more", Bottom bar button texts + * labelSmall - "Powered by Cookie Information", Device identifier + * + * Additional custom fields: + * + * readMore + * - Optional override for "Read more" button/label text style. + * - If provided, it replaces `bodyMedium` for "Read more" text. + * + * requiredTitle + * - Optional override for the "Required" . + * - If provided, it **replaces `titleMedium`**. + * + * requiredSectionTitle + * - Optional override for the header of the required consents section. + * - If provided, it **replaces `titleMedium`** in SectionHeader for required section. + * + * requiredSectionBody + * - Optional override for the body text of the required consents section. + * - If provided, it **replaces `bodyMedium`** for the section body. + * + * optionalTitle + * - Optional override for the "Optional". + * - If provided, it **replaces `titleMedium`** . + * + * optionalSectionTitle + * - Optional override for the header of the optional consents section. + * - If provided, it **replaces `titleMedium`** in SectionHeader for optional section. + * + * optionalSectionBody + * - Optional override for the body text of the optional consents section. + * - If provided, it **replaces `bodyMedium`** for the section body. */ data class CustomTypography( @@ -21,8 +50,31 @@ data class CustomTypography( val titleMedium: CustomTextStyle? = null, val bodyMedium: CustomTextStyle? = null, val labelLarge: CustomTextStyle? = null, - val labelSmall: CustomTextStyle? = null -) + val labelSmall: CustomTextStyle? = null, + //additional + val readMore: CustomTextStyle? = null, + val requiredTitle: CustomTextStyle? = null, + val requiredSectionTitle: CustomTextStyle? = null, + val requiredSectionBody: CustomTextStyle? = null, + val optionalTitle: CustomTextStyle? = null, + val optionalSectionTitle: CustomTextStyle? = null, + val optionalSectionBody: CustomTextStyle? = null +) { + + fun itemTitleStyle(isRequired: Boolean): TextStyle? = + if (isRequired) requiredTitle?.toTextStyle() + else optionalTitle?.toTextStyle() + + fun sectionHeaderStyle(isRequired: Boolean): TextStyle? = + if (isRequired) requiredSectionTitle?.toTextStyle() + else optionalSectionTitle?.toTextStyle() + + fun sectionBodyStyle(isRequired: Boolean): TextStyle? = + if (isRequired) requiredSectionBody?.toTextStyle() + else optionalSectionBody?.toTextStyle() + + fun readMoreStyle(): TextStyle? = readMore?.toTextStyle() +} internal fun CustomTypography.toTypography(): Typography { val defaultTypography = Typography() @@ -35,7 +87,7 @@ internal fun CustomTypography.toTypography(): Typography { return Typography( headlineSmall = hs, - titleMedium = tm, + titleMedium = tm, bodyMedium = bm, labelLarge = ll, labelSmall = ls diff --git a/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/ConsentsActivity.kt b/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/ConsentsActivity.kt index ecc79b0..9b91268 100644 --- a/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/ConsentsActivity.kt +++ b/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/ConsentsActivity.kt @@ -29,6 +29,7 @@ class ConsentsActivity : ComponentActivity() { viewModel = ConsentsViewModel(application), additionalLightColors = CustomUI.lightColorSchemeWithCustom, additionalDarkColors = CustomUI.darkColorSchemeWithCustom, + additionalTypography = CustomUI.additionalTypography, userId = userId ) } diff --git a/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/ConsentsScreen.kt b/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/ConsentsScreen.kt index a059577..203606f 100644 --- a/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/ConsentsScreen.kt +++ b/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/ConsentsScreen.kt @@ -50,6 +50,7 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.withStyle import androidx.compose.ui.unit.dp import androidx.core.text.HtmlCompat +import com.cookieinformation.mobileconsents.sdk.ui.CustomTypography import com.cookieinformation.mobileconsents.sdk.ui.R import com.cookieinformation.mobileconsents.sdk.ui.UIConsentItem import com.cookieinformation.mobileconsents.sdk.ui.ui.components.TextViewComposable @@ -66,7 +67,8 @@ fun ConsentsScreen( showPolicy: () -> Unit, acceptConsents: (MutableMap) -> Unit, modifier: Modifier = Modifier, - additionalColors: MaterialColorSchemeWithCustom? = null + additionalColors: MaterialColorSchemeWithCustom? = null, + additionalTypography: CustomTypography? ) { val selectedValues by rememberSaveable { @@ -110,20 +112,22 @@ fun ConsentsScreen( .verticalScroll(rememberScrollState()) .weight(weight = 1f, fill = true) ) { - PrivacyPolicySection(privacyPolicy, showPolicy, additionalColors) + PrivacyPolicySection(privacyPolicy, showPolicy, additionalColors, additionalTypography) val requiredConsents = consents.filter { it.required } val optionalConsents = consents.filter { !it.required } if (requiredConsents.isNotEmpty()) { - SectionHeader(requiredSectionHeader, additionalColors) + SectionHeader(requiredSectionHeader, additionalColors, additionalTypography, true) requiredConsents.forEach { item -> ConsentRow( title = item.title, description = item.description, required = item.required, accepted = item.accepted, - additionalColors = additionalColors + additionalColors = additionalColors, + additionalTypography = additionalTypography, + isRequiredSection = true ) { checked -> selectedValues[item.id] = checked } @@ -132,7 +136,7 @@ fun ConsentsScreen( } if (optionalConsents.isNotEmpty()) { - SectionHeader(optionalSectionHeader, additionalColors) + SectionHeader(optionalSectionHeader, additionalColors, additionalTypography, false) optionalConsents.forEach { item -> Column { ConsentRow( @@ -141,6 +145,8 @@ fun ConsentsScreen( required = item.required, accepted = item.accepted, additionalColors = additionalColors, + additionalTypography = additionalTypography, + isRequiredSection = false, onChange = { checked -> selectedValues[item.id] = checked }, @@ -229,11 +235,19 @@ fun ConsentsScreen( } @Composable -fun SectionHeader(title: String, additionalColors: MaterialColorSchemeWithCustom?) { +fun SectionHeader( + title: String, + additionalColors: MaterialColorSchemeWithCustom?, + additionalTypography: CustomTypography?, + isRequiredSection: Boolean = false +) { + + val customTextStyle = additionalTypography?.itemTitleStyle(isRequiredSection) + Text( text = title, color = MaterialTheme.colorScheme.onSurface, - style = MaterialTheme.typography.titleMedium, + style = customTextStyle ?: MaterialTheme.typography.titleMedium, modifier = Modifier .fillMaxWidth() .padding(16.dp) @@ -249,6 +263,8 @@ fun ConsentRow( required: Boolean, accepted: Boolean, additionalColors: MaterialColorSchemeWithCustom?, + additionalTypography: CustomTypography?, + isRequiredSection: Boolean = false, onChange: (checked: Boolean) -> Unit ) { var checked by remember { mutableStateOf(required || accepted) } @@ -275,9 +291,11 @@ fun ConsentRow( ) { Text( text = title, - modifier = Modifier.weight(1f).clearAndSetSemantics {}, + modifier = Modifier + .weight(1f) + .clearAndSetSemantics {}, color = MaterialTheme.colorScheme.onSurface, - style = MaterialTheme.typography.titleMedium + style = additionalTypography?.sectionHeaderStyle(isRequiredSection) ?: MaterialTheme.typography.titleMedium ) onChange(checked) @@ -311,6 +329,7 @@ fun ConsentRow( ), ) } + else -> { SwitchDefaults.colors( disabledCheckedTrackColor = MaterialTheme.colorScheme.primary.copy(alpha = 0.5f), @@ -324,13 +343,12 @@ fun ConsentRow( } if (containsHtmlTags(description)) { TextViewComposable(description = description) - } - else { + } else { Text( text = description, modifier = Modifier.clearAndSetSemantics {}, color = MaterialTheme.colorScheme.onSurfaceVariant, - style = MaterialTheme.typography.bodyMedium + style = additionalTypography?.sectionBodyStyle(isRequiredSection) ?: MaterialTheme.typography.bodyMedium ) } @@ -341,7 +359,8 @@ fun ConsentRow( fun PrivacyPolicySection( policy: UIConsentItem?, showPolicy: () -> Unit, - additionalColors: MaterialColorSchemeWithCustom? + additionalColors: MaterialColorSchemeWithCustom?, + additionalTypography: CustomTypography? ) { policy?.let { Column( @@ -371,12 +390,8 @@ fun PrivacyPolicySection( content = { Text( text = stringResource(id = R.string.read_more), - - style = MaterialTheme.typography.labelLarge.copy( - platformStyle = PlatformTextStyle( - includeFontPadding = false - ) - ), + style = (additionalTypography?.readMoreStyle() ?: MaterialTheme.typography.bodyMedium) + .copy(platformStyle = PlatformTextStyle(includeFontPadding = false)), textAlign = TextAlign.Center, color = additionalColors?.readMore ?: MaterialTheme.colorScheme.onSurface ) diff --git a/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/ConsentsWrappingScreen.kt b/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/ConsentsWrappingScreen.kt index c2440a4..2a20fc6 100644 --- a/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/ConsentsWrappingScreen.kt +++ b/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/ConsentsWrappingScreen.kt @@ -22,6 +22,7 @@ import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import com.cookieinformation.mobileconsents.core.domain.entities.ConsentType +import com.cookieinformation.mobileconsents.sdk.ui.CustomTypography import com.cookieinformation.mobileconsents.sdk.ui.toUIConsentItem import kotlinx.coroutines.launch @@ -38,7 +39,8 @@ fun ConsentsWrappingScreen( navController: NavHostController = rememberNavController(), userId: String?, additionalLightColors: MaterialColorSchemeWithCustom?, - additionalDarkColors: MaterialColorSchemeWithCustom? + additionalDarkColors: MaterialColorSchemeWithCustom?, + additionalTypography: CustomTypography? ) { val context = LocalContext.current val coroutineScope = rememberCoroutineScope() @@ -99,7 +101,8 @@ fun ConsentsWrappingScreen( showPolicy = { navController.navigate(AppScreen.PrivacyPolicy.name) }, - additionalColors = additionalColors + additionalColors = additionalColors, + additionalTypography = additionalTypography ) } composable(route = AppScreen.PrivacyPolicy.name) { diff --git a/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/CustomUI.kt b/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/CustomUI.kt index 0a80933..ad1c040 100644 --- a/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/CustomUI.kt +++ b/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/ui/CustomUI.kt @@ -3,6 +3,8 @@ package com.cookieinformation.mobileconsents.sdk.ui.ui import androidx.compose.material3.ColorScheme import androidx.compose.material3.Typography import androidx.compose.ui.graphics.Color +import com.cookieinformation.mobileconsents.sdk.ui.CustomTypography +import com.cookieinformation.mobileconsents.sdk.ui.toTypography data class MaterialColorSchemeWithCustom( @@ -19,7 +21,8 @@ object CustomUI { private var customLightColorScheme: MaterialColorSchemeWithCustom? = null private var customDarkColorScheme: MaterialColorSchemeWithCustom? = null - private var customTypography: Typography? = null + private var baseTypography: Typography? = null + private var customTypography: CustomTypography? = null fun setCustomUi( @@ -29,16 +32,17 @@ object CustomUI { ) { customLightColorScheme = MaterialColorSchemeWithCustom(materialColorScheme = lightScheme) customDarkColorScheme = MaterialColorSchemeWithCustom(materialColorScheme = darkScheme) - customTypography = typography + baseTypography = typography } fun setCustomUi( lightScheme: MaterialColorSchemeWithCustom? = null, darkScheme: MaterialColorSchemeWithCustom? = null, - typography: Typography? = null + typography: CustomTypography? = null ) { customLightColorScheme = lightScheme customDarkColorScheme = darkScheme + baseTypography = typography?.toTypography() customTypography = typography } @@ -49,6 +53,9 @@ object CustomUI { get() = customDarkColorScheme?.materialColorScheme val typography: Typography? + get() = baseTypography + + val additionalTypography: CustomTypography? get() = customTypography val lightColorSchemeWithCustom: MaterialColorSchemeWithCustom? diff --git a/example/src/main/java/com/cookieinformation/mobileconsents/ui/MainActivity.kt b/example/src/main/java/com/cookieinformation/mobileconsents/ui/MainActivity.kt index 524556d..05e4651 100644 --- a/example/src/main/java/com/cookieinformation/mobileconsents/ui/MainActivity.kt +++ b/example/src/main/java/com/cookieinformation/mobileconsents/ui/MainActivity.kt @@ -20,6 +20,8 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.cookieinformation.mobileconsents.sdk.ui.ConsentsUISDK import com.cookieinformation.mobileconsents.sdk.ui.CustomColorScheme +import com.cookieinformation.mobileconsents.sdk.ui.CustomTextStyle +import com.cookieinformation.mobileconsents.sdk.ui.CustomTypography import com.cookieinformation.mobileconsents.ui.ui.theme.BrightOrange import com.cookieinformation.mobileconsents.ui.ui.theme.Cyan import com.cookieinformation.mobileconsents.ui.ui.theme.ForestGreen @@ -49,6 +51,20 @@ class MainActivity : ComponentActivity() { checkbox = BrightOrange, readMore = Gold ), + customTypography = CustomTypography( + requiredSectionTitle = CustomTextStyle( + fontResId = R.font.bbh_bogle, + fontSize = 15, + ), + optionalSectionTitle = CustomTextStyle( + fontResId = R.font.dancing_script, + fontSize = 22 + ), + optionalSectionBody = CustomTextStyle( + fontResId = R.font.dancing_script, + fontSize = 30 + ) + ), languageCode = "en", ) diff --git a/example/src/main/res/font/bbh_bogle.ttf b/example/src/main/res/font/bbh_bogle.ttf new file mode 100644 index 0000000000000000000000000000000000000000..d9f2a270e8a7aee520a9fba4bde6cfbac0d16935 GIT binary patch literal 15656 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 CGZZlZ literal 0 HcmV?d00001 diff --git a/example/src/main/res/font/dancing_script.ttf b/example/src/main/res/font/dancing_script.ttf new file mode 100644 index 0000000000000000000000000000000000000000..5c0f61a8915eee29d2ed72e5600e0aac2269a838 GIT binary patch literal 130480 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 UBj^UBB0)FE;wN`{xlZ?g0DiW;oB#j- literal 0 HcmV?d00001 From e56527543295b0ab0b7a784100fe1e3395e043dd Mon Sep 17 00:00:00 2001 From: Karolina Poplawska Date: Mon, 5 Jan 2026 00:40:56 +0100 Subject: [PATCH 4/4] [PPSDK-292] clean old code to avoid duplicates --- .../sdk/ui/CustomColorScheme.kt | 99 ++++++------------- 1 file changed, 32 insertions(+), 67 deletions(-) diff --git a/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/CustomColorScheme.kt b/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/CustomColorScheme.kt index 363bc8d..ba5c505 100644 --- a/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/CustomColorScheme.kt +++ b/UI-SDK/src/main/java/com/cookieinformation/mobileconsents/sdk/ui/CustomColorScheme.kt @@ -1,5 +1,6 @@ package com.cookieinformation.mobileconsents.sdk.ui +import androidx.compose.material3.ColorScheme import androidx.compose.material3.darkColorScheme import androidx.compose.material3.lightColorScheme import androidx.compose.ui.graphics.Color @@ -44,7 +45,7 @@ data class CustomColorScheme( val divider: Int? = null, val checkboxes: Int? = null, val readMore: Int? = null, -){ +) { constructor( primaryColor: Color? = null, onPrimaryColor: Color? = null, @@ -80,75 +81,39 @@ data class CustomColorScheme( ) } -internal fun CustomColorScheme.toLightColorScheme(): MaterialColorSchemeWithCustom { - val lcm = lightColorScheme() - - val pc = primaryColorCode?.let { Color(it) } ?: lcm.primary - val opc = onPrimaryColorCode?.let { Color(it) } ?: lcm.onPrimary - val pcc = primaryContainerColorCode?.let { Color(it) } ?: lcm.primaryContainer - val sc = surfaceColorCode?.let { Color(it) } ?: lcm.surface - val osc = onSurfaceColorCode?.let { Color(it) } ?: lcm.onSurface - val osvc = onSurfaceVariantColorCode?.let { Color(it) } ?: lcm.onSurfaceVariant - val svc = surfaceVariantColorCode?.let { Color(it) } ?: lcm.surfaceVariant - val oc = outlineColorCode?.let { Color(it) } ?: lcm.outline - val ovc = outlineVariantColorCode?.let { Color(it) } ?: lcm.outlineVariant +private fun CustomColorScheme.toMaterialColorScheme(baseScheme: ColorScheme): MaterialColorSchemeWithCustom { + val primary = primaryColorCode.toColorOrDefault(baseScheme.primary) + val onPrimary = onPrimaryColorCode.toColorOrDefault(baseScheme.onPrimary) + val primaryContainer = primaryContainerColorCode.toColorOrDefault(baseScheme.primaryContainer) + val surface = surfaceColorCode.toColorOrDefault(baseScheme.surface) + val onSurface = onSurfaceColorCode.toColorOrDefault(baseScheme.onSurface) + val onSurfaceVariant = onSurfaceVariantColorCode.toColorOrDefault(baseScheme.onSurfaceVariant) + val surfaceVariant = surfaceVariantColorCode.toColorOrDefault(baseScheme.surfaceVariant) + val outline = outlineColorCode.toColorOrDefault(baseScheme.outline) + val outlineVariant = outlineVariantColorCode.toColorOrDefault(baseScheme.outlineVariant) return MaterialColorSchemeWithCustom( - materialColorScheme = - lightColorScheme( - primary = pc, - onPrimary = opc, - primaryContainer = pcc, - surface = sc, - onSurface = osc, - onSurfaceVariant = osvc, - surfaceVariant = svc, - outline = oc, - outlineVariant = ovc - ), - primaryButton = primaryButton?.let { Color(it) } ?: pc, - secondaryButton = secondaryButton?.let { Color(it) } ?: pc, - topBar = topBar?.let { Color(it) } ?: pc, - divider = divider?.let { Color(it) } ?: oc, - checkbox = checkboxes?.let { Color(it) } ?: pc, - readMore = readMore?.let { Color(it) } ?: pc + materialColorScheme = baseScheme.copy( + primary = primary, + onPrimary = onPrimary, + primaryContainer = primaryContainer, + surface = surface, + onSurface = onSurface, + onSurfaceVariant = onSurfaceVariant, + surfaceVariant = surfaceVariant, + outline = outline, + outlineVariant = outlineVariant + ), + primaryButton = primaryButton.toColorOrDefault(primary), + secondaryButton = secondaryButton.toColorOrDefault(primary), + topBar = topBar.toColorOrDefault(primary), + divider = divider.toColorOrDefault(outline), + checkbox = checkboxes.toColorOrDefault(primary), + readMore = readMore.toColorOrDefault(primary) ) - - } -internal fun CustomColorScheme.toDarkColorScheme(): MaterialColorSchemeWithCustom { - val dcm = darkColorScheme() - - val pc = primaryColorCode?.let { Color(it) } ?: dcm.primary - val opc = onPrimaryColorCode?.let { Color(it) } ?: dcm.onPrimary - val pcc = primaryContainerColorCode?.let { Color(it) } ?: dcm.primaryContainer - val sc = surfaceColorCode?.let { Color(it) } ?: dcm.surface - val osc = onSurfaceColorCode?.let { Color(it) } ?: dcm.onSurface - val osvc = onSurfaceVariantColorCode?.let { Color(it) } ?: dcm.onSurfaceVariant - val svc = surfaceVariantColorCode?.let { Color(it) } ?: dcm.surfaceVariant - val oc = outlineColorCode?.let { Color(it) } ?: dcm.outline - val ovc = outlineVariantColorCode?.let { Color(it) } ?: dcm.outlineVariant - - return MaterialColorSchemeWithCustom( - materialColorScheme = - darkColorScheme( - primary = pc, - onPrimary = opc, - primaryContainer = pcc, - surface = sc, - onSurface = osc, - onSurfaceVariant = osvc, - surfaceVariant = svc, - outline = oc, - outlineVariant = ovc - ), - primaryButton = primaryButton?.let { Color(it) } ?: pc, - secondaryButton = secondaryButton?.let { Color(it) } ?: pc, - topBar = topBar?.let { Color(it) } ?: pc, - divider = divider?.let { Color(it) } ?: oc, - checkbox = checkboxes?.let { Color(it) } ?: pc, - readMore = readMore?.let { Color(it) } ?: pc - ) +internal fun CustomColorScheme.toLightColorScheme() = toMaterialColorScheme(lightColorScheme()) +internal fun CustomColorScheme.toDarkColorScheme() = toMaterialColorScheme(darkColorScheme()) +fun Int?.toColorOrDefault(default: Color) = this?.let { Color(it) } ?: default -} \ No newline at end of file