From e4cc733f4a07a9fa621950beecdcc4083dd0ee6b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 26 Jan 2023 15:15:51 +0100 Subject: [PATCH] First draft of full custom theme. ElementTheme everywhere Create ElementButton --- .../io/element/android/x/MainActivity.kt | 10 +- .../android/x/component/ShowkaseButton.kt | 4 +- .../login/changeserver/ChangeServerView.kt | 19 ++- .../features/login/root/LoginRootScreen.kt | 17 ++- .../android/features/messages/MessagesView.kt | 8 +- .../messages/actionlist/ActionListView.kt | 6 +- .../textcomposer/MessageComposerView.kt | 4 +- .../messages/timeline/TimelineView.kt | 10 +- .../timeline/components/MessageEventBubble.kt | 12 +- .../components/TimelineItemImageView.kt | 4 +- .../components/TimelineItemInformativeView.kt | 6 +- .../components/TimelineItemReactionsView.kt | 12 +- .../timeline/components/html/HtmlDocument.kt | 42 +++--- .../features/onboarding/OnBoardingScreen.kt | 29 ++--- .../rageshake/bugreport/BugReportView.kt | 10 +- .../android/features/roomlist/RoomListView.kt | 12 +- .../roomlist/components/RoomListTopBar.kt | 28 ++-- .../roomlist/components/RoomSummaryRow.kt | 8 +- .../libraries/designsystem/ColorUtil.kt | 6 +- .../libraries/designsystem/ExtendedColors.kt | 39 ------ .../android/libraries/designsystem/Theme.kt | 120 ------------------ .../android/libraries/designsystem/Type.kt | 42 +----- .../components/LabelledCheckbox.kt | 3 +- .../designsystem/components/ProgressDialog.kt | 8 +- .../components/dialogs/ConfirmationDialog.kt | 25 +++- .../components/dialogs/ErrorDialog.kt | 21 ++- .../preferences/PreferenceCategory.kt | 6 +- .../preferences/PreferenceScreen.kt | 6 +- .../components/preferences/PreferenceSlide.kt | 9 +- .../preferences/PreferenceSwitch.kt | 7 +- .../components/preferences/PreferenceText.kt | 4 +- .../designsystem/theme/ColorsDark.kt | 53 ++++++++ .../designsystem/theme/ColorsLight.kt | 54 ++++++++ .../designsystem/theme/ContentColor.kt | 42 ++++++ .../designsystem/theme/ElementColors.kt | 118 +++++++++++++++++ .../ElementSpaces.kt} | 26 ++-- .../designsystem/theme/ElementTheme.kt | 84 ++++++++++++ .../designsystem/theme/ElementTypography.kt | 118 +++++++++++++++++ .../theme/components/ElementButton.kt | 66 ++++++++++ .../theme/components/ElementCheckbox.kt | 55 ++++++++ .../theme/components/ElementMediumAppBar.kt | 56 ++++++++ .../theme/components/ElementScaffold.kt | 57 +++++++++ .../theme/components/ElementSlider.kt | 63 +++++++++ .../theme/components/ElementSurface.kt | 52 ++++++++ .../theme/components/ElementTopAppBar.kt | 56 ++++++++ .../matrix/ui/components/MatrixUserHeader.kt | 4 +- .../matrix/ui/components/MatrixUserRow.kt | 4 +- .../android/tests/uitests/ShowkaseButton.kt | 3 +- .../android/tests/uitests/ScreenshotTest.kt | 7 +- .../tests/uitests/TypographyTestPreview.kt | 4 +- 50 files changed, 1082 insertions(+), 377 deletions(-) delete mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/ExtendedColors.kt delete mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/Theme.kt create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/ColorsDark.kt create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/ColorsLight.kt create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/ContentColor.kt create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/ElementColors.kt rename libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/{components/VectorButton.kt => theme/ElementSpaces.kt} (52%) create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/ElementTheme.kt create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/ElementTypography.kt create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ElementButton.kt create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ElementCheckbox.kt create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ElementMediumAppBar.kt create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ElementScaffold.kt create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ElementSlider.kt create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ElementSurface.kt create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ElementTopAppBar.kt diff --git a/app/src/main/kotlin/io/element/android/x/MainActivity.kt b/app/src/main/kotlin/io/element/android/x/MainActivity.kt index ebd9494017..eb249d5b75 100644 --- a/app/src/main/kotlin/io/element/android/x/MainActivity.kt +++ b/app/src/main/kotlin/io/element/android/x/MainActivity.kt @@ -19,15 +19,14 @@ package io.element.android.x import android.os.Bundle import androidx.activity.compose.setContent import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface import androidx.compose.ui.Modifier import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.core.view.WindowCompat import com.bumble.appyx.core.integration.NodeHost import com.bumble.appyx.core.integrationpoint.NodeComponentActivity import io.element.android.libraries.architecture.bindings -import io.element.android.libraries.designsystem.ElementXTheme +import io.element.android.libraries.designsystem.theme.components.ElementSurface +import io.element.android.libraries.designsystem.theme.ElementTheme import io.element.android.libraries.di.DaggerComponentOwner import io.element.android.x.di.AppBindings import io.element.android.x.node.RootFlowNode @@ -41,10 +40,9 @@ class MainActivity : NodeComponentActivity() { appBindings.matrixClientsHolder().restore(savedInstanceState) WindowCompat.setDecorFitsSystemWindows(window, false) setContent { - ElementXTheme { - Surface( + ElementTheme { + ElementSurface( modifier = Modifier.fillMaxSize(), - color = MaterialTheme.colorScheme.background ) { NodeHost(integrationPoint = appyxIntegrationPoint) { RootFlowNode( diff --git a/app/src/main/kotlin/io/element/android/x/component/ShowkaseButton.kt b/app/src/main/kotlin/io/element/android/x/component/ShowkaseButton.kt index 689b46dcdc..7a9ffe9791 100644 --- a/app/src/main/kotlin/io/element/android/x/component/ShowkaseButton.kt +++ b/app/src/main/kotlin/io/element/android/x/component/ShowkaseButton.kt @@ -20,13 +20,13 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Close -import androidx.compose.material3.Button import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp +import io.element.android.libraries.designsystem.theme.components.ElementButton @Composable internal fun ShowkaseButton( @@ -36,7 +36,7 @@ internal fun ShowkaseButton( modifier: Modifier = Modifier, ) { if (isVisible) { - Button( + ElementButton( modifier = modifier .padding(top = 32.dp, start = 16.dp), onClick = onClick diff --git a/features/login/src/main/kotlin/io/element/android/features/login/changeserver/ChangeServerView.kt b/features/login/src/main/kotlin/io/element/android/features/login/changeserver/ChangeServerView.kt index 2695163ac4..a8ea2de0fb 100644 --- a/features/login/src/main/kotlin/io/element/android/features/login/changeserver/ChangeServerView.kt +++ b/features/login/src/main/kotlin/io/element/android/features/login/changeserver/ChangeServerView.kt @@ -33,12 +33,9 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.verticalScroll -import androidx.compose.material3.Button import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField -import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -57,6 +54,9 @@ import io.element.android.features.login.error.changeServerError import io.element.android.libraries.architecture.Async import io.element.android.libraries.designsystem.components.VectorIcon import io.element.android.libraries.designsystem.components.form.textFieldState +import io.element.android.libraries.designsystem.theme.ElementTheme +import io.element.android.libraries.designsystem.theme.components.ElementButton +import io.element.android.libraries.designsystem.theme.components.ElementSurface import io.element.android.libraries.testtags.TestTags import io.element.android.libraries.testtags.testTag @@ -66,9 +66,8 @@ fun ChangeServerView( modifier: Modifier = Modifier, onChangeServerSuccess: () -> Unit = {}, ) { - Surface( + ElementSurface( modifier = modifier, - color = MaterialTheme.colorScheme.background, ) { val eventSink = state.eventSink val scrollState = rememberScrollState() @@ -92,7 +91,7 @@ fun ChangeServerView( .size(width = 81.dp, height = 73.dp) .align(Alignment.CenterHorizontally) .background( - color = MaterialTheme.colorScheme.surfaceVariant, + color = ElementTheme.colors.surfaceVariant, shape = RoundedCornerShape(32.dp) ) ) { @@ -124,7 +123,7 @@ fun ChangeServerView( .padding(top = 16.dp), textAlign = TextAlign.Center, fontSize = 16.sp, - color = MaterialTheme.colorScheme.secondary + color = ElementTheme.colors.secondary ) var homeserverFieldState by textFieldState(stateValue = state.homeserver) OutlinedTextField( @@ -155,12 +154,12 @@ fun ChangeServerView( state.homeserver, state.changeServerAction.error ), - color = MaterialTheme.colorScheme.error, - style = MaterialTheme.typography.bodySmall, + color = ElementTheme.colors.error, + style = ElementTheme.typography.bodySmall, modifier = Modifier.padding(start = 16.dp) ) } - Button( + ElementButton( onClick = { eventSink(ChangeServerEvents.Submit) }, enabled = state.submitEnabled, modifier = Modifier diff --git a/features/login/src/main/kotlin/io/element/android/features/login/root/LoginRootScreen.kt b/features/login/src/main/kotlin/io/element/android/features/login/root/LoginRootScreen.kt index b927ae4555..1511648c74 100644 --- a/features/login/src/main/kotlin/io/element/android/features/login/root/LoginRootScreen.kt +++ b/features/login/src/main/kotlin/io/element/android/features/login/root/LoginRootScreen.kt @@ -32,14 +32,11 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Visibility import androidx.compose.material.icons.filled.VisibilityOff -import androidx.compose.material3.Button import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField -import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -60,6 +57,9 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import io.element.android.features.login.error.loginError import io.element.android.libraries.designsystem.components.form.textFieldState +import io.element.android.libraries.designsystem.theme.ElementTheme +import io.element.android.libraries.designsystem.theme.components.ElementButton +import io.element.android.libraries.designsystem.theme.components.ElementSurface import io.element.android.libraries.matrix.core.SessionId import io.element.android.libraries.testtags.TestTags import io.element.android.libraries.testtags.testTag @@ -74,9 +74,8 @@ fun LoginRootScreen( onLoginWithSuccess: (SessionId) -> Unit = {}, ) { val eventSink = state.eventSink - Surface( + ElementSurface( modifier = modifier, - color = MaterialTheme.colorScheme.background, ) { Box( modifier = Modifier @@ -125,7 +124,7 @@ fun LoginRootScreen( keyboardType = KeyboardType.Uri, ), ) - Button( + ElementButton( onClick = onChangeServer, modifier = Modifier .align(Alignment.CenterEnd) @@ -195,14 +194,14 @@ fun LoginRootScreen( if (state.loggedInState is LoggedInState.ErrorLoggingIn) { Text( text = loginError(state.formState, state.loggedInState.failure), - color = MaterialTheme.colorScheme.error, - style = MaterialTheme.typography.bodySmall, + color = ElementTheme.colors.error, + style = ElementTheme.typography.bodySmall, modifier = Modifier.padding(start = 16.dp) ) } } // Submit - Button( + ElementButton( onClick = { eventSink(LoginRootEvents.Submit) }, enabled = state.submitEnabled, modifier = Modifier diff --git a/features/messages/src/main/kotlin/io/element/android/features/messages/MessagesView.kt b/features/messages/src/main/kotlin/io/element/android/features/messages/MessagesView.kt index 706dc48c43..5baad6bc9d 100644 --- a/features/messages/src/main/kotlin/io/element/android/features/messages/MessagesView.kt +++ b/features/messages/src/main/kotlin/io/element/android/features/messages/MessagesView.kt @@ -21,6 +21,7 @@ package io.element.android.features.messages +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -64,6 +65,9 @@ import io.element.android.features.messages.timeline.TimelineView import io.element.android.features.messages.timeline.model.TimelineItem import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.AvatarData +import io.element.android.libraries.designsystem.theme.ElementTheme +import io.element.android.libraries.designsystem.theme.components.ElementScaffold +import io.element.android.libraries.designsystem.theme.components.ElementTopAppBar import io.element.android.libraries.designsystem.utils.LogCompositions import kotlinx.coroutines.launch import timber.log.Timber @@ -101,7 +105,7 @@ fun MessagesView( state.eventSink(MessagesEvents.HandleAction(action, messageEvent)) } - Scaffold( + ElementScaffold( modifier = modifier, contentWindowInsets = WindowInsets.statusBars, topBar = { @@ -172,7 +176,7 @@ fun MessagesViewTopBar( modifier: Modifier = Modifier, onBackPressed: () -> Unit = {}, ) { - TopAppBar( + ElementTopAppBar( modifier = modifier, navigationIcon = { IconButton(onClick = onBackPressed) { diff --git a/features/messages/src/main/kotlin/io/element/android/features/messages/actionlist/ActionListView.kt b/features/messages/src/main/kotlin/io/element/android/features/messages/actionlist/ActionListView.kt index 53df8d4b40..43414e732c 100644 --- a/features/messages/src/main/kotlin/io/element/android/features/messages/actionlist/ActionListView.kt +++ b/features/messages/src/main/kotlin/io/element/android/features/messages/actionlist/ActionListView.kt @@ -29,7 +29,6 @@ import androidx.compose.foundation.lazy.items import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.ListItem import androidx.compose.material.LocalContentColor -import androidx.compose.material.MaterialTheme import androidx.compose.material.ModalBottomSheetLayout import androidx.compose.material.ModalBottomSheetState import androidx.compose.material.ModalBottomSheetValue @@ -44,6 +43,7 @@ import androidx.compose.ui.unit.dp import io.element.android.features.messages.actionlist.model.TimelineItemAction import io.element.android.features.messages.timeline.model.TimelineItem import io.element.android.libraries.designsystem.components.VectorIcon +import io.element.android.libraries.designsystem.theme.ElementTheme import kotlinx.coroutines.flow.filter import kotlinx.coroutines.launch @@ -115,13 +115,13 @@ private fun SheetContent( text = { Text( text = action.title, - color = if (action.destructive) MaterialTheme.colors.error else Color.Unspecified, + color = if (action.destructive) ElementTheme.colors.error else Color.Unspecified, ) }, icon = { VectorIcon( resourceId = action.icon, - tint = if (action.destructive) MaterialTheme.colors.error else LocalContentColor.current, + tint = if (action.destructive) ElementTheme.colors.error else LocalContentColor.current, ) } ) diff --git a/features/messages/src/main/kotlin/io/element/android/features/messages/textcomposer/MessageComposerView.kt b/features/messages/src/main/kotlin/io/element/android/features/messages/textcomposer/MessageComposerView.kt index e3b674d32a..0d2401d667 100644 --- a/features/messages/src/main/kotlin/io/element/android/features/messages/textcomposer/MessageComposerView.kt +++ b/features/messages/src/main/kotlin/io/element/android/features/messages/textcomposer/MessageComposerView.kt @@ -18,7 +18,7 @@ package io.element.android.features.messages.textcomposer import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import io.element.android.libraries.designsystem.LocalIsDarkTheme +import io.element.android.libraries.designsystem.theme.ElementTheme import io.element.android.libraries.textcomposer.TextComposer @Composable @@ -51,7 +51,7 @@ fun MessageComposerView( onComposerTextChange = ::onComposerTextChange, composerCanSendMessage = state.isSendButtonVisible, composerText = state.text?.charSequence?.toString(), - isInDarkMode = LocalIsDarkTheme.current, + isInDarkMode = !ElementTheme.colors.isLight, modifier = modifier ) } diff --git a/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/TimelineView.kt b/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/TimelineView.kt index a73c724448..fdcf3037b6 100644 --- a/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/TimelineView.kt +++ b/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/TimelineView.kt @@ -42,7 +42,6 @@ import androidx.compose.material.icons.filled.ArrowDownward import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.FloatingActionButton import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -79,6 +78,7 @@ import io.element.android.features.messages.timeline.model.content.TimelineItemT import io.element.android.features.messages.timeline.model.content.TimelineItemUnknownContent import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.AvatarData +import io.element.android.libraries.designsystem.theme.ElementTheme import io.element.android.libraries.designsystem.utils.PairCombinedPreviewParameter import io.element.android.libraries.matrix.core.EventId import kotlinx.collections.immutable.ImmutableList @@ -267,7 +267,7 @@ private fun MessageSenderInformation( } Text( text = sender, - style = MaterialTheme.typography.titleMedium, + style = ElementTheme.typography.titleMedium, modifier = Modifier .alignBy(LastBaseline) ) @@ -326,8 +326,8 @@ internal fun BoxScope.TimelineScrollHelper( modifier = Modifier .align(Alignment.BottomCenter) .size(40.dp), - containerColor = MaterialTheme.colorScheme.surfaceVariant, - contentColor = MaterialTheme.colorScheme.onSurfaceVariant + containerColor = ElementTheme.colors.surfaceVariant, + contentColor = ElementTheme.colors.onSurfaceVariant ) { Icon(Icons.Default.ArrowDownward, "") } @@ -345,7 +345,7 @@ internal fun TimelineLoadingMoreIndicator() { ) { CircularProgressIndicator( strokeWidth = 2.dp, - color = MaterialTheme.colorScheme.primary + color = ElementTheme.colors.primary ) } } diff --git a/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/components/MessageEventBubble.kt b/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/components/MessageEventBubble.kt index b8922be78c..ddf2a66105 100644 --- a/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/components/MessageEventBubble.kt +++ b/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/components/MessageEventBubble.kt @@ -23,14 +23,14 @@ import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.widthIn import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.ripple.rememberRipple -import androidx.compose.material3.Surface import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Shape import androidx.compose.ui.unit.dp import io.element.android.features.messages.timeline.model.MessagesItemGroupPosition -import io.element.android.libraries.designsystem.LocalExtendedColors +import io.element.android.libraries.designsystem.theme.components.ElementSurface +import io.element.android.libraries.designsystem.theme.ElementTheme private val BUBBLE_RADIUS = 16.dp @@ -82,16 +82,16 @@ fun MessageEventBubble( } val backgroundBubbleColor = if (isHighlighted) { - LocalExtendedColors.current.messageHighlightedBackground + ElementTheme.colors.messageHighlightedBackground } else { if (isMine) { - LocalExtendedColors.current.messageFromMeBackground + ElementTheme.colors.messageFromMeBackground } else { - LocalExtendedColors.current.messageFromOtherBackground + ElementTheme.colors.messageFromOtherBackground } } val bubbleShape = bubbleShape() - Surface( + ElementSurface( modifier = modifier .widthIn(min = 80.dp) .offsetForItem() diff --git a/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/components/TimelineItemImageView.kt b/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/components/TimelineItemImageView.kt index e6548a71e8..cce7e21896 100644 --- a/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/components/TimelineItemImageView.kt +++ b/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/components/TimelineItemImageView.kt @@ -22,7 +22,6 @@ import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.saveable.rememberSaveable @@ -34,6 +33,7 @@ import androidx.compose.ui.platform.LocalContext import coil.compose.AsyncImage import coil.request.ImageRequest import io.element.android.features.messages.timeline.model.content.TimelineItemImageContent +import io.element.android.libraries.designsystem.theme.ElementTheme @Composable fun TimelineItemImageView( @@ -60,7 +60,7 @@ fun TimelineItemImageView( AsyncImage( model = model, contentDescription = null, - placeholder = ColorPainter(MaterialTheme.colorScheme.surfaceVariant), + placeholder = ColorPainter(ElementTheme.colors.surfaceVariant), contentScale = ContentScale.Crop, onSuccess = { isLoading.value = false }, ) diff --git a/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/components/TimelineItemInformativeView.kt b/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/components/TimelineItemInformativeView.kt index 9806bc05c8..40499798ee 100644 --- a/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/components/TimelineItemInformativeView.kt +++ b/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/components/TimelineItemInformativeView.kt @@ -21,7 +21,6 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.material3.Icon -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -30,6 +29,7 @@ import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import io.element.android.libraries.designsystem.theme.ElementTheme @Composable fun TimelineItemInformativeView( @@ -44,14 +44,14 @@ fun TimelineItemInformativeView( ) { Icon( imageVector = icon, - tint = MaterialTheme.colorScheme.secondary, + tint = ElementTheme.colors.secondary, contentDescription = iconDescription, modifier = Modifier.size(16.dp) ) Spacer(modifier = Modifier.width(4.dp)) Text( fontStyle = FontStyle.Italic, - color = MaterialTheme.colorScheme.secondary, + color = ElementTheme.colors.secondary, fontSize = 14.sp, text = text ) diff --git a/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/components/TimelineItemReactionsView.kt b/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/components/TimelineItemReactionsView.kt index b061f02f3d..4a8ac852b0 100644 --- a/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/components/TimelineItemReactionsView.kt +++ b/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/components/TimelineItemReactionsView.kt @@ -23,8 +23,6 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CornerSize import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -34,6 +32,8 @@ import androidx.compose.ui.unit.sp import com.google.accompanist.flowlayout.FlowRow import io.element.android.features.messages.timeline.model.AggregatedReaction import io.element.android.features.messages.timeline.model.TimelineItemReactions +import io.element.android.libraries.designsystem.theme.components.ElementSurface +import io.element.android.libraries.designsystem.theme.ElementTheme @Composable fun TimelineItemReactionsView( @@ -54,10 +54,10 @@ fun TimelineItemReactionsView( @Composable fun MessagesReactionButton(reaction: AggregatedReaction, modifier: Modifier = Modifier) { - Surface( + ElementSurface( modifier = modifier, - color = MaterialTheme.colorScheme.surfaceVariant, - border = BorderStroke(2.dp, MaterialTheme.colorScheme.background), + color = ElementTheme.colors.surfaceVariant, + border = BorderStroke(2.dp, ElementTheme.colors.background), shape = RoundedCornerShape(corner = CornerSize(12.dp)), ) { Row( @@ -66,7 +66,7 @@ fun MessagesReactionButton(reaction: AggregatedReaction, modifier: Modifier = Mo ) { Text(text = reaction.key, fontSize = 12.sp) Spacer(modifier = Modifier.width(4.dp)) - Text(text = reaction.count, color = MaterialTheme.colorScheme.secondary, fontSize = 12.sp) + Text(text = reaction.count, color = ElementTheme.colors.secondary, fontSize = 12.sp) } } } diff --git a/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/components/html/HtmlDocument.kt b/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/components/html/HtmlDocument.kt index 21a7cac714..092f503b67 100644 --- a/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/components/html/HtmlDocument.kt +++ b/features/messages/src/main/kotlin/io/element/android/features/messages/timeline/components/html/HtmlDocument.kt @@ -25,10 +25,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.InlineTextContent import androidx.compose.foundation.text.appendInlineContent -import androidx.compose.material3.ColorScheme import androidx.compose.material3.LocalTextStyle -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier @@ -49,6 +46,9 @@ import androidx.compose.ui.unit.sp import com.google.accompanist.flowlayout.FlowRow import io.element.android.libraries.designsystem.LinkColor import io.element.android.libraries.designsystem.components.ClickableLinkText +import io.element.android.libraries.designsystem.theme.components.ElementSurface +import io.element.android.libraries.designsystem.theme.ElementColors +import io.element.android.libraries.designsystem.theme.ElementTheme import io.element.android.libraries.matrix.permalink.PermalinkData import io.element.android.libraries.matrix.permalink.PermalinkParser import kotlinx.collections.immutable.persistentMapOf @@ -214,7 +214,7 @@ private fun HtmlInline( ) { Box(modifier) { val styledText = buildAnnotatedString { - appendInlineElement(element, MaterialTheme.colorScheme) + appendInlineElement(element, ElementTheme.colors) } HtmlText( text = styledText, @@ -232,7 +232,7 @@ private fun HtmlPreformatted( ) { val isCode = pre.firstElementChild()?.normalName() == "code" val backgroundColor = - if (isCode) MaterialTheme.colorScheme.codeBackground() else Color.Unspecified + if (isCode) ElementTheme.colors.codeBackground() else Color.Unspecified Box( modifier .background(color = backgroundColor) @@ -255,7 +255,7 @@ private fun HtmlParagraph( ) { Box(modifier) { val styledText = buildAnnotatedString { - appendInlineChildrenElements(paragraph.childNodes(), MaterialTheme.colorScheme) + appendInlineChildrenElements(paragraph.childNodes(), ElementTheme.colors) } HtmlText( text = styledText, onClick = onTextClicked, @@ -272,7 +272,7 @@ private fun HtmlBlockquote( onTextClicked: () -> Unit = {}, onTextLongClicked: () -> Unit = {}, ) { - val color = MaterialTheme.colorScheme.onBackground + val color = ElementTheme.colors.onBackground Box( modifier = modifier .drawBehind { @@ -287,7 +287,7 @@ private fun HtmlBlockquote( ) { val text = buildAnnotatedString { withStyle(style = SpanStyle(fontStyle = FontStyle.Italic)) { - appendInlineChildrenElements(blockquote.childNodes(), MaterialTheme.colorScheme) + appendInlineChildrenElements(blockquote.childNodes(), ElementTheme.colors) } } HtmlText( @@ -306,19 +306,19 @@ private fun HtmlHeading( onTextLongClicked: () -> Unit = {}, ) { val style = when (heading.normalName()) { - "h1" -> MaterialTheme.typography.headlineLarge.copy(fontSize = 30.sp) - "h2" -> MaterialTheme.typography.headlineLarge.copy(fontSize = 26.sp) - "h3" -> MaterialTheme.typography.headlineMedium.copy(fontSize = 22.sp) - "h4" -> MaterialTheme.typography.headlineMedium.copy(fontSize = 18.sp) - "h5" -> MaterialTheme.typography.headlineSmall.copy(fontSize = 14.sp) - "h6" -> MaterialTheme.typography.headlineSmall.copy(fontSize = 12.sp) + "h1" -> ElementTheme.typography.headlineLarge.copy(fontSize = 30.sp) + "h2" -> ElementTheme.typography.headlineLarge.copy(fontSize = 26.sp) + "h3" -> ElementTheme.typography.headlineMedium.copy(fontSize = 22.sp) + "h4" -> ElementTheme.typography.headlineMedium.copy(fontSize = 18.sp) + "h5" -> ElementTheme.typography.headlineSmall.copy(fontSize = 14.sp) + "h6" -> ElementTheme.typography.headlineSmall.copy(fontSize = 12.sp) else -> { return } } Box(modifier) { val text = buildAnnotatedString { - appendInlineChildrenElements(heading.childNodes(), MaterialTheme.colorScheme) + appendInlineChildrenElements(heading.childNodes(), ElementTheme.colors) } HtmlText( text = text, @@ -340,11 +340,11 @@ private fun HtmlMxReply( ) { val blockquote = mxReply.childNodes().firstOrNull() ?: return val shape = RoundedCornerShape(12.dp) - Surface( + ElementSurface( modifier = modifier .padding(bottom = 4.dp) .offset(x = -(8.dp)), - color = MaterialTheme.colorScheme.background, + color = ElementTheme.colors.background, shape = shape, ) { val text = buildAnnotatedString { @@ -354,7 +354,7 @@ private fun HtmlMxReply( withStyle( style = SpanStyle( fontSize = 12.sp, - color = MaterialTheme.colorScheme.secondary + color = ElementTheme.colors.secondary ) ) { append(blockquoteNode.text()) @@ -462,13 +462,13 @@ private fun HtmlListItems( } } -private fun ColorScheme.codeBackground(): Color { +private fun ElementColors.codeBackground(): Color { return background.copy(alpha = 0.3f) } private fun AnnotatedString.Builder.appendInlineChildrenElements( childNodes: List, - colors: ColorScheme + colors: ElementColors ) { for (node in childNodes) { when (node) { @@ -482,7 +482,7 @@ private fun AnnotatedString.Builder.appendInlineChildrenElements( } } -private fun AnnotatedString.Builder.appendInlineElement(element: Element, colors: ColorScheme) { +private fun AnnotatedString.Builder.appendInlineElement(element: Element, colors: ElementColors) { when (element.normalName()) { "br" -> { append('\n') diff --git a/features/onboarding/src/main/kotlin/io/element/android/features/onboarding/OnBoardingScreen.kt b/features/onboarding/src/main/kotlin/io/element/android/features/onboarding/OnBoardingScreen.kt index f0f524cddf..684d7a02ce 100644 --- a/features/onboarding/src/main/kotlin/io/element/android/features/onboarding/OnBoardingScreen.kt +++ b/features/onboarding/src/main/kotlin/io/element/android/features/onboarding/OnBoardingScreen.kt @@ -27,8 +27,6 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -49,7 +47,9 @@ import com.google.accompanist.pager.ExperimentalPagerApi import com.google.accompanist.pager.HorizontalPager import com.google.accompanist.pager.HorizontalPagerIndicator import com.google.accompanist.pager.rememberPagerState -import io.element.android.libraries.designsystem.components.VectorButton +import io.element.android.libraries.designsystem.theme.ElementTheme +import io.element.android.libraries.designsystem.theme.components.ElementButton +import io.element.android.libraries.designsystem.theme.components.ElementSurface import io.element.android.libraries.testtags.TestTags import io.element.android.libraries.testtags.testTag import kotlinx.coroutines.delay @@ -67,9 +67,9 @@ fun OnBoardingScreen( val carrouselState = remember { SplashCarouselStateFactory().create() } val nbOfPages = carrouselState.items.size var key by remember { mutableStateOf(false) } - Surface( + ElementSurface( modifier = modifier, - color = MaterialTheme.colorScheme.background, + color = ElementTheme.colors.background, ) { Box( modifier = Modifier @@ -109,20 +109,7 @@ fun OnBoardingScreen( .align(CenterHorizontally) .padding(16.dp), ) - /* - VectorButton( - text = "CREATE ACCOUNT", - onClick = { - onSignUp() - }, - enabled = true, - modifier = Modifier - .align(CenterHorizontally) - .padding(top = 16.dp) - ) - */ - VectorButton( - text = stringResource(id = StringR.string.login_splash_submit), + ElementButton( onClick = { onSignIn() }, @@ -131,7 +118,9 @@ fun OnBoardingScreen( .align(CenterHorizontally) .testTag(TestTags.onBoardingSignIn) .padding(top = 16.dp) - ) + ) { + Text(text = stringResource(id = StringR.string.login_splash_submit)) + } } } } diff --git a/features/rageshake/src/main/kotlin/io/element/android/features/rageshake/bugreport/BugReportView.kt b/features/rageshake/src/main/kotlin/io/element/android/features/rageshake/bugreport/BugReportView.kt index 8a32f1ac7a..3fd7810b73 100644 --- a/features/rageshake/src/main/kotlin/io/element/android/features/rageshake/bugreport/BugReportView.kt +++ b/features/rageshake/src/main/kotlin/io/element/android/features/rageshake/bugreport/BugReportView.kt @@ -26,12 +26,9 @@ import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.verticalScroll -import androidx.compose.material3.Button import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField -import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -54,6 +51,8 @@ import io.element.android.libraries.architecture.Async import io.element.android.libraries.designsystem.components.LabelledCheckbox import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog import io.element.android.libraries.designsystem.components.form.textFieldState +import io.element.android.libraries.designsystem.theme.components.ElementButton +import io.element.android.libraries.designsystem.theme.components.ElementSurface import io.element.android.libraries.designsystem.utils.LogCompositions import io.element.android.libraries.ui.strings.R as StringR @@ -73,9 +72,8 @@ fun BugReportView( } return } - Surface( + ElementSurface( modifier = modifier, - color = MaterialTheme.colorScheme.background, ) { Box( modifier = Modifier @@ -185,7 +183,7 @@ fun BugReportView( } } // Submit - Button( + ElementButton( onClick = { eventSink(BugReportEvents.SendBugReport) }, enabled = state.submitEnabled, modifier = Modifier diff --git a/features/roomlist/src/main/kotlin/io/element/android/features/roomlist/RoomListView.kt b/features/roomlist/src/main/kotlin/io/element/android/features/roomlist/RoomListView.kt index 8a67b649e3..8aff881f24 100644 --- a/features/roomlist/src/main/kotlin/io/element/android/features/roomlist/RoomListView.kt +++ b/features/roomlist/src/main/kotlin/io/element/android/features/roomlist/RoomListView.kt @@ -24,7 +24,6 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.Scaffold import androidx.compose.material3.TopAppBarDefaults import androidx.compose.material3.rememberTopAppBarState import androidx.compose.runtime.Composable @@ -43,6 +42,7 @@ import io.element.android.features.roomlist.model.RoomListRoomSummary import io.element.android.features.roomlist.model.RoomListState import io.element.android.features.roomlist.model.stubbedRoomSummaries import io.element.android.libraries.designsystem.components.avatar.AvatarData +import io.element.android.libraries.designsystem.theme.components.ElementScaffold import io.element.android.libraries.designsystem.utils.LogCompositions import io.element.android.libraries.matrix.core.RoomId import io.element.android.libraries.matrix.core.UserId @@ -117,7 +117,7 @@ fun RoomListView( } } - Scaffold( + ElementScaffold( modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection), topBar = { RoomListTopBar( @@ -125,11 +125,15 @@ fun RoomListView( filter = filter, onFilterChanged = onFilterChanged, onOpenSettings = onOpenSettings, - scrollBehavior = scrollBehavior + scrollBehavior = scrollBehavior, + modifier = Modifier, ) }, content = { padding -> - Column(modifier = Modifier.padding(padding)) { + Column( + modifier = Modifier + .padding(padding) + ) { LazyColumn( modifier = Modifier .weight(1f) diff --git a/features/roomlist/src/main/kotlin/io/element/android/features/roomlist/components/RoomListTopBar.kt b/features/roomlist/src/main/kotlin/io/element/android/features/roomlist/components/RoomListTopBar.kt index c7f077374f..a2549a8f9f 100644 --- a/features/roomlist/src/main/kotlin/io/element/android/features/roomlist/components/RoomListTopBar.kt +++ b/features/roomlist/src/main/kotlin/io/element/android/features/roomlist/components/RoomListTopBar.kt @@ -29,7 +29,6 @@ import androidx.compose.material.icons.filled.Settings import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MediumTopAppBar import androidx.compose.material3.Text import androidx.compose.material3.TextField @@ -54,6 +53,9 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.sp import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.form.textFieldState +import io.element.android.libraries.designsystem.theme.ElementTheme +import io.element.android.libraries.designsystem.theme.components.ElementMediumAppBar +import io.element.android.libraries.designsystem.theme.components.ElementTopAppBar import io.element.android.libraries.designsystem.utils.LogCompositions import io.element.android.libraries.matrix.ui.model.MatrixUser import io.element.android.libraries.ui.strings.R as StringR @@ -64,7 +66,8 @@ fun RoomListTopBar( filter: String, onFilterChanged: (String) -> Unit, onOpenSettings: () -> Unit, - scrollBehavior: TopAppBarScrollBehavior + scrollBehavior: TopAppBarScrollBehavior, + modifier: Modifier = Modifier, ) { LogCompositions( tag = "RoomListScreen", @@ -87,6 +90,7 @@ fun RoomListTopBar( onFilterChanged = onFilterChanged, onCloseClicked = ::closeFilter, scrollBehavior = scrollBehavior, + modifier = modifier, ) } else { DefaultRoomListTopBar( @@ -96,6 +100,7 @@ fun RoomListTopBar( searchWidgetStateIsOpened = true }, scrollBehavior = scrollBehavior, + modifier = modifier, ) } } @@ -110,7 +115,7 @@ fun SearchRoomListTopBar( ) { var filterState by textFieldState(stateValue = text) val focusRequester = remember { FocusRequester() } - TopAppBar( + ElementTopAppBar( modifier = modifier .nestedScroll(scrollBehavior.nestedScrollConnection), title = { @@ -129,7 +134,7 @@ fun SearchRoomListTopBar( placeholder = { Text( text = "Search", - color = MaterialTheme.colorScheme.onBackground.copy(alpha = ContentAlpha.medium) + color = ElementTheme.colors.onBackground.copy(alpha = ContentAlpha.medium) ) }, singleLine = true, @@ -143,15 +148,15 @@ fun SearchRoomListTopBar( Icon( imageVector = Icons.Default.Close, contentDescription = "clear", - tint = MaterialTheme.colorScheme.onBackground + tint = ElementTheme.colors.onBackground ) } } }, colors = TextFieldDefaults.textFieldColors( - textColor = MaterialTheme.colorScheme.onBackground, + textColor = ElementTheme.colors.onBackground, containerColor = Color.Transparent, - cursorColor = MaterialTheme.colorScheme.onBackground.copy(alpha = ContentAlpha.medium), + cursorColor = ElementTheme.colors.onBackground.copy(alpha = ContentAlpha.medium), focusedIndicatorColor = Color.Transparent, unfocusedIndicatorColor = Color.Transparent, disabledIndicatorColor = Color.Transparent @@ -167,7 +172,7 @@ fun SearchRoomListTopBar( Icon( imageVector = Icons.Default.ArrowBack, contentDescription = "close", - tint = MaterialTheme.colorScheme.onBackground + tint = ElementTheme.colors.onBackground ) } }, @@ -182,10 +187,11 @@ private fun DefaultRoomListTopBar( matrixUser: MatrixUser?, onOpenSettings: () -> Unit, onSearchClicked: () -> Unit, - scrollBehavior: TopAppBarScrollBehavior + scrollBehavior: TopAppBarScrollBehavior, + modifier: Modifier = Modifier, ) { - MediumTopAppBar( - modifier = Modifier + ElementMediumAppBar( + modifier = modifier .nestedScroll(scrollBehavior.nestedScrollConnection), title = { Text( diff --git a/features/roomlist/src/main/kotlin/io/element/android/features/roomlist/components/RoomSummaryRow.kt b/features/roomlist/src/main/kotlin/io/element/android/features/roomlist/components/RoomSummaryRow.kt index 7b561d9054..05494f95c3 100644 --- a/features/roomlist/src/main/kotlin/io/element/android/features/roomlist/components/RoomSummaryRow.kt +++ b/features/roomlist/src/main/kotlin/io/element/android/features/roomlist/components/RoomSummaryRow.kt @@ -31,7 +31,6 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.ripple.rememberRipple -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.remember @@ -54,6 +53,7 @@ import androidx.compose.ui.unit.sp import com.google.accompanist.placeholder.material.placeholder import io.element.android.features.roomlist.model.RoomListRoomSummary import io.element.android.libraries.designsystem.components.avatar.Avatar +import io.element.android.libraries.designsystem.theme.ElementTheme private val minHeight = 72.dp @@ -117,7 +117,7 @@ internal fun DefaultRoomSummaryRow( Text( modifier = Modifier.placeholder(room.isPlaceholder, shape = TextPlaceholderShape), text = room.lastMessage?.toString().orEmpty(), - color = MaterialTheme.colorScheme.secondary, + color = ElementTheme.colors.secondary, fontSize = 14.sp, maxLines = 1, overflow = TextOverflow.Ellipsis @@ -132,11 +132,11 @@ internal fun DefaultRoomSummaryRow( modifier = Modifier.placeholder(room.isPlaceholder, shape = TextPlaceholderShape), fontSize = 12.sp, text = room.timestamp ?: "", - color = MaterialTheme.colorScheme.secondary, + color = ElementTheme.colors.secondary, ) Spacer(Modifier.size(4.dp)) val unreadIndicatorColor = - if (room.hasUnread) MaterialTheme.colorScheme.primary else Color.Transparent + if (room.hasUnread) ElementTheme.colors.primary else Color.Transparent Box( modifier = Modifier .size(12.dp) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/ColorUtil.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/ColorUtil.kt index b15bfc49db..def4c49e89 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/ColorUtil.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/ColorUtil.kt @@ -16,15 +16,15 @@ package io.element.android.libraries.designsystem -import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.ui.graphics.Color +import io.element.android.libraries.designsystem.theme.ElementTheme @Composable fun Boolean.toEnabledColor(): Color { return if (this) { - MaterialTheme.colorScheme.primary + ElementTheme.colors.primary } else { - MaterialTheme.colorScheme.secondary + ElementTheme.colors.secondary } } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/ExtendedColors.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/ExtendedColors.kt deleted file mode 100644 index 9cdda9cb73..0000000000 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/ExtendedColors.kt +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2023 New Vector Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.element.android.libraries.designsystem - -import androidx.compose.runtime.Immutable -import androidx.compose.ui.graphics.Color - -@Immutable -data class ExtendedColors( - val messageFromMeBackground: Color, - val messageFromOtherBackground: Color, - val messageHighlightedBackground: Color, -) - -internal val extendedColorsLight = ExtendedColors( - messageFromMeBackground = SystemGrey5Light, - messageFromOtherBackground = SystemGrey6Light, - messageHighlightedBackground = Azure, -) - -internal val extendedColorsDark = ExtendedColors( - messageFromMeBackground = SystemGrey5Dark, - messageFromOtherBackground = SystemGrey6Dark, - messageHighlightedBackground = Azure, -) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/Theme.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/Theme.kt deleted file mode 100644 index 09bb595599..0000000000 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/Theme.kt +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2023 New Vector Ltd - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.element.android.libraries.designsystem - -import android.os.Build -import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.darkColorScheme -import androidx.compose.material3.dynamicDarkColorScheme -import androidx.compose.material3.dynamicLightColorScheme -import androidx.compose.material3.lightColorScheme -import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider -import androidx.compose.runtime.SideEffect -import androidx.compose.runtime.compositionLocalOf -import androidx.compose.runtime.staticCompositionLocalOf -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalContext -import com.google.accompanist.systemuicontroller.rememberSystemUiController - -private val DarkColorScheme = darkColorScheme( - primary = Color.White, - secondary = DarkGrey, - tertiary = Color.White, - background = Color.Black, - onBackground = Color.White, - surface = Color.Black, - surfaceVariant = SystemGrey5Dark, - onSurface = Color.White, - onSurfaceVariant = Color.White, -) - -private val LightColorScheme = lightColorScheme( - primary = Color.Black, - secondary = LightGrey, - tertiary = Color.Black, - background = Color.White, - onBackground = Color.Black, - surface = Color.White, - surfaceVariant = SystemGrey5Light, - onSurface = Color.Black, - onSurfaceVariant = Color.Black, - - /* Other default colors to override - background = Color(0xFFFFFBFE), - surface = Color(0xFFFFFBFE), - onPrimary = Color.White, - onSecondary = Color.White, - onTertiary = Color.White, - onBackground = Color(0xFF1C1B1F), - onSurface = Color(0xFF1C1B1F), - */ -) - -@Suppress("CompositionLocalAllowlist") -val LocalIsDarkTheme = compositionLocalOf { error("Not defined") } - -val LocalExtendedColors = staticCompositionLocalOf { - ExtendedColors( - messageFromMeBackground = Color.Unspecified, - messageFromOtherBackground = Color.Unspecified, - messageHighlightedBackground = Color.Unspecified, - ) -} - -@Composable -fun ElementXTheme( - darkTheme: Boolean = isSystemInDarkTheme(), - // Dynamic color is available on Android 12+ - dynamicColor: Boolean = false, - content: @Composable () -> Unit -) { - val colorScheme = when { - dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { - val context = LocalContext.current - if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) - } - darkTheme -> DarkColorScheme - else -> LightColorScheme - } - val systemUiController = rememberSystemUiController() - val useDarkIcons = !darkTheme - - SideEffect { - systemUiController.setStatusBarColor( - color = colorScheme.background - ) - systemUiController.setSystemBarsColor( - color = Color.Transparent, - darkIcons = useDarkIcons - ) - } - - val extendedColors = if (darkTheme) extendedColorsDark else extendedColorsLight - - CompositionLocalProvider( - LocalIsDarkTheme provides darkTheme, - LocalExtendedColors provides extendedColors, - ) { - MaterialTheme( - colorScheme = colorScheme, - typography = Typography, - content = content - ) - } -} diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/Type.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/Type.kt index 6e97bfa4fb..50d5b7d1fd 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/Type.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/Type.kt @@ -23,48 +23,8 @@ import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.sp -import com.airbnb.android.showkase.annotation.ShowkaseTypography - -@ShowkaseTypography(name = "Body Large", group = "Element") -val bodyLarge = TextStyle( - fontFamily = FontFamily.Default, - fontWeight = FontWeight.Normal, - fontSize = 16.sp, - lineHeight = 24.sp, - letterSpacing = 0.5.sp -) - -@ShowkaseTypography(name = "Headline Small", group = "Element") -val headlineSmall = TextStyle( - fontFamily = FontFamily.Default, - fontWeight = FontWeight.Bold, - fontSize = 32.sp, - lineHeight = 24.sp, - letterSpacing = 0.5.sp -) - -// Set of Material typography styles to start with -val Typography = Typography( - bodyLarge = bodyLarge, - headlineSmall = headlineSmall, - /* Other default text styles to override - titleLarge = TextStyle( - fontFamily = FontFamily.Default, - fontWeight = FontWeight.Normal, - fontSize = 22.sp, - lineHeight = 28.sp, - letterSpacing = 0.sp - ), - labelSmall = TextStyle( - fontFamily = FontFamily.Default, - fontWeight = FontWeight.Medium, - fontSize = 11.sp, - lineHeight = 16.sp, - letterSpacing = 0.5.sp - ) - */ -) +// TODO Remove object ElementTextStyles { object Bold { diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LabelledCheckbox.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LabelledCheckbox.kt index f1ad5738ac..90646930ec 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LabelledCheckbox.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/LabelledCheckbox.kt @@ -24,6 +24,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview +import io.element.android.libraries.designsystem.theme.components.ElementCheckbox @Composable fun LabelledCheckbox( @@ -37,7 +38,7 @@ fun LabelledCheckbox( modifier = modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically ) { - Checkbox( + ElementCheckbox( checked = checked, onCheckedChange = onCheckedChange, enabled = enabled, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/ProgressDialog.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/ProgressDialog.kt index 8bcc77226b..5b7229cd87 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/ProgressDialog.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/ProgressDialog.kt @@ -23,7 +23,6 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.CircularProgressIndicator -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -32,6 +31,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.DialogProperties +import io.element.android.libraries.designsystem.theme.ElementTheme @Composable fun ProgressDialog( @@ -48,19 +48,19 @@ fun ProgressDialog( modifier = modifier .fillMaxWidth() .background( - color = MaterialTheme.colorScheme.onBackground, + color = ElementTheme.colors.onBackground, shape = RoundedCornerShape(8.dp) ) ) { Column(horizontalAlignment = Alignment.CenterHorizontally) { CircularProgressIndicator( modifier = Modifier.padding(16.dp), - color = MaterialTheme.colorScheme.background + color = ElementTheme.colors.background ) if (!text.isNullOrBlank()) { Text( text = text, - color = MaterialTheme.colorScheme.background, + color = ElementTheme.colors.background, modifier = Modifier.padding(16.dp) ) } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/ConfirmationDialog.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/ConfirmationDialog.kt index 6059b6b998..4d36007f1f 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/ConfirmationDialog.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/ConfirmationDialog.kt @@ -22,13 +22,18 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material3.AlertDialog -import androidx.compose.material3.Button +import androidx.compose.material3.AlertDialogDefaults import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Shape import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp +import io.element.android.libraries.designsystem.theme.components.ElementButton +import io.element.android.libraries.designsystem.theme.ElementTheme import io.element.android.libraries.ui.strings.R as StringR @Composable @@ -43,6 +48,12 @@ fun ConfirmationDialog( onCancelClicked: () -> Unit = {}, onThirdButtonClicked: () -> Unit = {}, onDismiss: () -> Unit = {}, + shape: Shape = AlertDialogDefaults.shape, + containerColor: Color = ElementTheme.colors.surfaceVariant, + iconContentColor: Color = ElementTheme.colors.onSurfaceVariant, + titleContentColor: Color = ElementTheme.colors.onSurfaceVariant, + textContentColor: Color = ElementTheme.colors.onSurfaceVariant, + tonalElevation: Dp = AlertDialogDefaults.TonalElevation, ) { AlertDialog( modifier = modifier, @@ -59,7 +70,7 @@ fun ConfirmationDialog( horizontalArrangement = Arrangement.Center ) { Column { - Button( + ElementButton( modifier = Modifier.fillMaxWidth(), onClick = { onCancelClicked() @@ -67,7 +78,7 @@ fun ConfirmationDialog( Text(cancelText) } if (thirdButtonText != null) { - Button( + ElementButton( modifier = Modifier.fillMaxWidth(), onClick = { onThirdButtonClicked() @@ -83,7 +94,7 @@ fun ConfirmationDialog( modifier = Modifier.padding(all = 8.dp), horizontalArrangement = Arrangement.Center ) { - Button( + ElementButton( modifier = Modifier.fillMaxWidth(), onClick = { onSubmitClicked() @@ -93,6 +104,12 @@ fun ConfirmationDialog( } } }, + shape = shape, + containerColor = containerColor, + iconContentColor = iconContentColor, + titleContentColor = titleContentColor, + textContentColor = textContentColor, + tonalElevation = tonalElevation, ) } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/ErrorDialog.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/ErrorDialog.kt index 99e473fdbd..c1ca38b11c 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/ErrorDialog.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/dialogs/ErrorDialog.kt @@ -21,13 +21,18 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material3.AlertDialog -import androidx.compose.material3.Button +import androidx.compose.material3.AlertDialogDefaults import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Shape import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp +import io.element.android.libraries.designsystem.theme.components.ElementButton +import io.element.android.libraries.designsystem.theme.ElementTheme import io.element.android.libraries.ui.strings.R as StringR @Composable @@ -37,6 +42,12 @@ fun ErrorDialog( title: String = stringResource(id = StringR.string.dialog_title_error), submitText: String = stringResource(id = StringR.string.ok), onDismiss: () -> Unit = {}, + shape: Shape = AlertDialogDefaults.shape, + containerColor: Color = ElementTheme.colors.surfaceVariant, + iconContentColor: Color = ElementTheme.colors.onSurfaceVariant, + titleContentColor: Color = ElementTheme.colors.onSurfaceVariant, + textContentColor: Color = ElementTheme.colors.onSurfaceVariant, + tonalElevation: Dp = AlertDialogDefaults.TonalElevation, ) { AlertDialog( modifier = modifier, @@ -52,7 +63,7 @@ fun ErrorDialog( modifier = Modifier.padding(all = 8.dp), horizontalArrangement = Arrangement.Center ) { - Button( + ElementButton( modifier = Modifier.fillMaxWidth(), onClick = { onDismiss() @@ -62,6 +73,12 @@ fun ErrorDialog( } } }, + shape = shape, + containerColor = containerColor, + iconContentColor = iconContentColor, + titleContentColor = titleContentColor, + textContentColor = textContentColor, + tonalElevation = tonalElevation, ) } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceCategory.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceCategory.kt index c9e6ac6740..65560e57f7 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceCategory.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceCategory.kt @@ -21,12 +21,12 @@ import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material3.Divider -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import io.element.android.libraries.designsystem.theme.ElementTheme @Composable fun PreferenceCategory( @@ -40,12 +40,12 @@ fun PreferenceCategory( ) { Divider( modifier = Modifier.padding(horizontal = 16.dp), - color = MaterialTheme.colorScheme.secondary, + color = ElementTheme.colors.secondary, thickness = 1.dp ) Text( modifier = Modifier.padding(top = 8.dp, start = 56.dp), - style = MaterialTheme.typography.titleSmall, + style = ElementTheme.typography.titleSmall, text = title ) content() diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceScreen.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceScreen.kt index 4b5f007506..948daace12 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceScreen.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceScreen.kt @@ -42,6 +42,8 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.sp +import io.element.android.libraries.designsystem.theme.components.ElementScaffold +import io.element.android.libraries.designsystem.theme.components.ElementTopAppBar @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -51,7 +53,7 @@ fun PreferenceView( onBackPressed: () -> Unit = {}, content: @Composable ColumnScope.() -> Unit, ) { - Scaffold( + ElementScaffold( modifier = modifier .fillMaxSize() .systemBarsPadding() @@ -85,7 +87,7 @@ fun PreferenceTopAppBar( modifier: Modifier = Modifier, onBackPressed: () -> Unit = {}, ) { - TopAppBar( + ElementTopAppBar( modifier = modifier, navigationIcon = { IconButton(onClick = onBackPressed) { diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceSlide.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceSlide.kt index aadb0ab236..244f257944 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceSlide.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceSlide.kt @@ -23,7 +23,6 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.defaultMinSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Slider import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -32,6 +31,8 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.tooling.preview.Preview import io.element.android.libraries.designsystem.components.preferences.components.PreferenceIcon +import io.element.android.libraries.designsystem.theme.ElementTheme +import io.element.android.libraries.designsystem.theme.components.ElementSlider import io.element.android.libraries.designsystem.toEnabledColor @Composable @@ -61,19 +62,19 @@ fun PreferenceSlide( ) { Text( modifier = Modifier.fillMaxWidth(), - style = MaterialTheme.typography.bodyLarge, + style = ElementTheme.typography.bodyLarge, color = enabled.toEnabledColor(), text = title ) summary?.let { Text( modifier = Modifier.fillMaxWidth(), - style = MaterialTheme.typography.bodyMedium, + style = ElementTheme.typography.bodyMedium, color = enabled.toEnabledColor(), text = summary ) } - Slider( + ElementSlider( value = value, steps = steps, onValueChange = onValueChange, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceSwitch.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceSwitch.kt index 68a402296c..47e32f409d 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceSwitch.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceSwitch.kt @@ -25,7 +25,6 @@ import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Announcement import androidx.compose.material3.Checkbox -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -33,6 +32,8 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.tooling.preview.Preview import io.element.android.libraries.designsystem.components.preferences.components.PreferenceIcon +import io.element.android.libraries.designsystem.theme.ElementTheme +import io.element.android.libraries.designsystem.theme.components.ElementCheckbox import io.element.android.libraries.designsystem.toEnabledColor @Composable @@ -61,11 +62,11 @@ fun PreferenceSwitch( ) Text( modifier = Modifier.weight(1f), - style = MaterialTheme.typography.bodyLarge, + style = ElementTheme.typography.bodyLarge, color = enabled.toEnabledColor(), text = title ) - Checkbox( + ElementCheckbox( modifier = Modifier.padding(end = preferencePaddingEnd), checked = isChecked, enabled = enabled, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceText.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceText.kt index bef45830e2..6f4c1598b7 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceText.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/preferences/PreferenceText.kt @@ -24,7 +24,6 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.BugReport -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -32,6 +31,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.tooling.preview.Preview import io.element.android.libraries.designsystem.components.preferences.components.PreferenceIcon +import io.element.android.libraries.designsystem.theme.ElementTheme @Composable fun PreferenceText( @@ -56,7 +56,7 @@ fun PreferenceText( modifier = Modifier .weight(1f) .padding(end = preferencePaddingEnd), - style = MaterialTheme.typography.bodyLarge, + style = ElementTheme.typography.bodyLarge, text = title ) } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/ColorsDark.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/ColorsDark.kt new file mode 100644 index 0000000000..19c7c2f49a --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/ColorsDark.kt @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.designsystem.theme + +import androidx.compose.ui.graphics.Color +import io.element.android.libraries.designsystem.Azure +import io.element.android.libraries.designsystem.DarkGrey +import io.element.android.libraries.designsystem.SystemGrey5Dark +import io.element.android.libraries.designsystem.SystemGrey6Dark + +fun elementColorsDark() = ElementColors( + primary = Color.White, + onPrimary = Color.Black, + secondary = DarkGrey, + text = Color.White, + background = Color.Black, + onBackground = Color.White, + surfaceVariant = SystemGrey5Dark, + onSurfaceVariant = Color.White, + messageFromMeBackground = SystemGrey5Dark, + messageFromOtherBackground = SystemGrey6Dark, + messageHighlightedBackground = Azure, + success = Color.Green, + error = Color.Red, + isLight = false, +) + +/* +private val DarkColorScheme = darkColorScheme( + primary = Color.White, + secondary = DarkGrey, + tertiary = Color.White, + background = Color.Black, + onBackground = Color.White, + surface = Color.Black, + surfaceVariant = SystemGrey5Dark, + onSurface = Color.White, +) + */ diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/ColorsLight.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/ColorsLight.kt new file mode 100644 index 0000000000..6d7c7f62ea --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/ColorsLight.kt @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.designsystem.theme + +import androidx.compose.ui.graphics.Color +import io.element.android.libraries.designsystem.Azure +import io.element.android.libraries.designsystem.LightGrey +import io.element.android.libraries.designsystem.SystemGrey5Light +import io.element.android.libraries.designsystem.SystemGrey6Light + +fun elementColorsLight() = ElementColors( + primary = Color.Black, + onPrimary = Color.White, + secondary = LightGrey, + text = Color.Black, + background = Color.White, + onBackground = Color.Black, + surfaceVariant = SystemGrey5Light, + onSurfaceVariant = Color.Black, + messageFromMeBackground = SystemGrey5Light, + messageFromOtherBackground = SystemGrey6Light, + messageHighlightedBackground = Azure, + success = Color.Green, + error = Color.Red, + isLight = true, +) + +/* +private val LightColorScheme = lightColorScheme( + primary = Color.Black, + secondary = LightGrey, + tertiary = Color.Black, + background = Color.White, + onBackground = Color.Black, + surface = Color.White, + surfaceVariant = SystemGrey5Light, + onSurface = Color.Black, + onSurfaceVariant = Color.Black, + + */ diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/ContentColor.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/ContentColor.kt new file mode 100644 index 0000000000..56df033d27 --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/ContentColor.kt @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.designsystem.components.color + +import androidx.compose.material3.LocalContentColor +import androidx.compose.runtime.Composable +import androidx.compose.runtime.ReadOnlyComposable +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.takeOrElse +import io.element.android.libraries.designsystem.theme.ElementColors +import io.element.android.libraries.designsystem.theme.ElementTheme + +@Composable +@ReadOnlyComposable +fun elementContentColorFor(backgroundColor: Color): Color { + return ElementTheme.colors.elementContentColorFor(backgroundColor).takeOrElse { + LocalContentColor.current + } +} + +fun ElementColors.elementContentColorFor(backgroundColor: Color): Color { + return when (backgroundColor) { + primary -> onPrimary + surfaceVariant -> onSurfaceVariant + background -> onBackground + else -> Color.Unspecified + } +} diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/ElementColors.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/ElementColors.kt new file mode 100644 index 0000000000..38da8e7816 --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/ElementColors.kt @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.designsystem.theme + +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.compose.ui.graphics.Color + +class ElementColors( + primary: Color, + onPrimary: Color, + secondary: Color, + text: Color, + background: Color, + onBackground: Color, + surfaceVariant: Color, + onSurfaceVariant: Color, + messageFromMeBackground: Color, + messageFromOtherBackground: Color, + messageHighlightedBackground: Color, + success: Color, + error: Color, + isLight: Boolean, +) { + var primary by mutableStateOf(primary) + private set + var onPrimary by mutableStateOf(onPrimary) + private set + var secondary by mutableStateOf(secondary) + private set + var text by mutableStateOf(text) + private set + var success by mutableStateOf(success) + private set + var error by mutableStateOf(error) + private set + var background by mutableStateOf(background) + private set + var onBackground by mutableStateOf(onBackground) + private set + var surfaceVariant by mutableStateOf(surfaceVariant) + private set + var onSurfaceVariant by mutableStateOf(onSurfaceVariant) + private set + var messageFromMeBackground by mutableStateOf(messageFromMeBackground) + private set + var messageFromOtherBackground by mutableStateOf(messageFromOtherBackground) + private set + var messageHighlightedBackground by mutableStateOf(messageHighlightedBackground) + private set + + var isLight by mutableStateOf(isLight) + private set + + fun copy( + primary: Color = this.primary, + onPrimary: Color = this.onPrimary, + secondary: Color = this.secondary, + text: Color = this.text, + background: Color = this.background, + onBackground: Color = this.onBackground, + surfaceVariant: Color = this.surfaceVariant, + onSurfaceVariant: Color = this.onSurfaceVariant, + messageFromMeBackground: Color = this.messageFromMeBackground, + messageFromOtherBackground: Color = this.messageFromOtherBackground, + messageHighlightedBackground: Color = this.messageHighlightedBackground, + success: Color = this.success, + error: Color = this.error, + isLight: Boolean = this.isLight, + ) = ElementColors( + primary = primary, + onPrimary = onPrimary, + secondary = secondary, + text = text, + background = background, + onBackground = onBackground, + surfaceVariant = surfaceVariant, + onSurfaceVariant = onSurfaceVariant, + messageFromMeBackground = messageFromMeBackground, + messageFromOtherBackground = messageFromOtherBackground, + messageHighlightedBackground = messageHighlightedBackground, + success = success, + error = error, + isLight = isLight, + ) + + fun updateColorsFrom(other: ElementColors) { + primary = other.primary + onPrimary = other.onPrimary + secondary = other.secondary + text = other.text + success = other.success + background = other.background + onBackground = other.onBackground + surfaceVariant = other.surfaceVariant + onSurfaceVariant = other.onSurfaceVariant + messageFromMeBackground = other.messageFromMeBackground + messageFromOtherBackground = other.messageFromOtherBackground + messageHighlightedBackground = other.messageHighlightedBackground + error = other.error + isLight = other.isLight + } +} diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/VectorButton.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/ElementSpaces.kt similarity index 52% rename from libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/VectorButton.kt rename to libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/ElementSpaces.kt index 928e83cfa4..e5f2236cf0 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/VectorButton.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/ElementSpaces.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 New Vector Ltd + * Copyright (c) 2023 New Vector Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,20 +14,14 @@ * limitations under the License. */ -package io.element.android.libraries.designsystem.components +package io.element.android.libraries.designsystem.theme -import androidx.compose.material3.Button -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp -@Composable -fun VectorButton(text: String, enabled: Boolean, onClick: () -> Unit, modifier: Modifier = Modifier) { - Button( - onClick = onClick, - enabled = enabled, - modifier = modifier - ) { - Text(text = text) - } -} +data class ElementSpaces( + val small: Dp = 4.dp, + val medium: Dp = 8.dp, + val large: Dp = 16.dp, + val extraLarge: Dp = 40.dp, +) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/ElementTheme.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/ElementTheme.kt new file mode 100644 index 0000000000..5281888b17 --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/ElementTheme.kt @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.designsystem.theme + +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material.ProvideTextStyle +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.ReadOnlyComposable +import androidx.compose.runtime.SideEffect +import androidx.compose.runtime.remember +import androidx.compose.runtime.staticCompositionLocalOf +import androidx.compose.ui.graphics.Color +import com.google.accompanist.systemuicontroller.rememberSystemUiController + +/** + * Inspired from https://medium.com/@lucasyujideveloper/54cbcbde1ace + */ +object ElementTheme { + val colors: ElementColors + @Composable + @ReadOnlyComposable + get() = LocalColors.current + + val typography: ElementTypography + @Composable + @ReadOnlyComposable + get() = LocalTypography.current + + val spaces: ElementSpaces + @Composable + @ReadOnlyComposable + get() = LocalSpaces.current +} + +/* Global variables (application level) */ +val LocalSpaces = staticCompositionLocalOf { ElementSpaces() } +val LocalColors = staticCompositionLocalOf { elementColorsLight() } +val LocalTypography = staticCompositionLocalOf { ElementTypography() } + +@Composable +fun ElementTheme( + darkTheme: Boolean = isSystemInDarkTheme(), + lightColors: ElementColors = elementColorsLight(), + darkColors: ElementColors = elementColorsDark(), + typography: ElementTypography = ElementTheme.typography, + spaces: ElementSpaces = ElementTheme.spaces, + content: @Composable () -> Unit, +) { + val systemUiController = rememberSystemUiController() + val useDarkIcons = !darkTheme + val currentColor = remember { if (darkTheme) darkColors else lightColors } + SideEffect { + systemUiController.setStatusBarColor( + color = currentColor.background + ) + systemUiController.setSystemBarsColor( + color = Color.Transparent, + darkIcons = useDarkIcons + ) + } + val rememberedColors = remember { currentColor.copy() }.apply { updateColorsFrom(currentColor) } + CompositionLocalProvider( + LocalColors provides rememberedColors, + LocalSpaces provides spaces, + LocalTypography provides typography, + ) { + ProvideTextStyle(typography.body1, content = content) + } +} diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/ElementTypography.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/ElementTypography.kt new file mode 100644 index 0000000000..57d0beaa36 --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/ElementTypography.kt @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.designsystem.theme + +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.sp +import com.airbnb.android.showkase.annotation.ShowkaseTypography + +@ShowkaseTypography(name = "H1", group = "Element") +val h1Default: TextStyle = TextStyle( + fontFamily = FontFamily.SansSerif, + fontWeight = FontWeight.Bold, + fontSize = 24.sp +) + +@ShowkaseTypography(name = "Body1", group = "Element") +val body1Default: TextStyle = TextStyle( + fontFamily = FontFamily.SansSerif, + fontWeight = FontWeight.Normal, + fontSize = 16.sp +) + +@ShowkaseTypography(name = "BodySmall", group = "Element") +val bodySmallDefault: TextStyle = TextStyle( + fontFamily = FontFamily.SansSerif, + fontWeight = FontWeight.Normal, + fontSize = 14.sp +) + +@ShowkaseTypography(name = "bodyMedium", group = "Element") +val bodyMediumDefault: TextStyle = TextStyle( + fontFamily = FontFamily.SansSerif, + fontWeight = FontWeight.Normal, + fontSize = 18.sp +) + +@ShowkaseTypography(name = "Body Large", group = "Element") +val bodyLargeDefault: TextStyle = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 16.sp, + lineHeight = 24.sp, + letterSpacing = 0.5.sp +) + +@ShowkaseTypography(name = "Headline Small", group = "Element") +val headlineSmallDefault: TextStyle = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Bold, + fontSize = 24.sp, + lineHeight = 30.sp, + letterSpacing = 1.sp +) + +@ShowkaseTypography(name = "Headline Medium", group = "Element") +val headlineMediumDefault: TextStyle = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Bold, + fontSize = 28.sp, + lineHeight = 34.sp, + letterSpacing = 1.sp +) + +@ShowkaseTypography(name = "Headline Large", group = "Element") +val headlineLargeDefault: TextStyle = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Bold, + fontSize = 32.sp, + lineHeight = 38.sp, + letterSpacing = 1.sp +) + +@ShowkaseTypography(name = "titleSmall", group = "Element") +val titleSmallDefault: TextStyle = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 14.sp, + lineHeight = 20.sp, + letterSpacing = 0.5.sp +) + +@ShowkaseTypography(name = "titleMedium", group = "Element") +val titleMediumDefault: TextStyle = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 18.sp, + lineHeight = 24.sp, + letterSpacing = 0.5.sp +) + +data class ElementTypography( + val h1: TextStyle = h1Default, + val body1: TextStyle = body1Default, + val bodySmall: TextStyle = bodySmallDefault, + val bodyMedium: TextStyle = bodyMediumDefault, + val bodyLarge: TextStyle = bodyLargeDefault, + val headlineSmall: TextStyle = headlineSmallDefault, + val headlineMedium: TextStyle = headlineMediumDefault, + val headlineLarge: TextStyle = headlineLargeDefault, + val titleSmall: TextStyle = titleSmallDefault, + val titleMedium: TextStyle = titleMediumDefault, +) diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ElementButton.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ElementButton.kt new file mode 100644 index 0000000000..d9a536b4db --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ElementButton.kt @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.designsystem.theme.components + +import androidx.compose.foundation.layout.RowScope +import androidx.compose.material.ContentAlpha +import androidx.compose.material.ProvideTextStyle +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.compositeOver +import io.element.android.libraries.designsystem.components.color.elementContentColorFor +import io.element.android.libraries.designsystem.theme.ElementTheme + +@Composable +fun ElementButton( + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + containerColor: Color = ElementTheme.colors.primary, + content: @Composable RowScope.() -> Unit +) { + Button( + colors = ButtonDefaults.buttonColors( + containerColor = containerColor, + contentColor = elementContentColorFor(backgroundColor = containerColor), + disabledContainerColor = containerColor + .copy(alpha = 0.12f) + .compositeOver(containerColor), + disabledContentColor = elementContentColorFor(backgroundColor = containerColor) + .copy(alpha = ContentAlpha.disabled) + ), + // TODO shape = ButtonShape, + // TODO elevation = ButtonDefaults.elevation( + // defaultElevation = ElementTheme.elevation.default, + // pressedElevation = ElementTheme.elevation.pressed + // /* disabledElevation = 0.dp */ + // ), + onClick = onClick, + modifier = modifier, + enabled = enabled, + content = { + ProvideTextStyle( + value = ElementTheme.typography.body1 + ) { + content() + } + } + ) +} diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ElementCheckbox.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ElementCheckbox.kt new file mode 100644 index 0000000000..058313d40d --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ElementCheckbox.kt @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.designsystem.theme.components + +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.material3.Checkbox +import androidx.compose.material3.CheckboxColors +import androidx.compose.material3.CheckboxDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import io.element.android.libraries.designsystem.theme.ElementTheme + +@Composable +fun ElementCheckbox( + checked: Boolean, + onCheckedChange: ((Boolean) -> Unit)?, + modifier: Modifier = Modifier, + enabled: Boolean = true, + colors: CheckboxColors = CheckboxDefaults.colors( + checkedColor = ElementTheme.colors.primary, + uncheckedColor = Color.Gray, // TODO ElementTheme.colors. + checkmarkColor = Color.Gray, // TODO ElementTheme.colors. + disabledCheckedColor = Color.Gray // TODO ElementTheme.colors. + .copy(alpha = 0.2F), + disabledUncheckedColor = Color.Gray // TODO ElementTheme.colors. + .copy(alpha = 0.2F), + disabledIndeterminateColor = Color.Gray // TODO ElementTheme.colors. + ), + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() } +) { + Checkbox( + checked = checked, + onCheckedChange = onCheckedChange, + modifier = modifier, + enabled = enabled, + colors = colors, + interactionSource = interactionSource, + ) +} diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ElementMediumAppBar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ElementMediumAppBar.kt new file mode 100644 index 0000000000..0d3a0a134d --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ElementMediumAppBar.kt @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.designsystem.theme.components + +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.MediumTopAppBar +import androidx.compose.material3.TopAppBarColors +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.material3.TopAppBarScrollBehavior +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import io.element.android.libraries.designsystem.theme.ElementTheme + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun ElementMediumAppBar( + title: @Composable () -> Unit, + modifier: Modifier = Modifier, + navigationIcon: @Composable () -> Unit = {}, + actions: @Composable RowScope.() -> Unit = {}, + windowInsets: WindowInsets = TopAppBarDefaults.windowInsets, + colors: TopAppBarColors = TopAppBarDefaults.mediumTopAppBarColors( + containerColor = ElementTheme.colors.background, + scrolledContainerColor = ElementTheme.colors.background, + navigationIconContentColor = ElementTheme.colors.onBackground, + titleContentColor = ElementTheme.colors.onBackground, + actionIconContentColor = ElementTheme.colors.onBackground, + ), + scrollBehavior: TopAppBarScrollBehavior? = null +) { + MediumTopAppBar( + title = title, + modifier = modifier, + navigationIcon = navigationIcon, + actions = actions, + windowInsets = windowInsets, + colors = colors, + scrollBehavior = scrollBehavior, + ) +} diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ElementScaffold.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ElementScaffold.kt new file mode 100644 index 0000000000..a244bb3fa7 --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ElementScaffold.kt @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.designsystem.theme.components + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.FabPosition +import androidx.compose.material3.Scaffold +import androidx.compose.material3.ScaffoldDefaults +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import io.element.android.libraries.designsystem.components.color.elementContentColorFor +import io.element.android.libraries.designsystem.theme.ElementTheme + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun ElementScaffold( + modifier: Modifier = Modifier, + topBar: @Composable () -> Unit = {}, + bottomBar: @Composable () -> Unit = {}, + snackbarHost: @Composable () -> Unit = {}, + floatingActionButton: @Composable () -> Unit = {}, + floatingActionButtonPosition: FabPosition = FabPosition.End, + containerColor: Color = ElementTheme.colors.background, + contentColor: Color = elementContentColorFor(containerColor), + contentWindowInsets: WindowInsets = ScaffoldDefaults.contentWindowInsets, + content: @Composable (PaddingValues) -> Unit +) { + Scaffold( + modifier = modifier, + topBar = topBar, + bottomBar = bottomBar, + snackbarHost = snackbarHost, + floatingActionButton = floatingActionButton, + floatingActionButtonPosition = floatingActionButtonPosition, + containerColor = containerColor, + contentColor = contentColor, + contentWindowInsets = contentWindowInsets, + content = content, + ) +} diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ElementSlider.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ElementSlider.kt new file mode 100644 index 0000000000..318aeb2b41 --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ElementSlider.kt @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.designsystem.theme.components + +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.material3.Slider +import androidx.compose.material3.SliderColors +import androidx.compose.material3.SliderDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import io.element.android.libraries.designsystem.theme.ElementTheme + +@Composable +fun ElementSlider( + value: Float, + onValueChange: (Float) -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + valueRange: ClosedFloatingPointRange = 0f..1f, + /*@IntRange(from = 0)*/ + steps: Int = 0, + onValueChangeFinished: (() -> Unit)? = null, + colors: SliderColors = SliderDefaults.colors( + thumbColor = ElementTheme.colors.primary, + activeTrackColor = ElementTheme.colors.primary, + activeTickColor = ElementTheme.colors.primary, + inactiveTrackColor = ElementTheme.colors.primary, + inactiveTickColor = ElementTheme.colors.primary, + disabledThumbColor = ElementTheme.colors.primary, + disabledActiveTrackColor = ElementTheme.colors.primary, + disabledActiveTickColor = ElementTheme.colors.primary, + disabledInactiveTrackColor = ElementTheme.colors.primary, + disabledInactiveTickColor = ElementTheme.colors.primary, + ), + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() } +) { + Slider( + value = value, + onValueChange = onValueChange, + modifier = modifier, + enabled = enabled, + valueRange = valueRange, + steps = steps, + onValueChangeFinished = onValueChangeFinished, + colors = colors, + interactionSource = interactionSource, + ) +} diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ElementSurface.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ElementSurface.kt new file mode 100644 index 0000000000..0039eb0ee3 --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ElementSurface.kt @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.designsystem.theme.components + +import androidx.compose.foundation.BorderStroke +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.RectangleShape +import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import io.element.android.libraries.designsystem.components.color.elementContentColorFor +import io.element.android.libraries.designsystem.theme.ElementTheme + +@Composable +fun ElementSurface( + modifier: Modifier = Modifier, + shape: Shape = RectangleShape, + color: Color = ElementTheme.colors.surfaceVariant, + contentColor: Color = elementContentColorFor(color), + tonalElevation: Dp = 0.dp, + shadowElevation: Dp = 0.dp, + border: BorderStroke? = null, + content: @Composable () -> Unit +) { + Surface( + modifier = modifier, + shape = shape, + color = color, + contentColor = contentColor, + tonalElevation = tonalElevation, + shadowElevation = shadowElevation, + border = border, + content = content, + ) +} diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ElementTopAppBar.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ElementTopAppBar.kt new file mode 100644 index 0000000000..7b7be7dfd1 --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/ElementTopAppBar.kt @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2023 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.element.android.libraries.designsystem.theme.components + +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarColors +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.material3.TopAppBarScrollBehavior +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import io.element.android.libraries.designsystem.theme.ElementTheme + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun ElementTopAppBar( + title: @Composable () -> Unit, + modifier: Modifier = Modifier, + navigationIcon: @Composable () -> Unit = {}, + actions: @Composable RowScope.() -> Unit = {}, + windowInsets: WindowInsets = TopAppBarDefaults.windowInsets, + colors: TopAppBarColors = TopAppBarDefaults.smallTopAppBarColors( + containerColor = ElementTheme.colors.background, + scrolledContainerColor = ElementTheme.colors.background, + navigationIconContentColor = ElementTheme.colors.onBackground, + titleContentColor = ElementTheme.colors.onBackground, + actionIconContentColor = ElementTheme.colors.onBackground, + ), + scrollBehavior: TopAppBarScrollBehavior? = null +) { + TopAppBar( + title = title, + modifier = modifier, + navigationIcon = navigationIcon, + actions = actions, + windowInsets = windowInsets, + colors = colors, + scrollBehavior = scrollBehavior, + ) +} diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/MatrixUserHeader.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/MatrixUserHeader.kt index 3fe339180e..94cc41c0f4 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/MatrixUserHeader.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/MatrixUserHeader.kt @@ -23,7 +23,6 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -36,6 +35,7 @@ import androidx.compose.ui.unit.sp import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.AvatarData import io.element.android.libraries.designsystem.components.avatar.AvatarSize +import io.element.android.libraries.designsystem.theme.ElementTheme import io.element.android.libraries.matrix.core.UserId import io.element.android.libraries.matrix.ui.model.MatrixUser import io.element.android.libraries.matrix.ui.model.getBestName @@ -71,7 +71,7 @@ fun MatrixUserHeader( Spacer(modifier = Modifier.height(4.dp)) Text( text = matrixUser.id.value, - color = MaterialTheme.colorScheme.secondary, + color = ElementTheme.colors.secondary, fontSize = 14.sp, maxLines = 1, overflow = TextOverflow.Ellipsis diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/MatrixUserRow.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/MatrixUserRow.kt index 498a8d17a9..e813fc8b50 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/MatrixUserRow.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/components/MatrixUserRow.kt @@ -23,7 +23,6 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -35,6 +34,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import io.element.android.libraries.designsystem.components.avatar.Avatar import io.element.android.libraries.designsystem.components.avatar.AvatarData +import io.element.android.libraries.designsystem.theme.ElementTheme import io.element.android.libraries.matrix.core.UserId import io.element.android.libraries.matrix.ui.model.MatrixUser import io.element.android.libraries.matrix.ui.model.getBestName @@ -74,7 +74,7 @@ fun MatrixUserRow( if (matrixUser.username.isNullOrEmpty().not()) { Text( text = matrixUser.id.value, - color = MaterialTheme.colorScheme.secondary, + color = ElementTheme.colors.secondary, fontSize = 14.sp, maxLines = 1, overflow = TextOverflow.Ellipsis diff --git a/tests/uitests/src/main/kotlin/io/element/android/tests/uitests/ShowkaseButton.kt b/tests/uitests/src/main/kotlin/io/element/android/tests/uitests/ShowkaseButton.kt index 9ae1b78577..7a89559b42 100644 --- a/tests/uitests/src/main/kotlin/io/element/android/tests/uitests/ShowkaseButton.kt +++ b/tests/uitests/src/main/kotlin/io/element/android/tests/uitests/ShowkaseButton.kt @@ -32,6 +32,7 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import io.element.android.libraries.designsystem.theme.components.ElementButton @Composable fun ShowkaseButton( @@ -41,7 +42,7 @@ fun ShowkaseButton( var isShowkaseButtonVisible by remember { mutableStateOf(BuildConfig.DEBUG) } if (isShowkaseButtonVisible) { - Button( + ElementButton( modifier = modifier .padding(top = 32.dp), onClick = onClick diff --git a/tests/uitests/src/test/kotlin/io/element/android/tests/uitests/ScreenshotTest.kt b/tests/uitests/src/test/kotlin/io/element/android/tests/uitests/ScreenshotTest.kt index 1c26565acf..bcd78869cf 100644 --- a/tests/uitests/src/test/kotlin/io/element/android/tests/uitests/ScreenshotTest.kt +++ b/tests/uitests/src/test/kotlin/io/element/android/tests/uitests/ScreenshotTest.kt @@ -24,7 +24,6 @@ import androidx.activity.OnBackPressedDispatcherOwner import androidx.activity.compose.LocalOnBackPressedDispatcherOwner import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box -import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalConfiguration @@ -36,7 +35,7 @@ import app.cash.paparazzi.Paparazzi import com.airbnb.android.showkase.models.Showkase import com.google.testing.junit.testparameterinjector.TestParameter import com.google.testing.junit.testparameterinjector.TestParameterInjector -import io.element.android.libraries.designsystem.ElementXTheme +import io.element.android.libraries.designsystem.theme.ElementTheme import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith @@ -101,8 +100,8 @@ class ScreenshotTest { override fun getOnBackPressedDispatcher() = OnBackPressedDispatcher() } ) { - ElementXTheme(darkTheme = (theme == "dark")) { - Box(modifier = Modifier.background(MaterialTheme.colorScheme.background)) { + ElementTheme(darkTheme = (theme == "dark")) { + Box(modifier = Modifier.background(ElementTheme.colors.background)) { componentTestPreview.Content() } } diff --git a/tests/uitests/src/test/kotlin/io/element/android/tests/uitests/TypographyTestPreview.kt b/tests/uitests/src/test/kotlin/io/element/android/tests/uitests/TypographyTestPreview.kt index 80f27c25a0..6f3b4f4bbf 100644 --- a/tests/uitests/src/test/kotlin/io/element/android/tests/uitests/TypographyTestPreview.kt +++ b/tests/uitests/src/test/kotlin/io/element/android/tests/uitests/TypographyTestPreview.kt @@ -19,11 +19,11 @@ package io.element.android.tests.uitests import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.text.BasicText -import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import com.airbnb.android.showkase.models.ShowkaseBrowserTypography import com.airbnb.android.showkase.ui.padding4x +import io.element.android.libraries.designsystem.theme.ElementTheme import java.util.Locale class TypographyTestPreview( @@ -39,7 +39,7 @@ class TypographyTestPreview( .fillMaxWidth() .padding(padding4x), style = showkaseBrowserTypography.textStyle.copy( - color = MaterialTheme.colorScheme.onBackground + color = ElementTheme.colors.onBackground ) ) }