First draft of full custom theme.
ElementTheme everywhere Create ElementButton
This commit is contained in:
parent
3ecce4e24f
commit
6e4edc8289
50 changed files with 1082 additions and 377 deletions
|
|
@ -19,15 +19,14 @@ package io.element.android.x
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Surface
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||||
import androidx.core.view.WindowCompat
|
import androidx.core.view.WindowCompat
|
||||||
import com.bumble.appyx.core.integration.NodeHost
|
import com.bumble.appyx.core.integration.NodeHost
|
||||||
import com.bumble.appyx.core.integrationpoint.NodeComponentActivity
|
import com.bumble.appyx.core.integrationpoint.NodeComponentActivity
|
||||||
import io.element.android.libraries.architecture.bindings
|
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.libraries.di.DaggerComponentOwner
|
||||||
import io.element.android.x.di.AppBindings
|
import io.element.android.x.di.AppBindings
|
||||||
import io.element.android.x.node.RootFlowNode
|
import io.element.android.x.node.RootFlowNode
|
||||||
|
|
@ -41,10 +40,9 @@ class MainActivity : NodeComponentActivity() {
|
||||||
appBindings.matrixClientsHolder().restore(savedInstanceState)
|
appBindings.matrixClientsHolder().restore(savedInstanceState)
|
||||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||||
setContent {
|
setContent {
|
||||||
ElementXTheme {
|
ElementTheme {
|
||||||
Surface(
|
ElementSurface(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
color = MaterialTheme.colorScheme.background
|
|
||||||
) {
|
) {
|
||||||
NodeHost(integrationPoint = appyxIntegrationPoint) {
|
NodeHost(integrationPoint = appyxIntegrationPoint) {
|
||||||
RootFlowNode(
|
RootFlowNode(
|
||||||
|
|
|
||||||
|
|
@ -20,13 +20,13 @@ import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Close
|
import androidx.compose.material.icons.filled.Close
|
||||||
import androidx.compose.material3.Button
|
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import io.element.android.libraries.designsystem.theme.components.ElementButton
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun ShowkaseButton(
|
internal fun ShowkaseButton(
|
||||||
|
|
@ -36,7 +36,7 @@ internal fun ShowkaseButton(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
if (isVisible) {
|
if (isVisible) {
|
||||||
Button(
|
ElementButton(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.padding(top = 32.dp, start = 16.dp),
|
.padding(top = 32.dp, start = 16.dp),
|
||||||
onClick = onClick
|
onClick = onClick
|
||||||
|
|
|
||||||
|
|
@ -33,12 +33,9 @@ import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.foundation.text.KeyboardActions
|
import androidx.compose.foundation.text.KeyboardActions
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material3.Button
|
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.OutlinedTextField
|
import androidx.compose.material3.OutlinedTextField
|
||||||
import androidx.compose.material3.Surface
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
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.architecture.Async
|
||||||
import io.element.android.libraries.designsystem.components.VectorIcon
|
import io.element.android.libraries.designsystem.components.VectorIcon
|
||||||
import io.element.android.libraries.designsystem.components.form.textFieldState
|
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.TestTags
|
||||||
import io.element.android.libraries.testtags.testTag
|
import io.element.android.libraries.testtags.testTag
|
||||||
|
|
||||||
|
|
@ -66,9 +66,8 @@ fun ChangeServerView(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
onChangeServerSuccess: () -> Unit = {},
|
onChangeServerSuccess: () -> Unit = {},
|
||||||
) {
|
) {
|
||||||
Surface(
|
ElementSurface(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
color = MaterialTheme.colorScheme.background,
|
|
||||||
) {
|
) {
|
||||||
val eventSink = state.eventSink
|
val eventSink = state.eventSink
|
||||||
val scrollState = rememberScrollState()
|
val scrollState = rememberScrollState()
|
||||||
|
|
@ -92,7 +91,7 @@ fun ChangeServerView(
|
||||||
.size(width = 81.dp, height = 73.dp)
|
.size(width = 81.dp, height = 73.dp)
|
||||||
.align(Alignment.CenterHorizontally)
|
.align(Alignment.CenterHorizontally)
|
||||||
.background(
|
.background(
|
||||||
color = MaterialTheme.colorScheme.surfaceVariant,
|
color = ElementTheme.colors.surfaceVariant,
|
||||||
shape = RoundedCornerShape(32.dp)
|
shape = RoundedCornerShape(32.dp)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
|
|
@ -124,7 +123,7 @@ fun ChangeServerView(
|
||||||
.padding(top = 16.dp),
|
.padding(top = 16.dp),
|
||||||
textAlign = TextAlign.Center,
|
textAlign = TextAlign.Center,
|
||||||
fontSize = 16.sp,
|
fontSize = 16.sp,
|
||||||
color = MaterialTheme.colorScheme.secondary
|
color = ElementTheme.colors.secondary
|
||||||
)
|
)
|
||||||
var homeserverFieldState by textFieldState(stateValue = state.homeserver)
|
var homeserverFieldState by textFieldState(stateValue = state.homeserver)
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
|
|
@ -155,12 +154,12 @@ fun ChangeServerView(
|
||||||
state.homeserver,
|
state.homeserver,
|
||||||
state.changeServerAction.error
|
state.changeServerAction.error
|
||||||
),
|
),
|
||||||
color = MaterialTheme.colorScheme.error,
|
color = ElementTheme.colors.error,
|
||||||
style = MaterialTheme.typography.bodySmall,
|
style = ElementTheme.typography.bodySmall,
|
||||||
modifier = Modifier.padding(start = 16.dp)
|
modifier = Modifier.padding(start = 16.dp)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Button(
|
ElementButton(
|
||||||
onClick = { eventSink(ChangeServerEvents.Submit) },
|
onClick = { eventSink(ChangeServerEvents.Submit) },
|
||||||
enabled = state.submitEnabled,
|
enabled = state.submitEnabled,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
|
|
||||||
|
|
@ -32,14 +32,11 @@ import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Visibility
|
import androidx.compose.material.icons.filled.Visibility
|
||||||
import androidx.compose.material.icons.filled.VisibilityOff
|
import androidx.compose.material.icons.filled.VisibilityOff
|
||||||
import androidx.compose.material3.Button
|
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.OutlinedTextField
|
import androidx.compose.material3.OutlinedTextField
|
||||||
import androidx.compose.material3.Surface
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
|
@ -60,6 +57,9 @@ import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import io.element.android.features.login.error.loginError
|
import io.element.android.features.login.error.loginError
|
||||||
import io.element.android.libraries.designsystem.components.form.textFieldState
|
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.matrix.core.SessionId
|
||||||
import io.element.android.libraries.testtags.TestTags
|
import io.element.android.libraries.testtags.TestTags
|
||||||
import io.element.android.libraries.testtags.testTag
|
import io.element.android.libraries.testtags.testTag
|
||||||
|
|
@ -74,9 +74,8 @@ fun LoginRootScreen(
|
||||||
onLoginWithSuccess: (SessionId) -> Unit = {},
|
onLoginWithSuccess: (SessionId) -> Unit = {},
|
||||||
) {
|
) {
|
||||||
val eventSink = state.eventSink
|
val eventSink = state.eventSink
|
||||||
Surface(
|
ElementSurface(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
color = MaterialTheme.colorScheme.background,
|
|
||||||
) {
|
) {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
|
@ -125,7 +124,7 @@ fun LoginRootScreen(
|
||||||
keyboardType = KeyboardType.Uri,
|
keyboardType = KeyboardType.Uri,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
Button(
|
ElementButton(
|
||||||
onClick = onChangeServer,
|
onClick = onChangeServer,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.align(Alignment.CenterEnd)
|
.align(Alignment.CenterEnd)
|
||||||
|
|
@ -195,14 +194,14 @@ fun LoginRootScreen(
|
||||||
if (state.loggedInState is LoggedInState.ErrorLoggingIn) {
|
if (state.loggedInState is LoggedInState.ErrorLoggingIn) {
|
||||||
Text(
|
Text(
|
||||||
text = loginError(state.formState, state.loggedInState.failure),
|
text = loginError(state.formState, state.loggedInState.failure),
|
||||||
color = MaterialTheme.colorScheme.error,
|
color = ElementTheme.colors.error,
|
||||||
style = MaterialTheme.typography.bodySmall,
|
style = ElementTheme.typography.bodySmall,
|
||||||
modifier = Modifier.padding(start = 16.dp)
|
modifier = Modifier.padding(start = 16.dp)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Submit
|
// Submit
|
||||||
Button(
|
ElementButton(
|
||||||
onClick = { eventSink(LoginRootEvents.Submit) },
|
onClick = { eventSink(LoginRootEvents.Submit) },
|
||||||
enabled = state.submitEnabled,
|
enabled = state.submitEnabled,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
package io.element.android.features.messages
|
package io.element.android.features.messages
|
||||||
|
|
||||||
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
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.features.messages.timeline.model.TimelineItem
|
||||||
import io.element.android.libraries.designsystem.components.avatar.Avatar
|
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.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 io.element.android.libraries.designsystem.utils.LogCompositions
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
@ -101,7 +105,7 @@ fun MessagesView(
|
||||||
state.eventSink(MessagesEvents.HandleAction(action, messageEvent))
|
state.eventSink(MessagesEvents.HandleAction(action, messageEvent))
|
||||||
}
|
}
|
||||||
|
|
||||||
Scaffold(
|
ElementScaffold(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
contentWindowInsets = WindowInsets.statusBars,
|
contentWindowInsets = WindowInsets.statusBars,
|
||||||
topBar = {
|
topBar = {
|
||||||
|
|
@ -172,7 +176,7 @@ fun MessagesViewTopBar(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
onBackPressed: () -> Unit = {},
|
onBackPressed: () -> Unit = {},
|
||||||
) {
|
) {
|
||||||
TopAppBar(
|
ElementTopAppBar(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
IconButton(onClick = onBackPressed) {
|
IconButton(onClick = onBackPressed) {
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.material.ExperimentalMaterialApi
|
import androidx.compose.material.ExperimentalMaterialApi
|
||||||
import androidx.compose.material.ListItem
|
import androidx.compose.material.ListItem
|
||||||
import androidx.compose.material.LocalContentColor
|
import androidx.compose.material.LocalContentColor
|
||||||
import androidx.compose.material.MaterialTheme
|
|
||||||
import androidx.compose.material.ModalBottomSheetLayout
|
import androidx.compose.material.ModalBottomSheetLayout
|
||||||
import androidx.compose.material.ModalBottomSheetState
|
import androidx.compose.material.ModalBottomSheetState
|
||||||
import androidx.compose.material.ModalBottomSheetValue
|
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.actionlist.model.TimelineItemAction
|
||||||
import io.element.android.features.messages.timeline.model.TimelineItem
|
import io.element.android.features.messages.timeline.model.TimelineItem
|
||||||
import io.element.android.libraries.designsystem.components.VectorIcon
|
import io.element.android.libraries.designsystem.components.VectorIcon
|
||||||
|
import io.element.android.libraries.designsystem.theme.ElementTheme
|
||||||
import kotlinx.coroutines.flow.filter
|
import kotlinx.coroutines.flow.filter
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
|
@ -115,13 +115,13 @@ private fun SheetContent(
|
||||||
text = {
|
text = {
|
||||||
Text(
|
Text(
|
||||||
text = action.title,
|
text = action.title,
|
||||||
color = if (action.destructive) MaterialTheme.colors.error else Color.Unspecified,
|
color = if (action.destructive) ElementTheme.colors.error else Color.Unspecified,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
icon = {
|
icon = {
|
||||||
VectorIcon(
|
VectorIcon(
|
||||||
resourceId = action.icon,
|
resourceId = action.icon,
|
||||||
tint = if (action.destructive) MaterialTheme.colors.error else LocalContentColor.current,
|
tint = if (action.destructive) ElementTheme.colors.error else LocalContentColor.current,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ package io.element.android.features.messages.textcomposer
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
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
|
import io.element.android.libraries.textcomposer.TextComposer
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|
@ -51,7 +51,7 @@ fun MessageComposerView(
|
||||||
onComposerTextChange = ::onComposerTextChange,
|
onComposerTextChange = ::onComposerTextChange,
|
||||||
composerCanSendMessage = state.isSendButtonVisible,
|
composerCanSendMessage = state.isSendButtonVisible,
|
||||||
composerText = state.text?.charSequence?.toString(),
|
composerText = state.text?.charSequence?.toString(),
|
||||||
isInDarkMode = LocalIsDarkTheme.current,
|
isInDarkMode = !ElementTheme.colors.isLight,
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,6 @@ import androidx.compose.material.icons.filled.ArrowDownward
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
import androidx.compose.material3.FloatingActionButton
|
import androidx.compose.material3.FloatingActionButton
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
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.features.messages.timeline.model.content.TimelineItemUnknownContent
|
||||||
import io.element.android.libraries.designsystem.components.avatar.Avatar
|
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.AvatarData
|
||||||
|
import io.element.android.libraries.designsystem.theme.ElementTheme
|
||||||
import io.element.android.libraries.designsystem.utils.PairCombinedPreviewParameter
|
import io.element.android.libraries.designsystem.utils.PairCombinedPreviewParameter
|
||||||
import io.element.android.libraries.matrix.core.EventId
|
import io.element.android.libraries.matrix.core.EventId
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
|
|
@ -267,7 +267,7 @@ private fun MessageSenderInformation(
|
||||||
}
|
}
|
||||||
Text(
|
Text(
|
||||||
text = sender,
|
text = sender,
|
||||||
style = MaterialTheme.typography.titleMedium,
|
style = ElementTheme.typography.titleMedium,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.alignBy(LastBaseline)
|
.alignBy(LastBaseline)
|
||||||
)
|
)
|
||||||
|
|
@ -326,8 +326,8 @@ internal fun BoxScope.TimelineScrollHelper(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.align(Alignment.BottomCenter)
|
.align(Alignment.BottomCenter)
|
||||||
.size(40.dp),
|
.size(40.dp),
|
||||||
containerColor = MaterialTheme.colorScheme.surfaceVariant,
|
containerColor = ElementTheme.colors.surfaceVariant,
|
||||||
contentColor = MaterialTheme.colorScheme.onSurfaceVariant
|
contentColor = ElementTheme.colors.onSurfaceVariant
|
||||||
) {
|
) {
|
||||||
Icon(Icons.Default.ArrowDownward, "")
|
Icon(Icons.Default.ArrowDownward, "")
|
||||||
}
|
}
|
||||||
|
|
@ -345,7 +345,7 @@ internal fun TimelineLoadingMoreIndicator() {
|
||||||
) {
|
) {
|
||||||
CircularProgressIndicator(
|
CircularProgressIndicator(
|
||||||
strokeWidth = 2.dp,
|
strokeWidth = 2.dp,
|
||||||
color = MaterialTheme.colorScheme.primary
|
color = ElementTheme.colors.primary
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,14 +23,14 @@ import androidx.compose.foundation.layout.offset
|
||||||
import androidx.compose.foundation.layout.widthIn
|
import androidx.compose.foundation.layout.widthIn
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material.ripple.rememberRipple
|
import androidx.compose.material.ripple.rememberRipple
|
||||||
import androidx.compose.material3.Surface
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.graphics.Shape
|
import androidx.compose.ui.graphics.Shape
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import io.element.android.features.messages.timeline.model.MessagesItemGroupPosition
|
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
|
private val BUBBLE_RADIUS = 16.dp
|
||||||
|
|
||||||
|
|
@ -82,16 +82,16 @@ fun MessageEventBubble(
|
||||||
}
|
}
|
||||||
|
|
||||||
val backgroundBubbleColor = if (isHighlighted) {
|
val backgroundBubbleColor = if (isHighlighted) {
|
||||||
LocalExtendedColors.current.messageHighlightedBackground
|
ElementTheme.colors.messageHighlightedBackground
|
||||||
} else {
|
} else {
|
||||||
if (isMine) {
|
if (isMine) {
|
||||||
LocalExtendedColors.current.messageFromMeBackground
|
ElementTheme.colors.messageFromMeBackground
|
||||||
} else {
|
} else {
|
||||||
LocalExtendedColors.current.messageFromOtherBackground
|
ElementTheme.colors.messageFromOtherBackground
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val bubbleShape = bubbleShape()
|
val bubbleShape = bubbleShape()
|
||||||
Surface(
|
ElementSurface(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.widthIn(min = 80.dp)
|
.widthIn(min = 80.dp)
|
||||||
.offsetForItem()
|
.offsetForItem()
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.aspectRatio
|
import androidx.compose.foundation.layout.aspectRatio
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
|
|
@ -34,6 +33,7 @@ import androidx.compose.ui.platform.LocalContext
|
||||||
import coil.compose.AsyncImage
|
import coil.compose.AsyncImage
|
||||||
import coil.request.ImageRequest
|
import coil.request.ImageRequest
|
||||||
import io.element.android.features.messages.timeline.model.content.TimelineItemImageContent
|
import io.element.android.features.messages.timeline.model.content.TimelineItemImageContent
|
||||||
|
import io.element.android.libraries.designsystem.theme.ElementTheme
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun TimelineItemImageView(
|
fun TimelineItemImageView(
|
||||||
|
|
@ -60,7 +60,7 @@ fun TimelineItemImageView(
|
||||||
AsyncImage(
|
AsyncImage(
|
||||||
model = model,
|
model = model,
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
placeholder = ColorPainter(MaterialTheme.colorScheme.surfaceVariant),
|
placeholder = ColorPainter(ElementTheme.colors.surfaceVariant),
|
||||||
contentScale = ContentScale.Crop,
|
contentScale = ContentScale.Crop,
|
||||||
onSuccess = { isLoading.value = false },
|
onSuccess = { isLoading.value = false },
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
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.text.font.FontStyle
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
|
import io.element.android.libraries.designsystem.theme.ElementTheme
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun TimelineItemInformativeView(
|
fun TimelineItemInformativeView(
|
||||||
|
|
@ -44,14 +44,14 @@ fun TimelineItemInformativeView(
|
||||||
) {
|
) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = icon,
|
imageVector = icon,
|
||||||
tint = MaterialTheme.colorScheme.secondary,
|
tint = ElementTheme.colors.secondary,
|
||||||
contentDescription = iconDescription,
|
contentDescription = iconDescription,
|
||||||
modifier = Modifier.size(16.dp)
|
modifier = Modifier.size(16.dp)
|
||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.width(4.dp))
|
Spacer(modifier = Modifier.width(4.dp))
|
||||||
Text(
|
Text(
|
||||||
fontStyle = FontStyle.Italic,
|
fontStyle = FontStyle.Italic,
|
||||||
color = MaterialTheme.colorScheme.secondary,
|
color = ElementTheme.colors.secondary,
|
||||||
fontSize = 14.sp,
|
fontSize = 14.sp,
|
||||||
text = text
|
text = text
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,6 @@ import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.foundation.shape.CornerSize
|
import androidx.compose.foundation.shape.CornerSize
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Surface
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
|
|
@ -34,6 +32,8 @@ import androidx.compose.ui.unit.sp
|
||||||
import com.google.accompanist.flowlayout.FlowRow
|
import com.google.accompanist.flowlayout.FlowRow
|
||||||
import io.element.android.features.messages.timeline.model.AggregatedReaction
|
import io.element.android.features.messages.timeline.model.AggregatedReaction
|
||||||
import io.element.android.features.messages.timeline.model.TimelineItemReactions
|
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
|
@Composable
|
||||||
fun TimelineItemReactionsView(
|
fun TimelineItemReactionsView(
|
||||||
|
|
@ -54,10 +54,10 @@ fun TimelineItemReactionsView(
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MessagesReactionButton(reaction: AggregatedReaction, modifier: Modifier = Modifier) {
|
fun MessagesReactionButton(reaction: AggregatedReaction, modifier: Modifier = Modifier) {
|
||||||
Surface(
|
ElementSurface(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
color = MaterialTheme.colorScheme.surfaceVariant,
|
color = ElementTheme.colors.surfaceVariant,
|
||||||
border = BorderStroke(2.dp, MaterialTheme.colorScheme.background),
|
border = BorderStroke(2.dp, ElementTheme.colors.background),
|
||||||
shape = RoundedCornerShape(corner = CornerSize(12.dp)),
|
shape = RoundedCornerShape(corner = CornerSize(12.dp)),
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
|
|
@ -66,7 +66,7 @@ fun MessagesReactionButton(reaction: AggregatedReaction, modifier: Modifier = Mo
|
||||||
) {
|
) {
|
||||||
Text(text = reaction.key, fontSize = 12.sp)
|
Text(text = reaction.key, fontSize = 12.sp)
|
||||||
Spacer(modifier = Modifier.width(4.dp))
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,10 +25,7 @@ import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.foundation.text.InlineTextContent
|
import androidx.compose.foundation.text.InlineTextContent
|
||||||
import androidx.compose.foundation.text.appendInlineContent
|
import androidx.compose.foundation.text.appendInlineContent
|
||||||
import androidx.compose.material3.ColorScheme
|
|
||||||
import androidx.compose.material3.LocalTextStyle
|
import androidx.compose.material3.LocalTextStyle
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Surface
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
|
@ -49,6 +46,9 @@ import androidx.compose.ui.unit.sp
|
||||||
import com.google.accompanist.flowlayout.FlowRow
|
import com.google.accompanist.flowlayout.FlowRow
|
||||||
import io.element.android.libraries.designsystem.LinkColor
|
import io.element.android.libraries.designsystem.LinkColor
|
||||||
import io.element.android.libraries.designsystem.components.ClickableLinkText
|
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.PermalinkData
|
||||||
import io.element.android.libraries.matrix.permalink.PermalinkParser
|
import io.element.android.libraries.matrix.permalink.PermalinkParser
|
||||||
import kotlinx.collections.immutable.persistentMapOf
|
import kotlinx.collections.immutable.persistentMapOf
|
||||||
|
|
@ -214,7 +214,7 @@ private fun HtmlInline(
|
||||||
) {
|
) {
|
||||||
Box(modifier) {
|
Box(modifier) {
|
||||||
val styledText = buildAnnotatedString {
|
val styledText = buildAnnotatedString {
|
||||||
appendInlineElement(element, MaterialTheme.colorScheme)
|
appendInlineElement(element, ElementTheme.colors)
|
||||||
}
|
}
|
||||||
HtmlText(
|
HtmlText(
|
||||||
text = styledText,
|
text = styledText,
|
||||||
|
|
@ -232,7 +232,7 @@ private fun HtmlPreformatted(
|
||||||
) {
|
) {
|
||||||
val isCode = pre.firstElementChild()?.normalName() == "code"
|
val isCode = pre.firstElementChild()?.normalName() == "code"
|
||||||
val backgroundColor =
|
val backgroundColor =
|
||||||
if (isCode) MaterialTheme.colorScheme.codeBackground() else Color.Unspecified
|
if (isCode) ElementTheme.colors.codeBackground() else Color.Unspecified
|
||||||
Box(
|
Box(
|
||||||
modifier
|
modifier
|
||||||
.background(color = backgroundColor)
|
.background(color = backgroundColor)
|
||||||
|
|
@ -255,7 +255,7 @@ private fun HtmlParagraph(
|
||||||
) {
|
) {
|
||||||
Box(modifier) {
|
Box(modifier) {
|
||||||
val styledText = buildAnnotatedString {
|
val styledText = buildAnnotatedString {
|
||||||
appendInlineChildrenElements(paragraph.childNodes(), MaterialTheme.colorScheme)
|
appendInlineChildrenElements(paragraph.childNodes(), ElementTheme.colors)
|
||||||
}
|
}
|
||||||
HtmlText(
|
HtmlText(
|
||||||
text = styledText, onClick = onTextClicked,
|
text = styledText, onClick = onTextClicked,
|
||||||
|
|
@ -272,7 +272,7 @@ private fun HtmlBlockquote(
|
||||||
onTextClicked: () -> Unit = {},
|
onTextClicked: () -> Unit = {},
|
||||||
onTextLongClicked: () -> Unit = {},
|
onTextLongClicked: () -> Unit = {},
|
||||||
) {
|
) {
|
||||||
val color = MaterialTheme.colorScheme.onBackground
|
val color = ElementTheme.colors.onBackground
|
||||||
Box(
|
Box(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.drawBehind {
|
.drawBehind {
|
||||||
|
|
@ -287,7 +287,7 @@ private fun HtmlBlockquote(
|
||||||
) {
|
) {
|
||||||
val text = buildAnnotatedString {
|
val text = buildAnnotatedString {
|
||||||
withStyle(style = SpanStyle(fontStyle = FontStyle.Italic)) {
|
withStyle(style = SpanStyle(fontStyle = FontStyle.Italic)) {
|
||||||
appendInlineChildrenElements(blockquote.childNodes(), MaterialTheme.colorScheme)
|
appendInlineChildrenElements(blockquote.childNodes(), ElementTheme.colors)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HtmlText(
|
HtmlText(
|
||||||
|
|
@ -306,19 +306,19 @@ private fun HtmlHeading(
|
||||||
onTextLongClicked: () -> Unit = {},
|
onTextLongClicked: () -> Unit = {},
|
||||||
) {
|
) {
|
||||||
val style = when (heading.normalName()) {
|
val style = when (heading.normalName()) {
|
||||||
"h1" -> MaterialTheme.typography.headlineLarge.copy(fontSize = 30.sp)
|
"h1" -> ElementTheme.typography.headlineLarge.copy(fontSize = 30.sp)
|
||||||
"h2" -> MaterialTheme.typography.headlineLarge.copy(fontSize = 26.sp)
|
"h2" -> ElementTheme.typography.headlineLarge.copy(fontSize = 26.sp)
|
||||||
"h3" -> MaterialTheme.typography.headlineMedium.copy(fontSize = 22.sp)
|
"h3" -> ElementTheme.typography.headlineMedium.copy(fontSize = 22.sp)
|
||||||
"h4" -> MaterialTheme.typography.headlineMedium.copy(fontSize = 18.sp)
|
"h4" -> ElementTheme.typography.headlineMedium.copy(fontSize = 18.sp)
|
||||||
"h5" -> MaterialTheme.typography.headlineSmall.copy(fontSize = 14.sp)
|
"h5" -> ElementTheme.typography.headlineSmall.copy(fontSize = 14.sp)
|
||||||
"h6" -> MaterialTheme.typography.headlineSmall.copy(fontSize = 12.sp)
|
"h6" -> ElementTheme.typography.headlineSmall.copy(fontSize = 12.sp)
|
||||||
else -> {
|
else -> {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Box(modifier) {
|
Box(modifier) {
|
||||||
val text = buildAnnotatedString {
|
val text = buildAnnotatedString {
|
||||||
appendInlineChildrenElements(heading.childNodes(), MaterialTheme.colorScheme)
|
appendInlineChildrenElements(heading.childNodes(), ElementTheme.colors)
|
||||||
}
|
}
|
||||||
HtmlText(
|
HtmlText(
|
||||||
text = text,
|
text = text,
|
||||||
|
|
@ -340,11 +340,11 @@ private fun HtmlMxReply(
|
||||||
) {
|
) {
|
||||||
val blockquote = mxReply.childNodes().firstOrNull() ?: return
|
val blockquote = mxReply.childNodes().firstOrNull() ?: return
|
||||||
val shape = RoundedCornerShape(12.dp)
|
val shape = RoundedCornerShape(12.dp)
|
||||||
Surface(
|
ElementSurface(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.padding(bottom = 4.dp)
|
.padding(bottom = 4.dp)
|
||||||
.offset(x = -(8.dp)),
|
.offset(x = -(8.dp)),
|
||||||
color = MaterialTheme.colorScheme.background,
|
color = ElementTheme.colors.background,
|
||||||
shape = shape,
|
shape = shape,
|
||||||
) {
|
) {
|
||||||
val text = buildAnnotatedString {
|
val text = buildAnnotatedString {
|
||||||
|
|
@ -354,7 +354,7 @@ private fun HtmlMxReply(
|
||||||
withStyle(
|
withStyle(
|
||||||
style = SpanStyle(
|
style = SpanStyle(
|
||||||
fontSize = 12.sp,
|
fontSize = 12.sp,
|
||||||
color = MaterialTheme.colorScheme.secondary
|
color = ElementTheme.colors.secondary
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
append(blockquoteNode.text())
|
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)
|
return background.copy(alpha = 0.3f)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun AnnotatedString.Builder.appendInlineChildrenElements(
|
private fun AnnotatedString.Builder.appendInlineChildrenElements(
|
||||||
childNodes: List<Node>,
|
childNodes: List<Node>,
|
||||||
colors: ColorScheme
|
colors: ElementColors
|
||||||
) {
|
) {
|
||||||
for (node in childNodes) {
|
for (node in childNodes) {
|
||||||
when (node) {
|
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()) {
|
when (element.normalName()) {
|
||||||
"br" -> {
|
"br" -> {
|
||||||
append('\n')
|
append('\n')
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,6 @@ import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.systemBarsPadding
|
import androidx.compose.foundation.layout.systemBarsPadding
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Surface
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
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.HorizontalPager
|
||||||
import com.google.accompanist.pager.HorizontalPagerIndicator
|
import com.google.accompanist.pager.HorizontalPagerIndicator
|
||||||
import com.google.accompanist.pager.rememberPagerState
|
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.TestTags
|
||||||
import io.element.android.libraries.testtags.testTag
|
import io.element.android.libraries.testtags.testTag
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
|
|
@ -67,9 +67,9 @@ fun OnBoardingScreen(
|
||||||
val carrouselState = remember { SplashCarouselStateFactory().create() }
|
val carrouselState = remember { SplashCarouselStateFactory().create() }
|
||||||
val nbOfPages = carrouselState.items.size
|
val nbOfPages = carrouselState.items.size
|
||||||
var key by remember { mutableStateOf(false) }
|
var key by remember { mutableStateOf(false) }
|
||||||
Surface(
|
ElementSurface(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
color = MaterialTheme.colorScheme.background,
|
color = ElementTheme.colors.background,
|
||||||
) {
|
) {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
|
@ -109,20 +109,7 @@ fun OnBoardingScreen(
|
||||||
.align(CenterHorizontally)
|
.align(CenterHorizontally)
|
||||||
.padding(16.dp),
|
.padding(16.dp),
|
||||||
)
|
)
|
||||||
/*
|
ElementButton(
|
||||||
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),
|
|
||||||
onClick = {
|
onClick = {
|
||||||
onSignIn()
|
onSignIn()
|
||||||
},
|
},
|
||||||
|
|
@ -131,7 +118,9 @@ fun OnBoardingScreen(
|
||||||
.align(CenterHorizontally)
|
.align(CenterHorizontally)
|
||||||
.testTag(TestTags.onBoardingSignIn)
|
.testTag(TestTags.onBoardingSignIn)
|
||||||
.padding(top = 16.dp)
|
.padding(top = 16.dp)
|
||||||
)
|
) {
|
||||||
|
Text(text = stringResource(id = StringR.string.login_splash_submit))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,12 +26,9 @@ import androidx.compose.foundation.layout.systemBarsPadding
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material3.Button
|
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.OutlinedTextField
|
import androidx.compose.material3.OutlinedTextField
|
||||||
import androidx.compose.material3.Surface
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
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.LabelledCheckbox
|
||||||
import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
|
import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
|
||||||
import io.element.android.libraries.designsystem.components.form.textFieldState
|
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.designsystem.utils.LogCompositions
|
||||||
import io.element.android.libraries.ui.strings.R as StringR
|
import io.element.android.libraries.ui.strings.R as StringR
|
||||||
|
|
||||||
|
|
@ -73,9 +72,8 @@ fun BugReportView(
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
Surface(
|
ElementSurface(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
color = MaterialTheme.colorScheme.background,
|
|
||||||
) {
|
) {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
|
@ -185,7 +183,7 @@ fun BugReportView(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Submit
|
// Submit
|
||||||
Button(
|
ElementButton(
|
||||||
onClick = { eventSink(BugReportEvents.SendBugReport) },
|
onClick = { eventSink(BugReportEvents.SendBugReport) },
|
||||||
enabled = state.submitEnabled,
|
enabled = state.submitEnabled,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.items
|
import androidx.compose.foundation.lazy.items
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Scaffold
|
|
||||||
import androidx.compose.material3.TopAppBarDefaults
|
import androidx.compose.material3.TopAppBarDefaults
|
||||||
import androidx.compose.material3.rememberTopAppBarState
|
import androidx.compose.material3.rememberTopAppBarState
|
||||||
import androidx.compose.runtime.Composable
|
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.RoomListState
|
||||||
import io.element.android.features.roomlist.model.stubbedRoomSummaries
|
import io.element.android.features.roomlist.model.stubbedRoomSummaries
|
||||||
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
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.designsystem.utils.LogCompositions
|
||||||
import io.element.android.libraries.matrix.core.RoomId
|
import io.element.android.libraries.matrix.core.RoomId
|
||||||
import io.element.android.libraries.matrix.core.UserId
|
import io.element.android.libraries.matrix.core.UserId
|
||||||
|
|
@ -117,7 +117,7 @@ fun RoomListView(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Scaffold(
|
ElementScaffold(
|
||||||
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||||
topBar = {
|
topBar = {
|
||||||
RoomListTopBar(
|
RoomListTopBar(
|
||||||
|
|
@ -125,11 +125,15 @@ fun RoomListView(
|
||||||
filter = filter,
|
filter = filter,
|
||||||
onFilterChanged = onFilterChanged,
|
onFilterChanged = onFilterChanged,
|
||||||
onOpenSettings = onOpenSettings,
|
onOpenSettings = onOpenSettings,
|
||||||
scrollBehavior = scrollBehavior
|
scrollBehavior = scrollBehavior,
|
||||||
|
modifier = Modifier,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
content = { padding ->
|
content = { padding ->
|
||||||
Column(modifier = Modifier.padding(padding)) {
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(padding)
|
||||||
|
) {
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ import androidx.compose.material.icons.filled.Settings
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.IconButton
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.MediumTopAppBar
|
import androidx.compose.material3.MediumTopAppBar
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextField
|
import androidx.compose.material3.TextField
|
||||||
|
|
@ -54,6 +53,9 @@ import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import io.element.android.libraries.designsystem.components.avatar.Avatar
|
import io.element.android.libraries.designsystem.components.avatar.Avatar
|
||||||
import io.element.android.libraries.designsystem.components.form.textFieldState
|
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.designsystem.utils.LogCompositions
|
||||||
import io.element.android.libraries.matrix.ui.model.MatrixUser
|
import io.element.android.libraries.matrix.ui.model.MatrixUser
|
||||||
import io.element.android.libraries.ui.strings.R as StringR
|
import io.element.android.libraries.ui.strings.R as StringR
|
||||||
|
|
@ -64,7 +66,8 @@ fun RoomListTopBar(
|
||||||
filter: String,
|
filter: String,
|
||||||
onFilterChanged: (String) -> Unit,
|
onFilterChanged: (String) -> Unit,
|
||||||
onOpenSettings: () -> Unit,
|
onOpenSettings: () -> Unit,
|
||||||
scrollBehavior: TopAppBarScrollBehavior
|
scrollBehavior: TopAppBarScrollBehavior,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
LogCompositions(
|
LogCompositions(
|
||||||
tag = "RoomListScreen",
|
tag = "RoomListScreen",
|
||||||
|
|
@ -87,6 +90,7 @@ fun RoomListTopBar(
|
||||||
onFilterChanged = onFilterChanged,
|
onFilterChanged = onFilterChanged,
|
||||||
onCloseClicked = ::closeFilter,
|
onCloseClicked = ::closeFilter,
|
||||||
scrollBehavior = scrollBehavior,
|
scrollBehavior = scrollBehavior,
|
||||||
|
modifier = modifier,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
DefaultRoomListTopBar(
|
DefaultRoomListTopBar(
|
||||||
|
|
@ -96,6 +100,7 @@ fun RoomListTopBar(
|
||||||
searchWidgetStateIsOpened = true
|
searchWidgetStateIsOpened = true
|
||||||
},
|
},
|
||||||
scrollBehavior = scrollBehavior,
|
scrollBehavior = scrollBehavior,
|
||||||
|
modifier = modifier,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -110,7 +115,7 @@ fun SearchRoomListTopBar(
|
||||||
) {
|
) {
|
||||||
var filterState by textFieldState(stateValue = text)
|
var filterState by textFieldState(stateValue = text)
|
||||||
val focusRequester = remember { FocusRequester() }
|
val focusRequester = remember { FocusRequester() }
|
||||||
TopAppBar(
|
ElementTopAppBar(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.nestedScroll(scrollBehavior.nestedScrollConnection),
|
.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||||
title = {
|
title = {
|
||||||
|
|
@ -129,7 +134,7 @@ fun SearchRoomListTopBar(
|
||||||
placeholder = {
|
placeholder = {
|
||||||
Text(
|
Text(
|
||||||
text = "Search",
|
text = "Search",
|
||||||
color = MaterialTheme.colorScheme.onBackground.copy(alpha = ContentAlpha.medium)
|
color = ElementTheme.colors.onBackground.copy(alpha = ContentAlpha.medium)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
singleLine = true,
|
singleLine = true,
|
||||||
|
|
@ -143,15 +148,15 @@ fun SearchRoomListTopBar(
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Default.Close,
|
imageVector = Icons.Default.Close,
|
||||||
contentDescription = "clear",
|
contentDescription = "clear",
|
||||||
tint = MaterialTheme.colorScheme.onBackground
|
tint = ElementTheme.colors.onBackground
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
colors = TextFieldDefaults.textFieldColors(
|
colors = TextFieldDefaults.textFieldColors(
|
||||||
textColor = MaterialTheme.colorScheme.onBackground,
|
textColor = ElementTheme.colors.onBackground,
|
||||||
containerColor = Color.Transparent,
|
containerColor = Color.Transparent,
|
||||||
cursorColor = MaterialTheme.colorScheme.onBackground.copy(alpha = ContentAlpha.medium),
|
cursorColor = ElementTheme.colors.onBackground.copy(alpha = ContentAlpha.medium),
|
||||||
focusedIndicatorColor = Color.Transparent,
|
focusedIndicatorColor = Color.Transparent,
|
||||||
unfocusedIndicatorColor = Color.Transparent,
|
unfocusedIndicatorColor = Color.Transparent,
|
||||||
disabledIndicatorColor = Color.Transparent
|
disabledIndicatorColor = Color.Transparent
|
||||||
|
|
@ -167,7 +172,7 @@ fun SearchRoomListTopBar(
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Default.ArrowBack,
|
imageVector = Icons.Default.ArrowBack,
|
||||||
contentDescription = "close",
|
contentDescription = "close",
|
||||||
tint = MaterialTheme.colorScheme.onBackground
|
tint = ElementTheme.colors.onBackground
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -182,10 +187,11 @@ private fun DefaultRoomListTopBar(
|
||||||
matrixUser: MatrixUser?,
|
matrixUser: MatrixUser?,
|
||||||
onOpenSettings: () -> Unit,
|
onOpenSettings: () -> Unit,
|
||||||
onSearchClicked: () -> Unit,
|
onSearchClicked: () -> Unit,
|
||||||
scrollBehavior: TopAppBarScrollBehavior
|
scrollBehavior: TopAppBarScrollBehavior,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
) {
|
) {
|
||||||
MediumTopAppBar(
|
ElementMediumAppBar(
|
||||||
modifier = Modifier
|
modifier = modifier
|
||||||
.nestedScroll(scrollBehavior.nestedScrollConnection),
|
.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||||
title = {
|
title = {
|
||||||
Text(
|
Text(
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,6 @@ import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
import androidx.compose.foundation.shape.CircleShape
|
||||||
import androidx.compose.material.ripple.rememberRipple
|
import androidx.compose.material.ripple.rememberRipple
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
|
@ -54,6 +53,7 @@ import androidx.compose.ui.unit.sp
|
||||||
import com.google.accompanist.placeholder.material.placeholder
|
import com.google.accompanist.placeholder.material.placeholder
|
||||||
import io.element.android.features.roomlist.model.RoomListRoomSummary
|
import io.element.android.features.roomlist.model.RoomListRoomSummary
|
||||||
import io.element.android.libraries.designsystem.components.avatar.Avatar
|
import io.element.android.libraries.designsystem.components.avatar.Avatar
|
||||||
|
import io.element.android.libraries.designsystem.theme.ElementTheme
|
||||||
|
|
||||||
private val minHeight = 72.dp
|
private val minHeight = 72.dp
|
||||||
|
|
||||||
|
|
@ -117,7 +117,7 @@ internal fun DefaultRoomSummaryRow(
|
||||||
Text(
|
Text(
|
||||||
modifier = Modifier.placeholder(room.isPlaceholder, shape = TextPlaceholderShape),
|
modifier = Modifier.placeholder(room.isPlaceholder, shape = TextPlaceholderShape),
|
||||||
text = room.lastMessage?.toString().orEmpty(),
|
text = room.lastMessage?.toString().orEmpty(),
|
||||||
color = MaterialTheme.colorScheme.secondary,
|
color = ElementTheme.colors.secondary,
|
||||||
fontSize = 14.sp,
|
fontSize = 14.sp,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
overflow = TextOverflow.Ellipsis
|
overflow = TextOverflow.Ellipsis
|
||||||
|
|
@ -132,11 +132,11 @@ internal fun DefaultRoomSummaryRow(
|
||||||
modifier = Modifier.placeholder(room.isPlaceholder, shape = TextPlaceholderShape),
|
modifier = Modifier.placeholder(room.isPlaceholder, shape = TextPlaceholderShape),
|
||||||
fontSize = 12.sp,
|
fontSize = 12.sp,
|
||||||
text = room.timestamp ?: "",
|
text = room.timestamp ?: "",
|
||||||
color = MaterialTheme.colorScheme.secondary,
|
color = ElementTheme.colors.secondary,
|
||||||
)
|
)
|
||||||
Spacer(Modifier.size(4.dp))
|
Spacer(Modifier.size(4.dp))
|
||||||
val unreadIndicatorColor =
|
val unreadIndicatorColor =
|
||||||
if (room.hasUnread) MaterialTheme.colorScheme.primary else Color.Transparent
|
if (room.hasUnread) ElementTheme.colors.primary else Color.Transparent
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.size(12.dp)
|
.size(12.dp)
|
||||||
|
|
|
||||||
|
|
@ -16,15 +16,15 @@
|
||||||
|
|
||||||
package io.element.android.libraries.designsystem
|
package io.element.android.libraries.designsystem
|
||||||
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import io.element.android.libraries.designsystem.theme.ElementTheme
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun Boolean.toEnabledColor(): Color {
|
fun Boolean.toEnabledColor(): Color {
|
||||||
return if (this) {
|
return if (this) {
|
||||||
MaterialTheme.colorScheme.primary
|
ElementTheme.colors.primary
|
||||||
} else {
|
} else {
|
||||||
MaterialTheme.colorScheme.secondary
|
ElementTheme.colors.secondary
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
|
||||||
)
|
|
||||||
|
|
@ -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<Boolean> { 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
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -23,48 +23,8 @@ import androidx.compose.ui.text.font.FontStyle
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.sp
|
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 ElementTextStyles {
|
||||||
|
|
||||||
object Bold {
|
object Bold {
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import io.element.android.libraries.designsystem.theme.components.ElementCheckbox
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun LabelledCheckbox(
|
fun LabelledCheckbox(
|
||||||
|
|
@ -37,7 +38,7 @@ fun LabelledCheckbox(
|
||||||
modifier = modifier.fillMaxWidth(),
|
modifier = modifier.fillMaxWidth(),
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
Checkbox(
|
ElementCheckbox(
|
||||||
checked = checked,
|
checked = checked,
|
||||||
onCheckedChange = onCheckedChange,
|
onCheckedChange = onCheckedChange,
|
||||||
enabled = enabled,
|
enabled = enabled,
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
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.unit.dp
|
||||||
import androidx.compose.ui.window.Dialog
|
import androidx.compose.ui.window.Dialog
|
||||||
import androidx.compose.ui.window.DialogProperties
|
import androidx.compose.ui.window.DialogProperties
|
||||||
|
import io.element.android.libraries.designsystem.theme.ElementTheme
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ProgressDialog(
|
fun ProgressDialog(
|
||||||
|
|
@ -48,19 +48,19 @@ fun ProgressDialog(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.background(
|
.background(
|
||||||
color = MaterialTheme.colorScheme.onBackground,
|
color = ElementTheme.colors.onBackground,
|
||||||
shape = RoundedCornerShape(8.dp)
|
shape = RoundedCornerShape(8.dp)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
Column(horizontalAlignment = Alignment.CenterHorizontally) {
|
||||||
CircularProgressIndicator(
|
CircularProgressIndicator(
|
||||||
modifier = Modifier.padding(16.dp),
|
modifier = Modifier.padding(16.dp),
|
||||||
color = MaterialTheme.colorScheme.background
|
color = ElementTheme.colors.background
|
||||||
)
|
)
|
||||||
if (!text.isNullOrBlank()) {
|
if (!text.isNullOrBlank()) {
|
||||||
Text(
|
Text(
|
||||||
text = text,
|
text = text,
|
||||||
color = MaterialTheme.colorScheme.background,
|
color = ElementTheme.colors.background,
|
||||||
modifier = Modifier.padding(16.dp)
|
modifier = Modifier.padding(16.dp)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,13 +22,18 @@ import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material3.AlertDialog
|
import androidx.compose.material3.AlertDialog
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.AlertDialogDefaults
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
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.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
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
|
import io.element.android.libraries.ui.strings.R as StringR
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|
@ -43,6 +48,12 @@ fun ConfirmationDialog(
|
||||||
onCancelClicked: () -> Unit = {},
|
onCancelClicked: () -> Unit = {},
|
||||||
onThirdButtonClicked: () -> Unit = {},
|
onThirdButtonClicked: () -> Unit = {},
|
||||||
onDismiss: () -> 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(
|
AlertDialog(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
|
|
@ -59,7 +70,7 @@ fun ConfirmationDialog(
|
||||||
horizontalArrangement = Arrangement.Center
|
horizontalArrangement = Arrangement.Center
|
||||||
) {
|
) {
|
||||||
Column {
|
Column {
|
||||||
Button(
|
ElementButton(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
onClick = {
|
onClick = {
|
||||||
onCancelClicked()
|
onCancelClicked()
|
||||||
|
|
@ -67,7 +78,7 @@ fun ConfirmationDialog(
|
||||||
Text(cancelText)
|
Text(cancelText)
|
||||||
}
|
}
|
||||||
if (thirdButtonText != null) {
|
if (thirdButtonText != null) {
|
||||||
Button(
|
ElementButton(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
onClick = {
|
onClick = {
|
||||||
onThirdButtonClicked()
|
onThirdButtonClicked()
|
||||||
|
|
@ -83,7 +94,7 @@ fun ConfirmationDialog(
|
||||||
modifier = Modifier.padding(all = 8.dp),
|
modifier = Modifier.padding(all = 8.dp),
|
||||||
horizontalArrangement = Arrangement.Center
|
horizontalArrangement = Arrangement.Center
|
||||||
) {
|
) {
|
||||||
Button(
|
ElementButton(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
onClick = {
|
onClick = {
|
||||||
onSubmitClicked()
|
onSubmitClicked()
|
||||||
|
|
@ -93,6 +104,12 @@ fun ConfirmationDialog(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
shape = shape,
|
||||||
|
containerColor = containerColor,
|
||||||
|
iconContentColor = iconContentColor,
|
||||||
|
titleContentColor = titleContentColor,
|
||||||
|
textContentColor = textContentColor,
|
||||||
|
tonalElevation = tonalElevation,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,13 +21,18 @@ import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material3.AlertDialog
|
import androidx.compose.material3.AlertDialog
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.AlertDialogDefaults
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
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.res.stringResource
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
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
|
import io.element.android.libraries.ui.strings.R as StringR
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|
@ -37,6 +42,12 @@ fun ErrorDialog(
|
||||||
title: String = stringResource(id = StringR.string.dialog_title_error),
|
title: String = stringResource(id = StringR.string.dialog_title_error),
|
||||||
submitText: String = stringResource(id = StringR.string.ok),
|
submitText: String = stringResource(id = StringR.string.ok),
|
||||||
onDismiss: () -> 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(
|
AlertDialog(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
|
|
@ -52,7 +63,7 @@ fun ErrorDialog(
|
||||||
modifier = Modifier.padding(all = 8.dp),
|
modifier = Modifier.padding(all = 8.dp),
|
||||||
horizontalArrangement = Arrangement.Center
|
horizontalArrangement = Arrangement.Center
|
||||||
) {
|
) {
|
||||||
Button(
|
ElementButton(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
onClick = {
|
onClick = {
|
||||||
onDismiss()
|
onDismiss()
|
||||||
|
|
@ -62,6 +73,12 @@ fun ErrorDialog(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
shape = shape,
|
||||||
|
containerColor = containerColor,
|
||||||
|
iconContentColor = iconContentColor,
|
||||||
|
titleContentColor = titleContentColor,
|
||||||
|
textContentColor = textContentColor,
|
||||||
|
tonalElevation = tonalElevation,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,12 +21,12 @@ import androidx.compose.foundation.layout.ColumnScope
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material3.Divider
|
import androidx.compose.material3.Divider
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
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.ElementTheme
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun PreferenceCategory(
|
fun PreferenceCategory(
|
||||||
|
|
@ -40,12 +40,12 @@ fun PreferenceCategory(
|
||||||
) {
|
) {
|
||||||
Divider(
|
Divider(
|
||||||
modifier = Modifier.padding(horizontal = 16.dp),
|
modifier = Modifier.padding(horizontal = 16.dp),
|
||||||
color = MaterialTheme.colorScheme.secondary,
|
color = ElementTheme.colors.secondary,
|
||||||
thickness = 1.dp
|
thickness = 1.dp
|
||||||
)
|
)
|
||||||
Text(
|
Text(
|
||||||
modifier = Modifier.padding(top = 8.dp, start = 56.dp),
|
modifier = Modifier.padding(top = 8.dp, start = 56.dp),
|
||||||
style = MaterialTheme.typography.titleSmall,
|
style = ElementTheme.typography.titleSmall,
|
||||||
text = title
|
text = title
|
||||||
)
|
)
|
||||||
content()
|
content()
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,8 @@ import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.sp
|
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)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
|
|
@ -51,7 +53,7 @@ fun PreferenceView(
|
||||||
onBackPressed: () -> Unit = {},
|
onBackPressed: () -> Unit = {},
|
||||||
content: @Composable ColumnScope.() -> Unit,
|
content: @Composable ColumnScope.() -> Unit,
|
||||||
) {
|
) {
|
||||||
Scaffold(
|
ElementScaffold(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.systemBarsPadding()
|
.systemBarsPadding()
|
||||||
|
|
@ -85,7 +87,7 @@ fun PreferenceTopAppBar(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
onBackPressed: () -> Unit = {},
|
onBackPressed: () -> Unit = {},
|
||||||
) {
|
) {
|
||||||
TopAppBar(
|
ElementTopAppBar(
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
IconButton(onClick = onBackPressed) {
|
IconButton(onClick = onBackPressed) {
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.defaultMinSize
|
import androidx.compose.foundation.layout.defaultMinSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Slider
|
import androidx.compose.material3.Slider
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
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.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import io.element.android.libraries.designsystem.components.preferences.components.PreferenceIcon
|
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
|
import io.element.android.libraries.designsystem.toEnabledColor
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|
@ -61,19 +62,19 @@ fun PreferenceSlide(
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
style = MaterialTheme.typography.bodyLarge,
|
style = ElementTheme.typography.bodyLarge,
|
||||||
color = enabled.toEnabledColor(),
|
color = enabled.toEnabledColor(),
|
||||||
text = title
|
text = title
|
||||||
)
|
)
|
||||||
summary?.let {
|
summary?.let {
|
||||||
Text(
|
Text(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
style = ElementTheme.typography.bodyMedium,
|
||||||
color = enabled.toEnabledColor(),
|
color = enabled.toEnabledColor(),
|
||||||
text = summary
|
text = summary
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Slider(
|
ElementSlider(
|
||||||
value = value,
|
value = value,
|
||||||
steps = steps,
|
steps = steps,
|
||||||
onValueChange = onValueChange,
|
onValueChange = onValueChange,
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Announcement
|
import androidx.compose.material.icons.filled.Announcement
|
||||||
import androidx.compose.material3.Checkbox
|
import androidx.compose.material3.Checkbox
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
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.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import io.element.android.libraries.designsystem.components.preferences.components.PreferenceIcon
|
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
|
import io.element.android.libraries.designsystem.toEnabledColor
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|
@ -61,11 +62,11 @@ fun PreferenceSwitch(
|
||||||
)
|
)
|
||||||
Text(
|
Text(
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
style = MaterialTheme.typography.bodyLarge,
|
style = ElementTheme.typography.bodyLarge,
|
||||||
color = enabled.toEnabledColor(),
|
color = enabled.toEnabledColor(),
|
||||||
text = title
|
text = title
|
||||||
)
|
)
|
||||||
Checkbox(
|
ElementCheckbox(
|
||||||
modifier = Modifier.padding(end = preferencePaddingEnd),
|
modifier = Modifier.padding(end = preferencePaddingEnd),
|
||||||
checked = isChecked,
|
checked = isChecked,
|
||||||
enabled = enabled,
|
enabled = enabled,
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.BugReport
|
import androidx.compose.material.icons.filled.BugReport
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
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.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import io.element.android.libraries.designsystem.components.preferences.components.PreferenceIcon
|
import io.element.android.libraries.designsystem.components.preferences.components.PreferenceIcon
|
||||||
|
import io.element.android.libraries.designsystem.theme.ElementTheme
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun PreferenceText(
|
fun PreferenceText(
|
||||||
|
|
@ -56,7 +56,7 @@ fun PreferenceText(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.padding(end = preferencePaddingEnd),
|
.padding(end = preferencePaddingEnd),
|
||||||
style = MaterialTheme.typography.bodyLarge,
|
style = ElementTheme.typography.bodyLarge,
|
||||||
text = title
|
text = title
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
)
|
||||||
|
*/
|
||||||
|
|
@ -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,
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -14,20 +14,14 @@
|
||||||
* limitations under the License.
|
* 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.ui.unit.Dp
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
|
|
||||||
@Composable
|
data class ElementSpaces(
|
||||||
fun VectorButton(text: String, enabled: Boolean, onClick: () -> Unit, modifier: Modifier = Modifier) {
|
val small: Dp = 4.dp,
|
||||||
Button(
|
val medium: Dp = 8.dp,
|
||||||
onClick = onClick,
|
val large: Dp = 16.dp,
|
||||||
enabled = enabled,
|
val extraLarge: Dp = 40.dp,
|
||||||
modifier = modifier
|
)
|
||||||
) {
|
|
||||||
Text(text = text)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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,
|
||||||
|
)
|
||||||
|
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -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<Float> = 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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -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,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -23,7 +23,6 @@ import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
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.Avatar
|
||||||
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
||||||
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
|
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.core.UserId
|
||||||
import io.element.android.libraries.matrix.ui.model.MatrixUser
|
import io.element.android.libraries.matrix.ui.model.MatrixUser
|
||||||
import io.element.android.libraries.matrix.ui.model.getBestName
|
import io.element.android.libraries.matrix.ui.model.getBestName
|
||||||
|
|
@ -71,7 +71,7 @@ fun MatrixUserHeader(
|
||||||
Spacer(modifier = Modifier.height(4.dp))
|
Spacer(modifier = Modifier.height(4.dp))
|
||||||
Text(
|
Text(
|
||||||
text = matrixUser.id.value,
|
text = matrixUser.id.value,
|
||||||
color = MaterialTheme.colorScheme.secondary,
|
color = ElementTheme.colors.secondary,
|
||||||
fontSize = 14.sp,
|
fontSize = 14.sp,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
overflow = TextOverflow.Ellipsis
|
overflow = TextOverflow.Ellipsis
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
|
|
@ -35,6 +34,7 @@ import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import io.element.android.libraries.designsystem.components.avatar.Avatar
|
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.AvatarData
|
||||||
|
import io.element.android.libraries.designsystem.theme.ElementTheme
|
||||||
import io.element.android.libraries.matrix.core.UserId
|
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.MatrixUser
|
||||||
import io.element.android.libraries.matrix.ui.model.getBestName
|
import io.element.android.libraries.matrix.ui.model.getBestName
|
||||||
|
|
@ -74,7 +74,7 @@ fun MatrixUserRow(
|
||||||
if (matrixUser.username.isNullOrEmpty().not()) {
|
if (matrixUser.username.isNullOrEmpty().not()) {
|
||||||
Text(
|
Text(
|
||||||
text = matrixUser.id.value,
|
text = matrixUser.id.value,
|
||||||
color = MaterialTheme.colorScheme.secondary,
|
color = ElementTheme.colors.secondary,
|
||||||
fontSize = 14.sp,
|
fontSize = 14.sp,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
overflow = TextOverflow.Ellipsis
|
overflow = TextOverflow.Ellipsis
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
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
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ShowkaseButton(
|
fun ShowkaseButton(
|
||||||
|
|
@ -41,7 +42,7 @@ fun ShowkaseButton(
|
||||||
var isShowkaseButtonVisible by remember { mutableStateOf(BuildConfig.DEBUG) }
|
var isShowkaseButtonVisible by remember { mutableStateOf(BuildConfig.DEBUG) }
|
||||||
|
|
||||||
if (isShowkaseButtonVisible) {
|
if (isShowkaseButtonVisible) {
|
||||||
Button(
|
ElementButton(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
.padding(top = 32.dp),
|
.padding(top = 32.dp),
|
||||||
onClick = onClick
|
onClick = onClick
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ import androidx.activity.OnBackPressedDispatcherOwner
|
||||||
import androidx.activity.compose.LocalOnBackPressedDispatcherOwner
|
import androidx.activity.compose.LocalOnBackPressedDispatcherOwner
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalConfiguration
|
import androidx.compose.ui.platform.LocalConfiguration
|
||||||
|
|
@ -36,7 +35,7 @@ import app.cash.paparazzi.Paparazzi
|
||||||
import com.airbnb.android.showkase.models.Showkase
|
import com.airbnb.android.showkase.models.Showkase
|
||||||
import com.google.testing.junit.testparameterinjector.TestParameter
|
import com.google.testing.junit.testparameterinjector.TestParameter
|
||||||
import com.google.testing.junit.testparameterinjector.TestParameterInjector
|
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.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
|
|
@ -101,8 +100,8 @@ class ScreenshotTest {
|
||||||
override fun getOnBackPressedDispatcher() = OnBackPressedDispatcher()
|
override fun getOnBackPressedDispatcher() = OnBackPressedDispatcher()
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
ElementXTheme(darkTheme = (theme == "dark")) {
|
ElementTheme(darkTheme = (theme == "dark")) {
|
||||||
Box(modifier = Modifier.background(MaterialTheme.colorScheme.background)) {
|
Box(modifier = Modifier.background(ElementTheme.colors.background)) {
|
||||||
componentTestPreview.Content()
|
componentTestPreview.Content()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,11 @@ package io.element.android.tests.uitests
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.text.BasicText
|
import androidx.compose.foundation.text.BasicText
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import com.airbnb.android.showkase.models.ShowkaseBrowserTypography
|
import com.airbnb.android.showkase.models.ShowkaseBrowserTypography
|
||||||
import com.airbnb.android.showkase.ui.padding4x
|
import com.airbnb.android.showkase.ui.padding4x
|
||||||
|
import io.element.android.libraries.designsystem.theme.ElementTheme
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
class TypographyTestPreview(
|
class TypographyTestPreview(
|
||||||
|
|
@ -39,7 +39,7 @@ class TypographyTestPreview(
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(padding4x),
|
.padding(padding4x),
|
||||||
style = showkaseBrowserTypography.textStyle.copy(
|
style = showkaseBrowserTypography.textStyle.copy(
|
||||||
color = MaterialTheme.colorScheme.onBackground
|
color = ElementTheme.colors.onBackground
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue