Merge branch 'develop' into feature/fga/room_list_api

This commit is contained in:
ganfra 2023-06-28 15:14:06 +02:00
commit 8e5c2a749a
935 changed files with 6059 additions and 3293 deletions

View file

@ -242,6 +242,19 @@ fun startImportTextFromFileIntent(
}
}
@Suppress("SwallowedException")
fun Context.openUrlInExternalApp(
url: String,
errorMessage: String = getString(R.string.error_no_compatible_app_found),
) {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
try {
startActivity(intent)
} catch (activityNotFoundException: ActivityNotFoundException) {
toast(errorMessage)
}
}
// Not in KTX anymore
fun Context.toast(resId: Int) {
Toast.makeText(this, resId, Toast.LENGTH_SHORT).show()

View file

@ -26,4 +26,8 @@ dependencies {
api(libs.dagger)
api(libs.appyx.core)
api(libs.androidx.lifecycle.runtime)
testImplementation(libs.test.junit)
testImplementation(libs.coroutines.test)
testImplementation(libs.test.truth)
}

View file

@ -18,51 +18,152 @@ package io.element.android.libraries.architecture
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.Stable
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
/**
* Sealed type that allows to model an asynchronous operation.
*/
@Stable
sealed interface Async<out T> {
/**
* Represents a failed operation.
*
* @param T the type of data returned by the operation.
* @property error the error that caused the operation to fail.
* @property prevData the data returned by a previous successful run of the operation if any.
*/
data class Failure<out T>(
val error: Throwable,
val prevData: T? = null,
) : Async<T>
/**
* Represents an operation that is currently ongoing.
*
* @param T the type of data returned by the operation.
* @property prevData the data returned by a previous successful run of the operation if any.
*/
data class Loading<out T>(
val prevData: T? = null,
) : Async<T>
/**
* Represents a successful operation.
*
* @param T the type of data returned by the operation.
* @property data the data returned by the operation.
*/
data class Success<out T>(
val data: T,
) : Async<T>
/**
* Represents an uninitialized operation (i.e. yet to be run).
*/
object Uninitialized : Async<Nothing>
data class Loading<out T>(val prevState: T? = null) : Async<T>
data class Failure<out T>(val error: Throwable, val prevState: T? = null) : Async<T>
data class Success<out T>(val state: T) : Async<T>
fun dataOrNull(): T? {
return when (this) {
is Failure -> prevState
is Loading -> prevState
is Success -> state
Uninitialized -> null
/**
* Returns the data returned by the operation, or null otherwise.
*
* Please note this method may return stale data if the operation is not [Success].
*/
fun dataOrNull(): T? = when (this) {
is Failure -> prevData
is Loading -> prevData
is Success -> data
Uninitialized -> null
}
/**
* Returns the error that caused the operation to fail, or null otherwise.
*/
fun errorOrNull(): Throwable? = when (this) {
is Failure -> error
else -> null
}
fun isFailure(): Boolean = this is Failure<T>
fun isLoading(): Boolean = this is Loading<T>
fun isSuccess(): Boolean = this is Success<T>
fun isUninitialized(): Boolean = this == Uninitialized
}
suspend inline fun <T> MutableState<Async<T>>.runCatchingUpdatingState(
errorTransform: (Throwable) -> Throwable = { it },
block: () -> T,
): Result<T> = runUpdatingState(
state = this,
errorTransform = errorTransform,
resultBlock = {
runCatching {
block()
}
}
}
},
)
suspend inline fun <T> (suspend () -> T).execute(
suspend inline fun <T> (suspend () -> T).runCatchingUpdatingState(
state: MutableState<Async<T>>,
errorMapping: ((Throwable) -> Throwable) = { it },
) {
try {
state.value = Async.Loading()
val result = this()
state.value = Async.Success(result)
} catch (error: Throwable) {
state.value = Async.Failure(errorMapping.invoke(error))
}
}
errorTransform: (Throwable) -> Throwable = { it },
): Result<T> = runUpdatingState(
state = state,
errorTransform = errorTransform,
resultBlock = {
runCatching {
this()
}
},
)
suspend inline fun <T> (suspend () -> Result<T>).executeResult(state: MutableState<Async<T>>) {
if (state.value !is Async.Success) {
state.value = Async.Loading()
suspend inline fun <T> MutableState<Async<T>>.runUpdatingState(
errorTransform: (Throwable) -> Throwable = { it },
resultBlock: () -> Result<T>,
): Result<T> = runUpdatingState(
state = this,
errorTransform = errorTransform,
resultBlock = resultBlock,
)
/**
* Calls the specified [Result]-returning function [resultBlock]
* encapsulating its progress and return value into an [Async] while
* posting its updates to the MutableState [state].
*
* @param T the type of data returned by the operation.
* @param state the [MutableState] to post updates to.
* @param errorTransform a function to transform the error before posting it.
* @param resultBlock a suspending function that returns a [Result].
* @return the [Result] returned by [resultBlock].
*/
@OptIn(ExperimentalContracts::class)
@Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE")
suspend inline fun <T> runUpdatingState(
state: MutableState<Async<T>>,
errorTransform: (Throwable) -> Throwable = { it },
resultBlock: suspend () -> Result<T>,
): Result<T> {
contract {
callsInPlace(resultBlock, InvocationKind.EXACTLY_ONCE)
}
this().fold(
val prevData = state.value.dataOrNull()
state.value = Async.Loading(prevData = prevData)
return resultBlock().fold(
onSuccess = {
state.value = Async.Success(it)
Result.success(it)
},
onFailure = {
state.value = Async.Failure(it)
val error = errorTransform(it)
state.value = Async.Failure(
error = error,
prevData = prevData,
)
Result.failure(error)
}
)
}
fun <T> Async<T>.isLoading(): Boolean {
return this is Async.Loading<T>
}

View file

@ -0,0 +1,113 @@
/*
* 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.architecture
import androidx.compose.runtime.MutableState
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.delay
import kotlinx.coroutines.test.runTest
import org.junit.Test
class AsyncKtTest {
@Test
fun `updates state when block returns success`() = runTest {
val state = TestableMutableState<Async<Int>>(Async.Uninitialized)
val result = runUpdatingState(state) {
delay(1)
Result.success(1)
}
assertThat(result.isSuccess).isTrue()
assertThat(result.getOrNull()).isEqualTo(1)
assertThat(state.popFirst()).isEqualTo(Async.Uninitialized)
assertThat(state.popFirst()).isEqualTo(Async.Loading(null))
assertThat(state.popFirst()).isEqualTo(Async.Success(1))
state.assertNoMoreValues()
}
@Test
fun `updates state when block returns failure`() = runTest {
val state = TestableMutableState<Async<Int>>(Async.Uninitialized)
val result = runUpdatingState(state) {
delay(1)
Result.failure(MyThrowable("hello"))
}
assertThat(result.isFailure).isTrue()
assertThat(result.exceptionOrNull()).isEqualTo(MyThrowable("hello"))
assertThat(state.popFirst()).isEqualTo(Async.Uninitialized)
assertThat(state.popFirst()).isEqualTo(Async.Loading(null))
assertThat(state.popFirst()).isEqualTo(Async.Failure<Int>(MyThrowable("hello")))
state.assertNoMoreValues()
}
@Test
fun `updates state when block returns failure transforming the error`() = runTest {
val state = TestableMutableState<Async<Int>>(Async.Uninitialized)
val result = runUpdatingState(state, { MyThrowable(it.message + " world") }) {
delay(1)
Result.failure(MyThrowable("hello"))
}
assertThat(result.isFailure).isTrue()
assertThat(result.exceptionOrNull()).isEqualTo(MyThrowable("hello world"))
assertThat(state.popFirst()).isEqualTo(Async.Uninitialized)
assertThat(state.popFirst()).isEqualTo(Async.Loading(null))
assertThat(state.popFirst()).isEqualTo(Async.Failure<Int>(MyThrowable("hello world")))
state.assertNoMoreValues()
}
}
/**
* A fake [MutableState] that allows to record all the states that were set.
*/
private class TestableMutableState<T>(
value: T
) : MutableState<T> {
private val _deque = ArrayDeque<T>(listOf(value))
override var value: T
get() = _deque.last()
set(value) {
_deque.addLast(value)
}
/**
* Returns the states that were set in the order they were set.
*/
fun popFirst(): T = _deque.removeFirst()
fun assertNoMoreValues() {
assertThat(_deque).isEmpty()
}
override operator fun component1(): T = value
override operator fun component2(): (T) -> Unit = { value = it }
}
/**
* An exception that is also a data class so we can compare it using equals.
*/
private data class MyThrowable(val myMessage: String) : Throwable(myMessage)

View file

@ -30,8 +30,12 @@ dependencies {
implementation(projects.libraries.di)
implementation(libs.dagger)
implementation(libs.androidx.corektx)
implementation(projects.libraries.core)
implementation(projects.libraries.matrix.api)
implementation(projects.libraries.androidutils)
implementation(projects.libraries.architecture)
implementation(projects.libraries.uiStrings)
implementation(projects.services.toolbox.api)
testImplementation(libs.test.junit)
testImplementation(libs.test.truth)

View file

@ -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.deeplink.usecase
import android.app.Activity
import io.element.android.libraries.androidutils.system.startSharePlainTextIntent
import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.permalink.PermalinkBuilder
import io.element.android.services.toolbox.api.strings.StringProvider
import timber.log.Timber
import javax.inject.Inject
import io.element.android.libraries.androidutils.R as AndroidUtilsR
import io.element.android.libraries.ui.strings.CommonStrings
class InviteFriendsUseCase @Inject constructor(
private val stringProvider: StringProvider,
private val matrixClient: MatrixClient,
private val buildMeta: BuildMeta,
) {
fun execute(activity: Activity) {
val permalinkResult = PermalinkBuilder.permalinkForUser(matrixClient.sessionId)
permalinkResult.fold(
onSuccess = { permalink ->
val appName = buildMeta.applicationName
startSharePlainTextIntent(
context = activity,
activityResultLauncher = null,
chooserTitle = stringProvider.getString(CommonStrings.action_invite_friends),
text = stringProvider.getString(CommonStrings.invite_friends_text, appName, permalink),
extraTitle = stringProvider.getString(CommonStrings.invite_friends_rich_title, appName),
noActivityFoundMessage = stringProvider.getString(AndroidUtilsR.string.error_no_compatible_app_found)
)
},
onFailure = {
Timber.e(it)
}
)
}
}

View file

@ -28,11 +28,10 @@ android {
}
dependencies {
api(projects.libraries.theme)
// Should not be there, but this is a POC
implementation(libs.coil.compose)
implementation(libs.accompanist.systemui)
implementation(libs.vanniktech.blurhash)
implementation(projects.libraries.elementresources)
implementation(projects.libraries.uiStrings)
ksp(libs.showkase.processor)

View file

@ -0,0 +1,71 @@
/*
* 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.atomic.atoms
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
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.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.theme.ElementTheme
@Composable
fun PlaceholderAtom(
width: Dp,
height: Dp,
modifier: Modifier = Modifier,
color: Color = ElementTheme.colors.textPlaceholder,
) {
Box(
modifier = modifier
.width(width)
.height(height)
.background(
color = color,
shape = RoundedCornerShape(size = height / 2)
)
)
}
@Preview
@Composable
internal fun PlaceholderAtomLightPreview() =
ElementPreviewLight { ContentToPreview() }
@Preview
@Composable
internal fun PlaceholderAtomDarkPreview() =
ElementPreviewDark { ContentToPreview() }
@Composable
private fun ContentToPreview() {
// Use a Red background to see the shape
Box(modifier = Modifier.background(color = Color.Red)) {
PlaceholderAtom(
width = 80.dp,
height = 12.dp
)
}
}

View file

@ -35,8 +35,8 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.theme.LocalColors
import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.theme.ElementTheme
/**
* RoundedIconAtom is an atom which displays an icon inside a rounded container.
@ -59,7 +59,7 @@ fun RoundedIconAtom(
modifier = modifier
.size(size.toContainerSize())
.background(
color = LocalColors.current.quinary,
color = ElementTheme.legacyColors.quinary,
shape = RoundedCornerShape(size.toCornerSize())
)
) {

View file

@ -0,0 +1,62 @@
/*
* 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.atomic.atoms
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
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.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.theme.roomListUnreadIndicator
@Composable
fun UnreadIndicatorAtom(
modifier: Modifier = Modifier,
size: Dp = 12.dp,
color: Color = MaterialTheme.roomListUnreadIndicator(),
) {
Box(
modifier = modifier
.size(size)
.clip(CircleShape)
.background(color)
)
}
@Preview
@Composable
internal fun UnreadIndicatorAtomLightPreview() =
ElementPreviewLight { ContentToPreview() }
@Preview
@Composable
internal fun UnreadIndicatorAtomDarkPreview() =
ElementPreviewDark { ContentToPreview() }
@Composable
private fun ContentToPreview() {
UnreadIndicatorAtom()
}

View file

@ -31,7 +31,7 @@ import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.theme.components.Button
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.ui.strings.R as StringR
import io.element.android.libraries.ui.strings.CommonStrings
@Composable
fun AsyncFailure(
@ -45,11 +45,11 @@ fun AsyncFailure(
.padding(vertical = 32.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(text = throwable.message ?: stringResource(id = StringR.string.error_unknown))
Text(text = throwable.message ?: stringResource(id = CommonStrings.error_unknown))
if (onRetry != null) {
Spacer(modifier = Modifier.height(24.dp))
Button(onClick = onRetry) {
Text(text = stringResource(id = StringR.string.action_retry))
Text(text = stringResource(id = CommonStrings.action_retry))
}
}
}

View file

@ -17,7 +17,9 @@
package io.element.android.libraries.designsystem.components.avatar
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.runtime.Composable
@ -30,14 +32,15 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.sp
import androidx.compose.ui.unit.dp
import coil.compose.AsyncImage
import io.element.android.libraries.designsystem.AvatarGradientEnd
import io.element.android.libraries.designsystem.AvatarGradientStart
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.designsystem.preview.debugPlaceholderAvatar
import io.element.android.libraries.designsystem.text.toSp
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.theme.AvatarGradientEnd
import io.element.android.libraries.theme.AvatarGradientStart
import timber.log.Timber
@Composable
@ -100,7 +103,7 @@ private fun InitialsAvatar(
Text(
modifier = Modifier.align(Alignment.Center),
text = avatarData.initial,
fontSize = (avatarData.size.dp / 2).value.sp,
fontSize = avatarData.size.dp.toSp() / 2,
color = Color.White,
)
}
@ -109,4 +112,12 @@ private fun InitialsAvatar(
@Preview(group = PreviewGroup.Avatars)
@Composable
fun AvatarPreview(@PreviewParameter(AvatarDataProvider::class) avatarData: AvatarData) =
ElementThemedPreview { Avatar(avatarData) }
ElementThemedPreview {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(16.dp)
) {
Avatar(avatarData)
Text(text = avatarData.size.name + " " + avatarData.size.dp)
}
}

View file

@ -23,7 +23,7 @@ data class AvatarData(
val id: String,
val name: String?,
val url: String? = null,
val size: AvatarSize = AvatarSize.MEDIUM
val size: AvatarSize,
) {
val initial by lazy {

View file

@ -20,15 +20,28 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider
open class AvatarDataProvider : PreviewParameterProvider<AvatarData> {
override val values: Sequence<AvatarData>
get() = sequenceOf(
anAvatarData(),
anAvatarData().copy(name = null),
anAvatarData().copy(url = "aUrl"),
)
get() {
AvatarSize.values()
.also { it.sortBy { item -> item.name } }
.asSequence()
return AvatarSize.values().asSequence().map {
sequenceOf(
anAvatarData(size = it),
anAvatarData(size = it).copy(name = null),
anAvatarData(size = it).copy(url = "aUrl"),
)
}
.flatten()
}
}
fun anAvatarData(id: String = "@id_of_alice:server.org", name: String = "Alice") = AvatarData(
fun anAvatarData(
// Let's the id not start with a 'a'.
id: String = "@id_of_alice:server.org",
name: String = "Alice",
size: AvatarSize = AvatarSize.RoomListItem,
) = AvatarData(
id = id,
name = name,
size = size,
)

View file

@ -19,13 +19,25 @@ package io.element.android.libraries.designsystem.components.avatar
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
sealed class AvatarSize(open val dp: Dp) {
enum class AvatarSize(val dp: Dp) {
CurrentUserTopBar(28.dp),
object SMALL : AvatarSize(32.dp)
object MEDIUM : AvatarSize(40.dp)
object BIG : AvatarSize(48.dp)
object HUGE : AvatarSize(96.dp)
RoomHeader(96.dp),
RoomListItem(52.dp),
// FIXME maybe remove this field and switch back to an enum (or remove this class) when design system will be integrated
data class Custom(override val dp: Dp) : AvatarSize(dp)
ForwardRoomListItem(36.dp),
UserHeader(96.dp),
UserListItem(36.dp),
SelectedUser(56.dp),
SelectedRoom(56.dp),
TimelineRoom(32.dp),
TimelineSender(32.dp),
MessageActionSender(32.dp),
RoomInviteItem(52.dp),
InviteSender(16.dp),
}

View file

@ -28,14 +28,14 @@ import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.theme.components.IconButton
import io.element.android.libraries.ui.strings.R as StringR
import io.element.android.libraries.ui.strings.CommonStrings
@Composable
fun BackButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
imageVector: ImageVector = Icons.Default.ArrowBack,
contentDescription: String = stringResource(StringR.string.action_back),
contentDescription: String = stringResource(CommonStrings.action_back),
enabled: Boolean = true,
) {
IconButton(

View file

@ -31,7 +31,7 @@ import androidx.compose.ui.unit.Dp
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.designsystem.utils.BooleanProvider
import io.element.android.libraries.ui.strings.R as StringR
import io.element.android.libraries.ui.strings.CommonStrings
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@ -41,8 +41,8 @@ fun ConfirmationDialog(
onDismiss: () -> Unit,
modifier: Modifier = Modifier,
title: String? = null,
submitText: String = stringResource(id = StringR.string.action_ok),
cancelText: String = stringResource(id = StringR.string.action_cancel),
submitText: String = stringResource(id = CommonStrings.action_ok),
cancelText: String = stringResource(id = CommonStrings.action_cancel),
thirdButtonText: String? = null,
emphasizeSubmitButton: Boolean = false,
onCancelClicked: () -> Unit = onDismiss,

View file

@ -28,7 +28,7 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.ui.strings.R as StringR
import io.element.android.libraries.ui.strings.CommonStrings
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@ -91,8 +91,8 @@ private fun ErrorDialogContent(
}
object ErrorDialogDefaults {
val title: String @Composable get() = stringResource(id = StringR.string.dialog_title_error)
val submitText: String @Composable get() = stringResource(id = StringR.string.action_ok)
val title: String @Composable get() = stringResource(id = CommonStrings.dialog_title_error)
val submitText: String @Composable get() = stringResource(id = CommonStrings.action_ok)
}
@Preview(group = PreviewGroup.Dialogs)

View file

@ -29,7 +29,7 @@ import androidx.compose.ui.unit.Dp
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.ui.strings.R as StringR
import io.element.android.libraries.ui.strings.CommonStrings
@Composable
fun RetryDialog(
@ -109,9 +109,9 @@ private fun RetryDialogContent(
}
object RetryDialogDefaults {
val title: String @Composable get() = stringResource(id = StringR.string.dialog_title_error)
val retryText: String @Composable get() = stringResource(id = StringR.string.action_retry)
val dismissText: String @Composable get() = stringResource(id = StringR.string.action_cancel)
val title: String @Composable get() = stringResource(id = CommonStrings.dialog_title_error)
val retryText: String @Composable get() = stringResource(id = CommonStrings.action_retry)
val dismissText: String @Composable get() = stringResource(id = CommonStrings.action_cancel)
}
@Preview(group = PreviewGroup.Dialogs)

View file

@ -28,7 +28,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.theme.ElementTheme
import io.element.android.libraries.theme.ElementTheme
import io.element.android.libraries.designsystem.theme.components.Surface
@Composable

View file

@ -21,10 +21,12 @@ object PreviewGroup {
const val Avatars = "Avatars"
const val BottomSheets = "Bottom Sheets"
const val Buttons = "Buttons"
const val DateTimePickers = "DateTime pickers"
const val Dialogs = "Dialogs"
const val Dividers = "Dividers"
const val FABs = "Floating Action Buttons"
const val Icons = "Icons"
const val Menus = "Menus"
const val Preferences = "Preferences"
const val Progress = "Progress Indicators"
const val Search = "Search views"

View file

@ -31,7 +31,7 @@ import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextDecoration
import io.element.android.libraries.designsystem.LinkColor
import io.element.android.libraries.theme.LinkColor
fun String.toAnnotatedString(): AnnotatedString = buildAnnotatedString {
append(this@toAnnotatedString)

View file

@ -0,0 +1,47 @@
/*
* 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.text
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.TextUnit
/**
* Convert Dp to Sp, regarding current density.
* Can be used for instance to use Dp unit for text.
*/
@Composable
fun Dp.toSp(): TextUnit = with(LocalDensity.current) { toSp() }
/**
* Convert Px value to Dp, regarding current density.
*/
@Composable
fun Int.toDp(): Dp = with(LocalDensity.current) { toDp() }
/**
* Convert Dp value to pixels, regarding current density.
*/
@Composable
fun Dp.toPx(): Float = with(LocalDensity.current) { toPx() }
/**
* Convert Dp value to pixels, regarding current density.
*/
@Composable
fun Dp.roundToPx(): Int = with(LocalDensity.current) { roundToPx() }

View file

@ -20,11 +20,9 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import io.element.android.libraries.designsystem.SystemGrey4Dark
import io.element.android.libraries.designsystem.SystemGrey6Light
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.theme.previews.ColorListPreview
import io.element.android.libraries.theme.previews.ColorListPreview
import kotlinx.collections.immutable.persistentMapOf
/**
@ -42,9 +40,6 @@ fun MaterialTheme.roomListRoomMessageDate() = colorScheme.secondary
@Composable
fun MaterialTheme.roomListUnreadIndicator() = colorScheme.primary
@Composable
fun ElementColors.roomListPlaceHolder() = if (isLight) SystemGrey6Light else SystemGrey4Dark
@Preview
@Composable
internal fun ColorAliasesLightPreview() = ElementPreviewLight { ContentToPreview() }
@ -63,7 +58,6 @@ private fun ContentToPreview() {
"roomListRoomMessage" to MaterialTheme.roomListRoomMessage(),
"roomListRoomMessageDate" to MaterialTheme.roomListRoomMessageDate(),
"roomListUnreadIndicator" to MaterialTheme.roomListUnreadIndicator(),
"roomListPlaceHolder" to ElementTheme.colors.roomListPlaceHolder(),
)
)
}

View file

@ -1,93 +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.theme
import androidx.compose.material3.darkColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import io.element.android.libraries.designsystem.Azure
import io.element.android.libraries.designsystem.Black_800
import io.element.android.libraries.designsystem.Black_950
import io.element.android.libraries.designsystem.Compound_Gray_300_Dark
import io.element.android.libraries.designsystem.DarkGrey
import io.element.android.libraries.designsystem.Compound_Gray_1400_Dark
import io.element.android.libraries.designsystem.Gray_300
import io.element.android.libraries.designsystem.Gray_400
import io.element.android.libraries.designsystem.Compound_Gray_400_Dark
import io.element.android.libraries.designsystem.Compound_Gray_800_Dark
import io.element.android.libraries.designsystem.Gray_450
import io.element.android.libraries.designsystem.SystemGrey5Dark
import io.element.android.libraries.designsystem.SystemGrey6Dark
import io.element.android.libraries.designsystem.TextColorCriticalDark
import io.element.android.libraries.designsystem.theme.previews.ColorsSchemePreview
fun elementColorsDark() = ElementColors(
messageFromMeBackground = SystemGrey5Dark,
messageFromOtherBackground = SystemGrey6Dark,
messageHighlightedBackground = Azure,
quaternary = Gray_400,
quinary = Gray_450,
gray300 = Compound_Gray_300_Dark,
gray400 = Compound_Gray_400_Dark,
gray1400 = Compound_Gray_1400_Dark,
textActionCritical = TextColorCriticalDark,
accentColor = Color(0xFF0DBD8B),
placeholder = Compound_Gray_800_Dark,
isLight = false,
)
// TODO Lots of colors are missing
val materialColorSchemeDark = darkColorScheme(
primary = Color.White,
onPrimary = Color.Black,
// TODO primaryContainer = ColorDarkTokens.PrimaryContainer,
// TODO onPrimaryContainer = ColorDarkTokens.OnPrimaryContainer,
// TODO inversePrimary = ColorDarkTokens.InversePrimary,
secondary = DarkGrey,
// TODO onSecondary = ColorDarkTokens.OnSecondary,
// TODO secondaryContainer = ColorDarkTokens.SecondaryContainer,
// TODO onSecondaryContainer = ColorDarkTokens.OnSecondaryContainer,
tertiary = Gray_300,
// TODO onTertiary = ColorDarkTokens.OnTertiary,
// TODO tertiaryContainer = ColorDarkTokens.TertiaryContainer,
// TODO onTertiaryContainer = ColorDarkTokens.OnTertiaryContainer,
background = Black_800,
onBackground = Color.White,
surface = Black_800,
onSurface = Color.White,
surfaceVariant = Black_950,
onSurfaceVariant = Gray_300,
// TODO surfaceTint = primary,
// TODO inverseSurface = ColorDarkTokens.InverseSurface,
// TODO inverseOnSurface = ColorDarkTokens.InverseOnSurface,
// TODO error = ColorDarkTokens.Error,
// TODO onError = ColorDarkTokens.OnError,
// TODO errorContainer = ColorDarkTokens.ErrorContainer,
// TODO onErrorContainer = ColorDarkTokens.OnErrorContainer,
// TODO outline = ColorDarkTokens.Outline,
outlineVariant = Gray_450,
// TODO scrim = ColorDarkTokens.Scrim,
)
@Preview
@Composable
fun ColorsSchemePreviewDark() = ColorsSchemePreview(
Color.White,
Color.Black,
materialColorSchemeDark,
)

View file

@ -1,93 +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.theme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import io.element.android.libraries.designsystem.Azure
import io.element.android.libraries.designsystem.Black_900
import io.element.android.libraries.designsystem.Compound_Gray_300_Light
import io.element.android.libraries.designsystem.Compound_Gray_400_Light
import io.element.android.libraries.designsystem.Compound_Gray_800_Light
import io.element.android.libraries.designsystem.Gray_100
import io.element.android.libraries.designsystem.Compound_Gray_1400_Light
import io.element.android.libraries.designsystem.Gray_150
import io.element.android.libraries.designsystem.Gray_200
import io.element.android.libraries.designsystem.Gray_25
import io.element.android.libraries.designsystem.Gray_50
import io.element.android.libraries.designsystem.SystemGrey5Light
import io.element.android.libraries.designsystem.SystemGrey6Light
import io.element.android.libraries.designsystem.TextColorCriticalLight
import io.element.android.libraries.designsystem.theme.previews.ColorsSchemePreview
fun elementColorsLight() = ElementColors(
messageFromMeBackground = SystemGrey5Light,
messageFromOtherBackground = SystemGrey6Light,
messageHighlightedBackground = Azure,
quaternary = Gray_100,
quinary = Gray_50,
gray300 = Compound_Gray_300_Light,
gray400 = Compound_Gray_400_Light,
gray1400 = Compound_Gray_1400_Light,
textActionCritical = TextColorCriticalLight,
accentColor = Color(0xFF0DBD8B),
placeholder = Compound_Gray_800_Light,
isLight = true,
)
// TODO Lots of colors are missing
val materialColorSchemeLight = lightColorScheme(
primary = Black_900,
onPrimary = Color.White,
// TODO primaryContainer = ColorLightTokens.PrimaryContainer,
// TODO onPrimaryContainer = ColorLightTokens.OnPrimaryContainer,
// TODO inversePrimary = ColorLightTokens.InversePrimary,
secondary = Gray_200,
// TODO onSecondary = ColorLightTokens.OnSecondary,
// TODO secondaryContainer = ColorLightTokens.SecondaryContainer,
// TODO onSecondaryContainer = ColorLightTokens.OnSecondaryContainer,
tertiary = Gray_150,
// TODO onTertiary = ColorLightTokens.OnTertiary,
// TODO tertiaryContainer = ColorLightTokens.TertiaryContainer,
// TODO onTertiaryContainer = ColorLightTokens.OnTertiaryContainer,
background = Color.White,
onBackground = Color.Black,
surface = Color.White,
onSurface = Color.Black,
surfaceVariant = Gray_25,
onSurfaceVariant = Gray_200,
// TODO surfaceTint = primary,
// TODO inverseSurface = ColorLightTokens.InverseSurface,
// TODO inverseOnSurface = ColorLightTokens.InverseOnSurface,
// TODO error = ColorLightTokens.Error,
// TODO onError = ColorLightTokens.OnError,
// TODO errorContainer = ColorLightTokens.ErrorContainer,
// TODO onErrorContainer = ColorLightTokens.OnErrorContainer,
// TODO outline = ColorLightTokens.Outline,
outlineVariant = Gray_50,
// TODO scrim = ColorLightTokens.Scrim,
)
@Preview
@Composable
fun ColorsSchemePreviewLight() = ColorsSchemePreview(
Color.Black,
Color.White,
materialColorSchemeLight,
)

View file

@ -22,6 +22,7 @@ import androidx.compose.material3.ProgressIndicatorDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
@ -49,11 +50,21 @@ fun CircularProgressIndicator(
color: Color = ProgressIndicatorDefaults.circularColor,
strokeWidth: Dp = ProgressIndicatorDefaults.CircularStrokeWidth,
) {
androidx.compose.material3.CircularProgressIndicator(
modifier = modifier,
color = color,
strokeWidth = strokeWidth,
)
if (LocalInspectionMode.current) {
// Use a determinate progress indicator to improve the preview rendering
androidx.compose.material3.CircularProgressIndicator(
modifier = modifier,
progress = 0.75F,
color = color,
strokeWidth = strokeWidth,
)
} else {
androidx.compose.material3.CircularProgressIndicator(
modifier = modifier,
color = color,
strokeWidth = strokeWidth,
)
}
}
@Preview(group = PreviewGroup.Progress)
@ -68,7 +79,7 @@ private fun ContentToPreview() {
)
// Fixed progress
CircularProgressIndicator(
progress = 0.75F
progress = 0.90F
)
}
}

View file

@ -17,6 +17,7 @@
package io.element.android.libraries.designsystem.theme.components
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Row
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material3.IconButtonDefaults
@ -52,7 +53,12 @@ internal fun IconButtonPreview() =
@Composable
private fun ContentToPreview() {
IconButton(onClick = {}) {
Icon(imageVector = Icons.Filled.Close, contentDescription = "")
Row {
IconButton(onClick = {}) {
Icon(imageVector = Icons.Filled.Close, contentDescription = "")
}
IconButton(enabled = false, onClick = {}) {
Icon(imageVector = Icons.Filled.Close, contentDescription = "")
}
}
}

View file

@ -38,6 +38,7 @@ import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.theme.ElementTheme
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
@ -50,7 +51,7 @@ fun ModalBottomSheet(
shape: Shape = BottomSheetDefaults.ExpandedShape,
containerColor: Color = BottomSheetDefaults.ContainerColor,
contentColor: Color = contentColorFor(containerColor),
tonalElevation: Dp = BottomSheetDefaults.Elevation,
tonalElevation: Dp = if (ElementTheme.isLightTheme) 0.dp else BottomSheetDefaults.Elevation,
scrimColor: Color = BottomSheetDefaults.ScrimColor,
dragHandle: @Composable (() -> Unit)? = { BottomSheetDefaults.DragHandle() },
windowInsets: WindowInsets = BottomSheetDefaults.windowInsets,
@ -102,7 +103,6 @@ private fun ContentToPreview() {
sheetState = SheetState(
skipPartiallyExpanded = true,
initialValue = SheetValue.Expanded,
skipHiddenState = true,
),
) {
Text(

View file

@ -18,6 +18,7 @@ package io.element.android.libraries.designsystem.theme.components
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.RowScope
@ -79,7 +80,7 @@ internal fun OutlinedButtonsPreview() = ElementThemedPreview { ContentToPreview(
@Composable
private fun ContentToPreview() {
Column {
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
OutlinedButton(onClick = {}, enabled = true) {
Text(text = "Click me! - Enabled")
}

View file

@ -55,5 +55,7 @@ private fun ContentToPreview() {
Column {
RadioButton(selected = false, onClick = {})
RadioButton(selected = true, onClick = {})
RadioButton(selected = false, enabled = false, onClick = {})
RadioButton(selected = true, enabled = false, onClick = {})
}
}

View file

@ -46,8 +46,8 @@ import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.components.button.BackButton
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.designsystem.theme.LocalColors
import io.element.android.libraries.ui.strings.R
import io.element.android.libraries.theme.ElementTheme
import io.element.android.libraries.ui.strings.CommonStrings
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@ -100,7 +100,7 @@ fun <T> SearchBar(
IconButton(onClick = { onQueryChange("") }) {
Icon(
imageVector = Icons.Default.Close,
contentDescription = stringResource(R.string.action_clear),
contentDescription = stringResource(CommonStrings.action_clear),
)
}
}
@ -110,7 +110,7 @@ fun <T> SearchBar(
{
Icon(
imageVector = Icons.Default.Search,
contentDescription = stringResource(R.string.action_search),
contentDescription = stringResource(CommonStrings.action_search),
tint = MaterialTheme.colorScheme.tertiary,
)
}
@ -135,7 +135,7 @@ fun <T> SearchBar(
Spacer(Modifier.size(80.dp))
Text(
text = stringResource(R.string.common_no_results),
text = stringResource(CommonStrings.common_no_results),
textAlign = TextAlign.Center,
color = MaterialTheme.colorScheme.tertiary,
modifier = Modifier.fillMaxWidth()
@ -156,10 +156,10 @@ object ElementSearchBarDefaults {
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun inactiveColors() = SearchBarDefaults.colors(
containerColor = LocalColors.current.gray300,
containerColor = ElementTheme.legacyColors.gray300,
inputFieldColors = TextFieldDefaults.colors(
unfocusedPlaceholderColor = LocalColors.current.placeholder,
focusedPlaceholderColor = LocalColors.current.placeholder,
unfocusedPlaceholderColor = ElementTheme.legacyColors.placeholder,
focusedPlaceholderColor = ElementTheme.legacyColors.placeholder,
unfocusedLeadingIconColor = MaterialTheme.colorScheme.primary,
focusedLeadingIconColor = MaterialTheme.colorScheme.primary,
unfocusedTrailingIconColor = MaterialTheme.colorScheme.primary,
@ -172,8 +172,8 @@ object ElementSearchBarDefaults {
fun activeColors() = SearchBarDefaults.colors(
containerColor = Color.Transparent,
inputFieldColors = TextFieldDefaults.colors(
unfocusedPlaceholderColor = LocalColors.current.placeholder,
focusedPlaceholderColor = LocalColors.current.placeholder,
unfocusedPlaceholderColor = ElementTheme.legacyColors.placeholder,
focusedPlaceholderColor = ElementTheme.legacyColors.placeholder,
unfocusedLeadingIconColor = MaterialTheme.colorScheme.primary,
focusedLeadingIconColor = MaterialTheme.colorScheme.primary,
unfocusedTrailingIconColor = MaterialTheme.colorScheme.primary,

View file

@ -21,7 +21,10 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.material3.SliderColors
import androidx.compose.material3.SliderDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
@ -59,8 +62,10 @@ internal fun SlidersPreview() = ElementThemedPreview { ContentToPreview() }
@Composable
private fun ContentToPreview() {
var value by remember { mutableStateOf(0.33f) }
Column {
Slider(onValueChange = {}, value = 0.33f, enabled = true)
Slider(onValueChange = {}, value = 0.33f, enabled = false)
Slider(onValueChange = { value = it }, value = value, enabled = true)
Slider(steps = 10, onValueChange = { value = it }, value = value, enabled = true)
Slider(onValueChange = { value = it }, value = value, enabled = false)
}
}

View file

@ -47,7 +47,7 @@ import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.designsystem.utils.toHrf
import io.element.android.libraries.theme.utils.toHrf
import kotlinx.collections.immutable.ImmutableMap
import kotlinx.collections.immutable.persistentMapOf

View file

@ -0,0 +1,62 @@
/*
* 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.previews
import androidx.compose.material3.AlertDialogDefaults
import androidx.compose.material3.DatePicker
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.rememberDatePickerState
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import io.element.android.libraries.designsystem.components.dialogs.AlertDialogContent
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.PreviewGroup
@Preview(group = PreviewGroup.DateTimePickers)
@Composable
internal fun DatePickerPreviewLight() {
ElementPreviewLight { ContentToPreview() }
}
@Preview(group = PreviewGroup.DateTimePickers)
@Composable
internal fun DatePickerPreviewDark() {
ElementPreviewDark { ContentToPreview() }
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun ContentToPreview() {
val state = rememberDatePickerState(
initialSelectedDateMillis = 1672578000000L,
)
AlertDialogContent(
buttons = { /*TODO*/ },
icon = { /*TODO*/ },
title = { /*TODO*/ },
text = { DatePicker(state = state, showModeToggle = true) },
shape = AlertDialogDefaults.shape,
containerColor = AlertDialogDefaults.containerColor,
tonalElevation = AlertDialogDefaults.TonalElevation,
buttonContentColor = MaterialTheme.colorScheme.primary,
iconContentColor = AlertDialogDefaults.iconContentColor,
titleContentColor = AlertDialogDefaults.titleContentColor,
textContentColor = AlertDialogDefaults.textContentColor,
)
}

View file

@ -0,0 +1,70 @@
/*
* 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.previews
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowRight
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.tooling.preview.Preview
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.designsystem.theme.components.Button
import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.theme.components.Text
@Preview(group = PreviewGroup.Menus)
@Composable
internal fun MenuPreview() {
ElementThemedPreview {
var isExpanded by remember { mutableStateOf(false) }
Button(onClick = { isExpanded = !isExpanded }) {
Text("Toggle")
}
DropdownMenu(expanded = isExpanded, onDismissRequest = { isExpanded = false }) {
for (i in 0..5) {
val leadingIcon: @Composable (() -> Unit)? = if (i in 2..3) {
@Composable {
Icon(Icons.Filled.Favorite, contentDescription = "Favorite")
}
} else {
null
}
val trailingIcon: @Composable (() -> Unit)? = if (i in 3..4) {
@Composable {
Icon(Icons.Filled.ArrowRight, contentDescription = "Favorite")
}
} else {
null
}
DropdownMenuItem(
text = { Text(text = "Item $i") },
onClick = { isExpanded = false },
leadingIcon = leadingIcon,
trailingIcon = trailingIcon,
)
}
}
}
}

View file

@ -0,0 +1,51 @@
/*
* 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.previews
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Check
import androidx.compose.material3.Switch
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.designsystem.theme.components.Icon
@Preview(group = PreviewGroup.Toggles)
@Composable
internal fun SwitchPreview() {
ElementThemedPreview {
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
var checked by remember { mutableStateOf(false) }
Switch(checked = checked, onCheckedChange = { checked = !checked })
Switch(checked = checked, onCheckedChange = { checked = !checked }, thumbContent = {
Icon(imageVector = Icons.Outlined.Check, contentDescription = null)
})
Switch(checked = checked, enabled = false, onCheckedChange = { checked = !checked })
Switch(checked = checked, enabled = false, onCheckedChange = { checked = !checked }, thumbContent = {
Icon(imageVector = Icons.Outlined.Check, contentDescription = null)
})
}
}
}

View file

@ -0,0 +1,98 @@
/*
* 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.previews
import androidx.compose.material3.AlertDialogDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.TimePicker
import androidx.compose.material3.TimePickerLayoutType
import androidx.compose.material3.rememberTimePickerState
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import io.element.android.libraries.designsystem.components.dialogs.AlertDialogContent
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
@OptIn(ExperimentalMaterial3Api::class)
@Preview(widthDp = 600, group = PreviewGroup.DateTimePickers)
@Composable
internal fun TimePickerHorizontalPreview() {
ElementThemedPreview {
AlertDialogContent(
buttons = { /*TODO*/ },
icon = { /*TODO*/ },
title = { /*TODO*/ },
text = { TimePicker(state = rememberTimePickerState(), layoutType = TimePickerLayoutType.Horizontal) },
shape = AlertDialogDefaults.shape,
containerColor = AlertDialogDefaults.containerColor,
tonalElevation = AlertDialogDefaults.TonalElevation,
buttonContentColor = MaterialTheme.colorScheme.primary,
iconContentColor = AlertDialogDefaults.iconContentColor,
titleContentColor = AlertDialogDefaults.titleContentColor,
textContentColor = AlertDialogDefaults.textContentColor,
)
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Preview(group = PreviewGroup.DateTimePickers)
@Composable
internal fun TimePickerVerticalPreviewLight() {
ElementPreviewLight {
AlertDialogContent(
buttons = { /*TODO*/ },
icon = { /*TODO*/ },
title = { /*TODO*/ },
text = { TimePicker(state = rememberTimePickerState(), layoutType = TimePickerLayoutType.Vertical) },
shape = AlertDialogDefaults.shape,
containerColor = AlertDialogDefaults.containerColor,
tonalElevation = AlertDialogDefaults.TonalElevation,
buttonContentColor = MaterialTheme.colorScheme.primary,
iconContentColor = AlertDialogDefaults.iconContentColor,
titleContentColor = AlertDialogDefaults.titleContentColor,
textContentColor = AlertDialogDefaults.textContentColor,
)
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Preview(group = PreviewGroup.DateTimePickers)
@Composable
internal fun TimePickerVerticalPreviewDark() {
val pickerState = rememberTimePickerState(
initialHour = 12,
initialMinute = 0,
)
ElementPreviewDark {
AlertDialogContent(
buttons = { /*TODO*/ },
icon = { /*TODO*/ },
title = { /*TODO*/ },
text = { TimePicker(state = pickerState, layoutType = TimePickerLayoutType.Vertical) },
shape = AlertDialogDefaults.shape,
containerColor = AlertDialogDefaults.containerColor,
tonalElevation = AlertDialogDefaults.TonalElevation,
buttonContentColor = MaterialTheme.colorScheme.primary,
iconContentColor = AlertDialogDefaults.iconContentColor,
titleContentColor = AlertDialogDefaults.titleContentColor,
textContentColor = AlertDialogDefaults.textContentColor,
)
}
}

View file

@ -1,20 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2022 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.
-->
<manifest>
</manifest>

View file

@ -1,177 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2022 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.
-->
<resources>
<!-- Error colors -->
<color name="vector_warning_color_2">@color/palette_melon</color>
<color name="vector_info_color">#2f9edb</color>
<!-- Notification view colors -->
<color name="soft_resource_limit_exceeded">#2f9edb</color>
<color name="hard_resource_limit_exceeded">?colorError</color>
<!-- Notification (do not depends on theme) -->
<color name="notification_accent_color">@color/palette_azure</color>
<color name="key_share_req_accent_color">@color/palette_melon</color>
<!-- Source: https://zpl.io/aBKw9Mk -->
<color name="bg_call_screen_blur">#99000000</color>
<color name="bg_call_screen">#27303A</color>
<color name="vctr_notice_secondary_alpha12">#1E61708B</color>
<!-- Other useful color -->
<!-- Emoji text has to use a black text color -->
<color name="emoji_color">@android:color/black</color>
<color name="join_conference_animated_color">#0BAC7E</color>
<color name="half_transparent_status_bar">#80000000</color>
<color name="black_alpha">#55000000</color>
<color name="black_54">#8A000000</color>
<!-- For Android status bar and navigation bar -->
<color name="android_status_bar_background_light">@color/element_system_light</color>
<color name="android_navigation_bar_background_light">@color/element_system_light</color>
<color name="android_status_bar_background_dark">@color/element_background_dark</color>
<color name="android_navigation_bar_background_dark">@color/element_system_dark</color>
<!-- Used for toolbar background -->
<attr name="vctr_toolbar_background" format="color" />
<!-- Used for header background -->
<attr name="vctr_header_background" format="color" />
<!-- Used for item separators in list -->
<attr name="vctr_list_separator" format="color" />
<!-- Used for item separators in list, variant using element system color -->
<attr name="vctr_list_separator_system" format="color" />
<!-- Used for item separators in list, on surface -->
<attr name="vctr_list_separator_on_surface" format="color" />
<!-- Background color used for:
- unread badge background for a room item in the room list
- start unread indicator for a room item in the room list
- Background for unread badge background in the bottom navigation -->
<attr name="vctr_unread_background" format="color" />
<!-- Other colors, which are not in the palette -->
<attr name="vctr_fab_label_bg" format="color" />
<color name="vctr_fab_label_bg_light">@android:color/white</color>
<color name="vctr_fab_label_bg_dark">#FF181B21</color>
<color name="vctr_fab_label_bg_black">#FF181B21</color>
<attr name="vctr_fab_label_stroke" format="color" />
<color name="vctr_fab_label_stroke_light">#1EFFFFFF</color>
<color name="vctr_fab_label_stroke_dark">@android:color/black</color>
<color name="vctr_fab_label_stroke_black">@android:color/black</color>
<attr name="vctr_fab_label_color" format="color" />
<color name="vctr_fab_label_color_light">#FF2E2F32</color>
<color name="vctr_fab_label_color_dark">#FFA1B2D1</color>
<color name="vctr_fab_label_color_black">#FFA1B2D1</color>
<attr name="vctr_touch_guard_bg" format="color" />
<color name="vctr_touch_guard_bg_light">#66000000</color>
<color name="vctr_touch_guard_bg_dark">#BF000000</color>
<color name="vctr_touch_guard_bg_black">#BF000000</color>
<attr name="vctr_room_active_widgets_banner_bg" format="color" />
<color name="vctr_room_active_widgets_banner_bg_light">#EBEFF5</color>
<color name="vctr_room_active_widgets_banner_bg_dark">#27303A</color>
<color name="vctr_room_active_widgets_banner_bg_black">#27303A</color>
<attr name="vctr_room_active_widgets_banner_text" format="color" />
<color name="vctr_room_active_widgets_banner_text_light">#61708B</color>
<color name="vctr_room_active_widgets_banner_text_dark">#E3E8F0</color>
<color name="vctr_room_active_widgets_banner_text_black">#E3E8F0</color>
<attr name="vctr_waiting_background_color" format="color" />
<color name="vctr_waiting_background_color_light">#AAAAAAAA</color>
<color name="vctr_waiting_background_color_dark">#55555555</color>
<color name="vctr_disabled_view_color_light">#EEEEEE</color>
<attr name="vctr_reaction_background_off" format="color" />
<color name="vctr_reaction_background_off_light">#FFF3F8FD</color>
<color name="vctr_reaction_background_off_dark">#22252B</color>
<color name="vctr_reaction_background_off_black">#22252B</color>
<attr name="vctr_reaction_background_on" format="color" />
<color name="vctr_reaction_background_on_light">#2011BC8A</color>
<color name="vctr_reaction_background_on_dark">#4011BC8A</color>
<color name="vctr_reaction_background_on_black">#4011BC8A</color>
<!-- (color from RiotWeb) -->
<attr name="vctr_keys_backup_banner_accent_color" format="color" />
<color name="vctr_keys_backup_banner_accent_color_light">#FFF8E3</color>
<color name="vctr_keys_backup_banner_accent_color_dark">#22262E</color>
<attr name="vctr_chat_effect_snow_background" format="color" />
<color name="vctr_chat_effect_snow_background_light">@color/black_alpha</color>
<color name="vctr_chat_effect_snow_background_dark">@android:color/transparent</color>
<attr name="vctr_toast_background" format="color" />
<color name="vctr_toast_background_light">@color/palette_black_900</color>
<color name="vctr_toast_background_dark">@color/palette_gray_400</color>
<!-- Presence Indicator colors -->
<attr name="vctr_presence_indicator_offline" format="color" />
<color name="vctr_presence_indicator_offline_light">@color/palette_gray_100</color>
<color name="vctr_presence_indicator_offline_dark">@color/palette_gray_450</color>
<attr name="vctr_presence_indicator_online" format="color" />
<color name="vctr_presence_indicator_online_light">@color/palette_element_green</color>
<color name="vctr_presence_indicator_online_dark">@color/palette_element_green</color>
<attr name="vctr_presence_indicator_busy" format="color" />
<color name="vctr_presence_indicator_busy_light">@color/element_alert_light</color>
<color name="vctr_presence_indicator_busy_dark">@color/element_alert_dark</color>
<attr name="vctr_presence_indicator_away" format="color" />
<color name="vctr_presence_indicator_away_light">@color/palette_element_orange</color>
<color name="vctr_presence_indicator_away_dark">@color/palette_element_orange</color>
<!-- Location sharing colors -->
<attr name="vctr_live_location" format="color" />
<color name="vctr_live_location_light">@color/palette_prune</color>
<color name="vctr_live_location_dark">@color/palette_prune</color>
<!-- Shield colors -->
<color name="shield_color_trust">#0DBD8B</color>
<color name="shield_color_trust_background">#0F0DBD8B</color>
<color name="shield_color_black">#17191C</color>
<color name="shield_color_gray">#91A1C0</color>
<color name="shield_color_warning">#FF4B55</color>
<color name="shield_color_warning_background">#0FFF4B55</color>
<color name="shield_color_unknown">@color/palette_gray_200</color>
<!-- Badge Colors -->
<attr name="vctr_badge_color_border" format="color" />
<color name="vctr_badge_color_border_light">@color/palette_white</color>
<color name="vctr_badge_color_border_dark">@color/palette_black_950</color>
<!-- WYSIWYG Colors -->
<attr name="vctr_rich_text_editor_menu_button_background" format="color" />
<color name="vctr_rich_text_editor_menu_button_background_light">#EEF8F4</color>
<color name="vctr_rich_text_editor_menu_button_background_dark">#1D292A</color>
</resources>

View file

@ -1,96 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2022 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.
-->
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="layout_touch_size">48dp</dimen>
<dimen name="layout_horizontal_margin">16dp</dimen>
<dimen name="layout_vertical_margin">16dp</dimen>
<dimen name="layout_vertical_margin_big">32dp</dimen>
<dimen name="profile_avatar_size">50dp</dimen>
<dimen name="typing_avatar_size">20dp</dimen>
<dimen name="item_event_message_state_size">16dp</dimen>
<dimen name="item_event_message_media_button_size">32dp</dimen>
<dimen name="quote_gap">8dp</dimen>
<item name="dialog_width_ratio" format="float" type="dimen">0.75</item>
<dimen name="pill_avatar_size">16dp</dimen>
<dimen name="pill_min_height">20dp</dimen>
<dimen name="pill_text_padding">4dp</dimen>
<dimen name="call_pip_height">128dp</dimen>
<dimen name="call_pip_width">88dp</dimen>
<dimen name="call_pip_radius">8dp</dimen>
<dimen name="item_form_min_height">76dp</dimen>
<!-- Max width for some buttons -->
<dimen name="button_max_width">280dp</dimen>
<!-- Navigation Drawer -->
<dimen name="navigation_drawer_max_width">320dp</dimen>
<!-- Preview Url -->
<dimen name="preview_url_view_corner_radius">8dp</dimen>
<dimen name="preview_url_view_image_max_height">160dp</dimen>
<dimen name="menu_item_icon_size">24dp</dimen>
<dimen name="menu_item_size">48dp</dimen>
<dimen name="menu_item_ripple_size">48dp</dimen>
<dimen name="menu_item_width_small">34dp</dimen>
<dimen name="chat_bubble_margin_start">28dp</dimen>
<dimen name="chat_bubble_margin_end">6dp</dimen>
<dimen name="chat_bubble_fixed_size">350sp</dimen>
<dimen name="chat_bubble_corner_radius">8dp</dimen>
<!-- Onboarding -->
<item name="ftue_auth_gutter_start_percent" format="float" type="dimen">0.05</item>
<item name="ftue_auth_gutter_end_percent" format="float" type="dimen">0.95</item>
<item name="ftue_auth_carousel_item_spacing" format="float" type="dimen">0.01</item>
<item name="ftue_auth_carousel_item_image_height" format="float" type="dimen">0.35</item>
<item name="ftue_auth_profile_picture_height" format="float" type="dimen">0.15</item>
<item name="ftue_auth_profile_picture_icon_height" format="float" type="dimen">0.05</item>
<!-- Location sharing -->
<dimen name="location_sharing_option_default_padding">10dp</dimen>
<dimen name="location_sharing_locate_button_margin_vertical">16dp</dimen>
<dimen name="location_sharing_locate_button_margin_horizontal">12dp</dimen>
<dimen name="location_sharing_compass_button_margin_horizontal">8dp</dimen>
<dimen name="location_sharing_live_duration_choice_margin_horizontal">12dp</dimen>
<dimen name="location_sharing_live_duration_choice_margin_vertical">22dp</dimen>
<!-- Voice Broadcast -->
<dimen name="voice_broadcast_recorder_button_size">48dp</dimen>
<dimen name="voice_broadcast_player_button_size">36dp</dimen>
<!-- Material 3 -->
<dimen name="collapsing_toolbar_layout_medium_size">112dp</dimen>
<dimen name="release_notes_vertical_margin_small">8dp</dimen>
<dimen name="release_notes_vertical_margin">16dp</dimen>
<dimen name="release_notes_vertical_margin_large">28dp</dimen>
</resources>

View file

@ -1,30 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2022 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.
-->
<resources>
<dimen name="text_size_title">24sp</dimen>
<dimen name="text_size_headline">18sp</dimen>
<dimen name="text_size_subtitle">16sp</dimen>
<dimen name="text_size_body">14sp</dimen>
<dimen name="text_size_caption">12sp</dimen>
<dimen name="text_size_micro">10sp</dimen>
<dimen name="text_size_nano">8sp</dimen>
<dimen name="text_size_button">14sp</dimen>
</resources>

View file

@ -1,63 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2022 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.
-->
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="UnusedResources">
<!--
Define all the colors used across the Element Android project
Source: https://www.figma.com/file/X4XTH9iS2KGJ2wFKDqkyed/Compound?node-id=1338%3A17947
Some colors are not used, but we want the palette to be complete so we ignore the lint error
UnusedResources for all the resources in this file
-->
<!-- For all themes -->
<color name="palette_azure">#368BD6</color>
<color name="palette_kiwi">#74D12C</color>
<color name="palette_grape">#AC3BA8</color>
<color name="palette_verde">#03B381</color>
<color name="palette_polly">#E64F7A</color>
<color name="palette_melon">#FF812D</color>
<color name="palette_element_green">#0DBD8B</color>
<color name="palette_element_orange">#D9B072</color>
<color name="palette_white">#FFFFFF</color>
<color name="palette_vermilion">#FF5B55</color>
<!-- (unused) -->
<color name="palette_ems">#7E69FF</color>
<color name="palette_aqua">#2DC2C5</color>
<color name="palette_prune">#5C56F5</color>
<color name="palette_links">#0086E6</color>
<!-- For light themes -->
<color name="palette_gray_25">#F4F6FA</color>
<color name="palette_gray_50">#E3E8F0</color>
<color name="palette_gray_100">#C1C6CD</color>
<color name="palette_gray_150">#8D97A5</color>
<color name="palette_gray_200">#737D8C</color>
<color name="palette_black_900">#17191C</color>
<!-- (unused) -->
<color name="palette_ice">#F4F9FD</color>
<!-- For dark themes -->
<color name="palette_gray_250">#A9B2BC</color>
<color name="palette_gray_300">#8E99A4</color>
<color name="palette_gray_400">#6F7882</color>
<color name="palette_gray_450">#394049</color>
<color name="palette_black_800">#15191E</color>
<color name="palette_black_950">#21262C</color>
</resources>

View file

@ -1,72 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2022 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.
-->
<resources>
<!-- Alias to the palette colors
Source: https://www.figma.com/file/X4XTH9iS2KGJ2wFKDqkyed/Compound?node-id=1521%3A23026 -->
<color name="element_accent_light">@android:color/black</color>
<color name="element_accent_dark">@android:color/white</color>
<color name="element_alert_light">@color/palette_vermilion</color>
<color name="element_alert_dark">@color/palette_vermilion</color>
<color name="element_link_light">@color/palette_links</color>
<color name="element_link_dark">@color/palette_links</color>
<!-- attr for content colors -->
<attr name="vctr_content_primary" format="color" />
<attr name="vctr_content_secondary" format="color" />
<attr name="vctr_content_tertiary" format="color" />
<attr name="vctr_content_quaternary" format="color" />
<attr name="vctr_content_quinary" format="color" />
<color name="element_content_primary_light">@color/palette_black_900</color>
<color name="element_content_secondary_light">@color/palette_gray_200</color>
<color name="element_content_tertiary_light">@color/palette_gray_150</color>
<color name="element_content_quaternary_light">@color/palette_gray_100</color>
<color name="element_content_quinary_light">@color/palette_gray_50</color>
<color name="element_content_primary_dark">@color/palette_white</color>
<color name="element_content_secondary_dark">@color/palette_gray_250</color>
<color name="element_content_tertiary_dark">@color/palette_gray_300</color>
<color name="element_content_quaternary_dark">@color/palette_gray_400</color>
<color name="element_content_quinary_dark">@color/palette_gray_450</color>
<attr name="vctr_system" format="color" />
<color name="element_system_light">@color/palette_gray_25</color>
<color name="element_system_dark">@color/palette_black_950</color>
<color name="element_background_light">@color/palette_white</color>
<color name="element_background_dark">@color/palette_black_800</color>
<color name="element_background_black">@android:color/black</color>
<color name="element_name_01">@color/palette_azure</color>
<color name="element_name_02">@color/palette_grape</color>
<color name="element_name_03">@color/palette_verde</color>
<color name="element_name_04">@color/palette_polly</color>
<color name="element_name_05">@color/palette_melon</color>
<color name="element_name_06">@color/palette_aqua</color>
<color name="element_name_07">@color/palette_prune</color>
<color name="element_name_08">@color/palette_kiwi</color>
<!-- Also create alias for rooms -->
<color name="element_room_01">@color/palette_verde</color>
<color name="element_room_02">@color/palette_azure</color>
<color name="element_room_03">@color/palette_grape</color>
</resources>

View file

@ -1,28 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2022 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.
-->
<resources>
<style name="BottomSheetItemTime">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:lines">1</item>
<item name="android:textColor">?vctr_content_secondary</item>
<item name="android:textSize">12sp</item>
</style>
</resources>

View file

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2022 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.
-->
<resources>
<style name="Widget.Vector.EditText.RichTextComposer" parent="Widget.AppCompat.EditText">
<item name="android:background">@android:color/transparent</item>
<item name="android:inputType">textCapSentences|textMultiLine</item>
<item name="android:maxLines">10</item>
<item name="android:minHeight">40dp</item>
<item name="android:paddingTop">10dp</item>
<item name="android:paddingBottom">10dp</item>
<item name="paddingStart">12dp</item>
<item name="android:clipToPadding">false</item>
<item name="android:textSize">15sp</item>
<item name="android:textColor">@color/element_content_primary_light</item>
</style>
</resources>

View file

@ -1,136 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2022 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.
-->
<resources>
<style name="Theme.ElementAndroid" parent="android:Theme.Material.Light.NoActionBar">
<!-- Element attribute for palette -->
<!-- content colors -->
<item name="vctr_content_primary">@color/element_content_primary_light</item>
<item name="vctr_content_secondary">@color/element_content_secondary_light</item>
<item name="vctr_content_tertiary">@color/element_content_tertiary_light</item>
<item name="vctr_content_quaternary">@color/element_content_quaternary_light</item>
<item name="vctr_content_quinary">@color/element_content_quinary_light</item>
<!-- system colors -->
<item name="vctr_system">@color/element_system_light</item>
<!-- other colors -->
<item name="vctr_fab_label_bg">@color/vctr_fab_label_bg_light</item>
<item name="vctr_fab_label_stroke">@color/vctr_fab_label_stroke_light</item>
<item name="vctr_fab_label_color">@color/vctr_fab_label_color_light</item>
<item name="vctr_touch_guard_bg">@color/vctr_touch_guard_bg_light</item>
<item name="vctr_keys_backup_banner_accent_color">@color/vctr_keys_backup_banner_accent_color_light</item>
<item name="vctr_room_active_widgets_banner_bg">@color/vctr_room_active_widgets_banner_bg_light</item>
<item name="vctr_room_active_widgets_banner_text">@color/vctr_room_active_widgets_banner_text_light</item>
<item name="vctr_reaction_background_off">@color/vctr_reaction_background_off_light</item>
<item name="vctr_reaction_background_on">@color/vctr_reaction_background_on_light</item>
<item name="vctr_waiting_background_color">@color/vctr_waiting_background_color_light</item>
<item name="vctr_chat_effect_snow_background">@color/vctr_chat_effect_snow_background_light</item>
<item name="vctr_toolbar_background">@color/element_background_light</item>
<item name="vctr_badge_color_border">@color/vctr_badge_color_border_light</item>
<!-- Presence Indicator colors -->
<item name="vctr_presence_indicator_offline">@color/vctr_presence_indicator_offline_light</item>
<item name="vctr_presence_indicator_online">@color/vctr_presence_indicator_online_light</item>
<item name="vctr_presence_indicator_busy">@color/vctr_presence_indicator_busy_light</item>
<item name="vctr_presence_indicator_away">@color/vctr_presence_indicator_away_light</item>
<!-- Some aliases -->
<item name="vctr_header_background">?vctr_system</item>
<item name="vctr_list_separator">?vctr_content_quinary</item>
<item name="vctr_list_separator_system">?vctr_system</item>
<item name="vctr_list_separator_on_surface">?vctr_system</item>
<item name="vctr_unread_background">?vctr_content_tertiary</item>
<!-- Material color -->
<item name="colorPrimary">@color/element_accent_light</item>
<item name="colorPrimaryVariant">@color/element_accent_light</item>
<item name="colorOnPrimary">@android:color/white</item>
<item name="colorSecondary">@color/element_accent_light</item>
<item name="colorSecondaryVariant">@color/element_accent_light</item>
<item name="colorOnSecondary">@android:color/white</item>
<item name="colorError">@color/element_alert_light</item>
<item name="colorOnError">@color/palette_white</item>
<item name="colorSurface">@color/element_system_light</item>
<item name="colorOnSurface">?vctr_content_primary</item>
<item name="android:colorBackground">@color/element_background_light</item>
<item name="colorOnBackground">?vctr_content_primary</item>
<!-- Default theme -->
<item name="android:textColorLink">@color/element_link_light</item>
<!-- Menu text color -->
<item name="android:actionMenuTextColor">?colorSecondary</item>
<!-- Default color for text View -->
<item name="android:textColorTertiary">@color/element_content_primary_light</item>
<!-- ANDROID SUPPORT ATTRIBUTES -->
<!-- disable the overscroll because setOverscrollHeader/Footer don't always work -->
<item name="android:overScrollMode">never</item>
<!--
<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
-->
<!--
<item name="lockscreen_theme">@style/PinCodeScreenStyle</item>
<item name="lockscreen_key_button_theme">@style/PinCodeKeyButtonStyle</item>
<item name="lockscreen_title_theme">@style/PinCodeTitleStyle</item>
<item name="lockscreen_hint_theme">@style/PinCodeHintStyle</item>
<item name="lockscreen_code_view_theme">@style/PinCodeDotsViewStyle</item>
<item name="lockscreen_delete_button_theme">@style/PinCodeDeleteButtonStyle</item>
<item name="lockscreen_fingerprint_button_theme">@style/PinCodeFingerprintButtonStyle</item>
<item name="lockscreen_next_theme">@style/PinCodeNextButtonStyle</item>
-->
<!-- Use dark color, to have enough contrast with icons color. windowLightStatusBar is only available in API 23+ -->
<item name="android:statusBarColor">@color/android_status_bar_background_dark</item>
<!-- Use dark color, to have enough contrast with icons color. windowLightNavigationBar is only available in API 27+ -->
<item name="android:navigationBarColor">@color/android_navigation_bar_background_dark</item>
<!-- enable window content transitions -->
<item name="android:windowContentTransitions">true</item>
<!--
<item name="vctr_social_login_button_google_style">@style/Widget.Vector.Button.Outlined.SocialLogin.Google.Light</item>
<item name="vctr_social_login_button_github_style">@style/Widget.Vector.Button.Outlined.SocialLogin.Github.Light</item>
<item name="vctr_social_login_button_facebook_style">@style/Widget.Vector.Button.Outlined.SocialLogin.Facebook.Light</item>
<item name="vctr_social_login_button_twitter_style">@style/Widget.Vector.Button.Outlined.SocialLogin.Twitter.Light</item>
<item name="vctr_social_login_button_apple_style">@style/Widget.Vector.Button.Outlined.SocialLogin.Apple.Light</item>
<item name="vctr_social_login_button_gitlab_style">@style/Widget.Vector.Button.Outlined.SocialLogin.Gitlab.Light</item>
-->
<!-- Keywords -->
<!--
<item name="vctr_keyword_style">@style/Widget.Vector.Keyword</item>
-->
<item name="vctr_toast_background">@color/vctr_toast_background_light</item>
<!-- Location sharing -->
<item name="vctr_live_location">@color/vctr_live_location_light</item>
<!-- Material 3 -->
<item name="collapsingToolbarLayoutMediumSize">@dimen/collapsing_toolbar_layout_medium_size</item>
<!-- WYSIWYG Editor -->
<item name="vctr_rich_text_editor_menu_button_background">@color/vctr_rich_text_editor_menu_button_background_light</item>
</style>
</resources>

View file

@ -47,9 +47,9 @@ import io.element.android.libraries.matrix.api.timeline.item.event.UnableToDecry
import io.element.android.libraries.matrix.api.timeline.item.event.UnknownContent
import io.element.android.libraries.matrix.api.timeline.item.event.UnknownMessageType
import io.element.android.libraries.matrix.api.timeline.item.event.VideoMessageType
import io.element.android.libraries.ui.strings.CommonStrings
import io.element.android.services.toolbox.api.strings.StringProvider
import javax.inject.Inject
import io.element.android.libraries.ui.strings.R as StringR
@ContributesBinding(SessionScope::class)
class DefaultRoomLastMessageFormatter @Inject constructor(
@ -66,7 +66,7 @@ class DefaultRoomLastMessageFormatter @Inject constructor(
return when (val content = event.content) {
is MessageContent -> processMessageContents(content, senderDisplayName, isDmRoom)
RedactedContent -> {
val message = sp.getString(StringR.string.common_message_removed)
val message = sp.getString(CommonStrings.common_message_removed)
if (!isDmRoom) {
prefix(message, senderDisplayName)
} else {
@ -77,7 +77,7 @@ class DefaultRoomLastMessageFormatter @Inject constructor(
content.body
}
is UnableToDecryptContent -> {
val message = sp.getString(StringR.string.common_decryption_error)
val message = sp.getString(CommonStrings.common_decryption_error)
if (!isDmRoom) {
prefix(message, senderDisplayName)
} else {
@ -94,7 +94,7 @@ class DefaultRoomLastMessageFormatter @Inject constructor(
stateContentFormatter.format(content, senderDisplayName, isOutgoing, RenderingMode.RoomList)
}
is FailedToParseMessageLikeContent, is FailedToParseStateContent, is UnknownContent -> {
prefixIfNeeded(sp.getString(StringR.string.common_unsupported_event), senderDisplayName, isDmRoom)
prefixIfNeeded(sp.getString(CommonStrings.common_unsupported_event), senderDisplayName, isDmRoom)
}
}
}
@ -111,19 +111,19 @@ class DefaultRoomLastMessageFormatter @Inject constructor(
messageType.body
}
is VideoMessageType -> {
sp.getString(StringR.string.common_video)
sp.getString(CommonStrings.common_video)
}
is ImageMessageType -> {
sp.getString(StringR.string.common_image)
sp.getString(CommonStrings.common_image)
}
is FileMessageType -> {
sp.getString(StringR.string.common_file)
sp.getString(CommonStrings.common_file)
}
is AudioMessageType -> {
sp.getString(StringR.string.common_audio)
sp.getString(CommonStrings.common_audio)
}
UnknownMessageType -> {
sp.getString(StringR.string.common_unsupported_event)
sp.getString(CommonStrings.common_unsupported_event)
}
is NoticeMessageType -> {
messageType.body

View file

@ -34,7 +34,7 @@ import io.element.android.libraries.matrix.api.timeline.item.event.StateContent
import io.element.android.libraries.matrix.api.timeline.item.event.StickerContent
import io.element.android.libraries.matrix.api.timeline.item.event.UnableToDecryptContent
import io.element.android.libraries.matrix.api.timeline.item.event.UnknownContent
import io.element.android.libraries.ui.strings.R
import io.element.android.libraries.ui.strings.CommonStrings
import io.element.android.services.toolbox.api.strings.StringProvider
import javax.inject.Inject
@ -71,7 +71,7 @@ class DefaultTimelineEventFormatter @Inject constructor(
if (buildMeta.isDebuggable) {
error("You should not use this formatter for this event: $event")
}
sp.getString(R.string.common_unsupported_event)
sp.getString(CommonStrings.common_unsupported_event)
}
}
}

View file

@ -19,10 +19,10 @@ package io.element.android.libraries.eventformatter.impl
import io.element.android.libraries.eventformatter.impl.mode.RenderingMode
import io.element.android.libraries.matrix.api.timeline.item.event.OtherState
import io.element.android.libraries.matrix.api.timeline.item.event.StateContent
import io.element.android.libraries.ui.strings.CommonStrings
import io.element.android.services.toolbox.api.strings.StringProvider
import timber.log.Timber
import javax.inject.Inject
import io.element.android.libraries.ui.strings.R as StringR
class StateContentFormatter @Inject constructor(
private val sp: StringProvider,
@ -50,7 +50,7 @@ class StateContentFormatter @Inject constructor(
sp.getString(R.string.state_event_room_created, senderDisplayName)
}
}
is OtherState.RoomEncryption -> sp.getString(StringR.string.common_encryption_enabled)
is OtherState.RoomEncryption -> sp.getString(CommonStrings.common_encryption_enabled)
is OtherState.RoomName -> {
val hasRoomName = content.name != null
when {

View file

@ -26,7 +26,6 @@ import io.element.android.libraries.matrix.api.media.FileInfo
import io.element.android.libraries.matrix.api.media.ImageInfo
import io.element.android.libraries.matrix.api.media.VideoInfo
import io.element.android.libraries.matrix.api.timeline.MatrixTimeline
import io.element.android.libraries.matrix.api.timeline.item.event.MessageContent
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow
import java.io.Closeable
@ -85,7 +84,7 @@ interface MatrixRoom : Closeable {
suspend fun sendFile(file: File, fileInfo: FileInfo, progressCallback: ProgressCallback?): Result<Unit>
suspend fun sendReaction(emoji: String, eventId: EventId): Result<Unit>
suspend fun toggleReaction(emoji: String, eventId: EventId): Result<Unit>
suspend fun forwardEvent(eventId: EventId, rooms: List<RoomId>): Result<Unit>

View file

@ -16,7 +16,10 @@
package io.element.android.libraries.matrix.api.timeline.item.event
import io.element.android.libraries.matrix.api.core.UserId
data class EventReaction(
val key: String,
val count: Long
val count: Long,
val senderIds: List<UserId>
)

View file

@ -63,7 +63,8 @@ class RustMatrixAuthenticationService @Inject constructor(
passphrase = null,
// TODO Oidc
// oidcClientMetadata = oidcClientMetadata,
customSlidingSyncProxy = null
customSlidingSyncProxy = null,
userAgent = null, // TODO
)
private var currentHomeserver = MutableStateFlow<MatrixHomeServerDetails?>(null)

View file

@ -303,9 +303,9 @@ class RustMatrixRoom(
}
}
override suspend fun sendReaction(emoji: String, eventId: EventId): Result<Unit> = withContext(coroutineDispatchers.io) {
override suspend fun toggleReaction(emoji: String, eventId: EventId): Result<Unit> = withContext(coroutineDispatchers.io) {
runCatching {
innerRoom.sendReaction(key = emoji, eventId = eventId.value)
innerRoom.toggleReaction(key = emoji, eventId = eventId.value)
}
}

View file

@ -78,7 +78,8 @@ private fun List<Reaction>?.map(): List<EventReaction> {
return this?.map {
EventReaction(
key = it.key,
count = it.count.toLong()
count = it.count.toLong(),
senderIds = it.senders.map { sender -> UserId(sender) }
)
} ?: emptyList()
}

View file

@ -72,7 +72,7 @@ class FakeMatrixRoom(
private var setTopicResult = Result.success(Unit)
private var updateAvatarResult = Result.success(Unit)
private var removeAvatarResult = Result.success(Unit)
private var sendReactionResult = Result.success(Unit)
private var toggleReactionResult = Result.success(Unit)
private var retrySendMessageResult = Result.success(Unit)
private var cancelSendResult = Result.success(Unit)
private var forwardEventResult = Result.success(Unit)
@ -82,8 +82,8 @@ class FakeMatrixRoom(
var sendMediaCount = 0
private set
var sendReactionCount = 0
private set
private val _myReactions = mutableSetOf<String>()
val myReactions: Set<String> = _myReactions
var retrySendMessageCount: Int = 0
private set
@ -150,9 +150,19 @@ class FakeMatrixRoom(
Result.success(Unit)
}
override suspend fun sendReaction(emoji: String, eventId: EventId): Result<Unit> {
sendReactionCount++
return sendReactionResult
override suspend fun toggleReaction(emoji: String, eventId: EventId): Result<Unit> {
if (toggleReactionResult.isFailure) {
// Don't do the toggle if we failed
return toggleReactionResult
}
if(_myReactions.contains(emoji)) {
_myReactions.remove(emoji)
} else {
_myReactions.add(emoji)
}
return toggleReactionResult
}
override suspend fun retrySendMessage(transactionId: String): Result<Unit> {
@ -352,8 +362,8 @@ class FakeMatrixRoom(
setTopicResult = result
}
fun givenSendReactionResult(result: Result<Unit>) {
sendReactionResult = result
fun givenToggleReactionResult(result: Result<Unit>) {
toggleReactionResult = result
}
fun givenRetrySendMessageResult(result: Result<Unit>) {

View file

@ -42,7 +42,7 @@ fun CheckableMatrixUserRow(
checked: Boolean,
matrixUser: MatrixUser,
modifier: Modifier = Modifier,
avatarSize: AvatarSize = AvatarSize.MEDIUM,
avatarSize: AvatarSize = AvatarSize.UserListItem,
onCheckedChange: (Boolean) -> Unit = {},
enabled: Boolean = true,
) = CheckableUserRow(

View file

@ -57,7 +57,7 @@ fun MatrixUserHeader(
horizontalAlignment = Alignment.CenterHorizontally
) {
Avatar(
matrixUser.getAvatarData(size = AvatarSize.HUGE),
matrixUser.getAvatarData(size = AvatarSize.UserHeader),
)
Spacer(modifier = Modifier.height(16.dp))
// Name

View file

@ -16,13 +16,10 @@
package io.element.android.libraries.matrix.ui.components
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
@ -49,7 +46,7 @@ import io.element.android.libraries.matrix.ui.model.getBestName
fun MatrixUserRow(
matrixUser: MatrixUser,
modifier: Modifier = Modifier,
avatarSize: AvatarSize = AvatarSize.Custom(36.dp),
avatarSize: AvatarSize = AvatarSize.UserListItem,
) = UserRow(
avatarData = matrixUser.getAvatarData(avatarSize),
name = matrixUser.getBestName(),
@ -67,16 +64,14 @@ fun UserRow(
Row(
modifier = modifier
.fillMaxWidth()
.padding(start = 16.dp, top = 8.dp, end = 16.dp, bottom = 8.dp)
.height(IntrinsicSize.Min),
.heightIn(min = 56.dp)
.padding(start = 16.dp, top = 4.dp, end = 16.dp, bottom = 4.dp),
verticalAlignment = Alignment.CenterVertically
) {
Avatar(avatarData)
Column(
modifier = Modifier
.padding(start = 12.dp)
.fillMaxHeight(),
verticalArrangement = Arrangement.SpaceBetween,
.padding(start = 12.dp),
) {
// Name
Text(

View file

@ -47,8 +47,7 @@ import io.element.android.libraries.designsystem.theme.components.Surface
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.room.RoomSummaryDetails
import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.ui.strings.R as StringR
import io.element.android.libraries.ui.strings.CommonStrings
@Composable
fun SelectedRoom(
@ -56,13 +55,14 @@ fun SelectedRoom(
modifier: Modifier = Modifier,
onRoomRemoved: (RoomSummaryDetails) -> Unit = {},
) {
Box(modifier = modifier
.width(56.dp)
Box(
modifier = modifier
.width(56.dp)
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
) {
Avatar(AvatarData(roomSummary.roomId.value, roomSummary.name, roomSummary.avatarURLString, AvatarSize.Custom(56.dp)))
Avatar(AvatarData(roomSummary.roomId.value, roomSummary.name, roomSummary.avatarURLString, AvatarSize.SelectedRoom))
Text(
text = roomSummary.name,
overflow = TextOverflow.Ellipsis,
@ -84,7 +84,7 @@ fun SelectedRoom(
) {
Icon(
imageVector = Icons.Default.Close,
contentDescription = stringResource(id = StringR.string.action_remove),
contentDescription = stringResource(id = CommonStrings.action_remove),
tint = MaterialTheme.colorScheme.onPrimary,
modifier = Modifier.padding(2.dp)
)
@ -102,8 +102,8 @@ internal fun SelectedRoomDarkPreview() = ElementPreviewDark { ContentToPreview()
@Composable
private fun ContentToPreview() {
SelectedRoom(roomSummary =
RoomSummaryDetails(
SelectedRoom(
roomSummary = RoomSummaryDetails(
roomId = RoomId("!room:domain"),
name = "roomName",
canonicalAlias = null,

View file

@ -47,7 +47,7 @@ import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.matrix.api.user.MatrixUser
import io.element.android.libraries.matrix.ui.model.getAvatarData
import io.element.android.libraries.matrix.ui.model.getBestName
import io.element.android.libraries.ui.strings.R as StringR
import io.element.android.libraries.ui.strings.CommonStrings
@Composable
fun SelectedUser(
@ -55,13 +55,14 @@ fun SelectedUser(
modifier: Modifier = Modifier,
onUserRemoved: (MatrixUser) -> Unit = {},
) {
Box(modifier = modifier
.width(56.dp)
Box(
modifier = modifier
.width(AvatarSize.SelectedUser.dp)
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
) {
Avatar(matrixUser.getAvatarData(size = AvatarSize.Custom(56.dp)))
Avatar(matrixUser.getAvatarData(size = AvatarSize.SelectedUser))
Text(
text = matrixUser.getBestName(),
overflow = TextOverflow.Ellipsis,
@ -83,7 +84,7 @@ fun SelectedUser(
) {
Icon(
imageVector = Icons.Default.Close,
contentDescription = stringResource(id = StringR.string.action_remove),
contentDescription = stringResource(id = CommonStrings.action_remove),
tint = MaterialTheme.colorScheme.onPrimary,
modifier = Modifier.padding(2.dp)
)

View file

@ -36,11 +36,11 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.text.toPx
import io.element.android.libraries.matrix.api.user.MatrixUser
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
@ -76,8 +76,8 @@ fun SelectedUsersList(
// users, the last visible user will be precisely half visible. This gives an obvious affordance that there are more entries and the list can be scrolled.
// For efficiency, we assume that all the children are the same width. If they needed to be different sizes we'd have to do this calculation each time
// they needed to be measured.
val minimumSpacing = with(LocalDensity.current) { 24.dp.toPx() }
val userWidth = with(LocalDensity.current) { 56.dp.toPx() }
val minimumSpacing = 24.dp.toPx()
val userWidth = 56.dp.toPx()
val userSpacing by remember {
derivedStateOf {
if (rowWidth == 0) {

View file

@ -19,11 +19,9 @@ package io.element.android.libraries.matrix.ui.components
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
@ -44,11 +42,12 @@ import io.element.android.libraries.designsystem.components.avatar.AvatarData
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.theme.components.Checkbox
import io.element.android.libraries.designsystem.theme.components.Divider
import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.theme.noFontPadding
import io.element.android.libraries.matrix.ui.model.getAvatarData
import io.element.android.libraries.ui.strings.R
import io.element.android.libraries.ui.strings.CommonStrings
@Composable
fun UnresolvedUserRow(
@ -59,15 +58,14 @@ fun UnresolvedUserRow(
Row(
modifier = modifier
.fillMaxWidth()
.padding(start = 16.dp, top = 8.dp, end = 16.dp, bottom = 8.dp)
.height(IntrinsicSize.Min),
.heightIn(min = 56.dp)
.padding(start = 16.dp, top = 8.dp, end = 16.dp, bottom = 8.dp),
verticalAlignment = Alignment.CenterVertically
) {
Avatar(avatarData)
Column(
modifier = Modifier
.padding(start = 12.dp)
.fillMaxHeight(),
.padding(start = 12.dp),
verticalArrangement = Arrangement.SpaceBetween,
) {
// ID
@ -82,7 +80,11 @@ fun UnresolvedUserRow(
)
// Warning
Row(modifier = Modifier.fillMaxWidth().padding(top = 3.dp)) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(top = 3.dp)
) {
Icon(
imageVector = Icons.Filled.Error,
contentDescription = "",
@ -94,7 +96,7 @@ fun UnresolvedUserRow(
)
Text(
text = stringResource(R.string.common_invite_unknown_profile),
text = stringResource(CommonStrings.common_invite_unknown_profile),
color = MaterialTheme.colorScheme.secondary,
fontSize = 12.sp,
lineHeight = 16.sp,
@ -141,7 +143,7 @@ fun CheckableUnresolvedUserRow(
internal fun UnresolvedUserRowPreview() =
ElementThemedPreview {
val matrixUser = aMatrixUser()
UnresolvedUserRow(matrixUser.getAvatarData(), matrixUser.userId.value)
UnresolvedUserRow(matrixUser.getAvatarData(size = AvatarSize.UserListItem), matrixUser.userId.value)
}
@Preview
@ -150,9 +152,12 @@ internal fun CheckableUnresolvedUserRowPreview() =
ElementThemedPreview {
val matrixUser = aMatrixUser()
Column {
CheckableUnresolvedUserRow(false, matrixUser.getAvatarData(AvatarSize.Custom(36.dp)), matrixUser.userId.value)
CheckableUnresolvedUserRow(true, matrixUser.getAvatarData(AvatarSize.Custom(36.dp)), matrixUser.userId.value)
CheckableUnresolvedUserRow(false, matrixUser.getAvatarData(AvatarSize.Custom(36.dp)), matrixUser.userId.value, enabled = false)
CheckableUnresolvedUserRow(true, matrixUser.getAvatarData(AvatarSize.Custom(36.dp)), matrixUser.userId.value, enabled = false)
CheckableUnresolvedUserRow(false, matrixUser.getAvatarData(AvatarSize.UserListItem), matrixUser.userId.value)
Divider()
CheckableUnresolvedUserRow(true, matrixUser.getAvatarData(AvatarSize.UserListItem), matrixUser.userId.value)
Divider()
CheckableUnresolvedUserRow(false, matrixUser.getAvatarData(AvatarSize.UserListItem), matrixUser.userId.value, enabled = false)
Divider()
CheckableUnresolvedUserRow(true, matrixUser.getAvatarData(AvatarSize.UserListItem), matrixUser.userId.value, enabled = false)
}
}

View file

@ -39,8 +39,8 @@ import coil.request.ImageRequest
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.debugPlaceholderBackground
import io.element.android.libraries.designsystem.theme.LocalColors
import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.theme.ElementTheme
/**
* An avatar that the user has selected, but which has not yet been uploaded to Matrix.
@ -69,7 +69,7 @@ fun UnsavedAvatar(
contentDescription = null,
)
} else {
Box(modifier = commonModifier.background(LocalColors.current.quinary)) {
Box(modifier = commonModifier.background(ElementTheme.legacyColors.quinary)) {
Icon(
imageVector = Icons.Outlined.AddAPhoto,
contentDescription = "",

View file

@ -23,7 +23,7 @@ import androidx.compose.material.icons.outlined.PhotoCamera
import androidx.compose.material.icons.outlined.PhotoLibrary
import androidx.compose.runtime.Immutable
import androidx.compose.ui.graphics.vector.ImageVector
import io.element.android.libraries.ui.strings.R
import io.element.android.libraries.ui.strings.CommonStrings
@Immutable
sealed class AvatarAction(
@ -31,7 +31,7 @@ sealed class AvatarAction(
val icon: ImageVector,
val destructive: Boolean = false,
) {
object TakePhoto : AvatarAction(titleResId = R.string.action_take_photo, icon = Icons.Outlined.PhotoCamera)
object ChoosePhoto : AvatarAction(titleResId = R.string.action_choose_photo, icon = Icons.Outlined.PhotoLibrary)
object Remove : AvatarAction(titleResId = R.string.action_remove, icon = Icons.Outlined.Delete, destructive = true)
object TakePhoto : AvatarAction(titleResId = CommonStrings.action_take_photo, icon = Icons.Outlined.PhotoCamera)
object ChoosePhoto : AvatarAction(titleResId = CommonStrings.action_choose_photo, icon = Icons.Outlined.PhotoLibrary)
object Remove : AvatarAction(titleResId = CommonStrings.action_remove, icon = Icons.Outlined.Delete, destructive = true)
}

View file

@ -20,7 +20,7 @@ import io.element.android.libraries.designsystem.components.avatar.AvatarData
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.matrix.api.user.MatrixUser
fun MatrixUser.getAvatarData(size: AvatarSize = AvatarSize.MEDIUM) = AvatarData(
fun MatrixUser.getAvatarData(size: AvatarSize) = AvatarData(
id = userId.value,
name = displayName,
url = avatarUrl,

View file

@ -47,7 +47,6 @@ dependencies {
implementation(projects.libraries.matrix.api)
implementation(projects.libraries.matrixui)
implementation(projects.libraries.designsystem)
implementation(projects.libraries.elementresources)
implementation(projects.libraries.uiStrings)
api(projects.libraries.permissions.api)

View file

@ -25,7 +25,6 @@ android {
}
dependencies {
implementation(projects.libraries.elementresources)
implementation(projects.libraries.uiStrings)
implementation(projects.libraries.androidutils)
implementation(projects.libraries.core)

View file

@ -70,7 +70,6 @@ import io.element.android.libraries.designsystem.VectorIcons
import io.element.android.libraries.designsystem.modifiers.applyIf
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.theme.LocalColors
import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.theme.components.Surface
import io.element.android.libraries.designsystem.theme.components.Text
@ -79,7 +78,8 @@ import io.element.android.libraries.matrix.api.media.MediaSource
import io.element.android.libraries.matrix.ui.components.AttachmentThumbnail
import io.element.android.libraries.matrix.ui.components.AttachmentThumbnailInfo
import io.element.android.libraries.matrix.ui.components.AttachmentThumbnailType
import io.element.android.libraries.ui.strings.R as StringR
import io.element.android.libraries.theme.ElementTheme
import io.element.android.libraries.ui.strings.CommonStrings
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@ -92,13 +92,15 @@ fun TextComposer(
onSendMessage: (String) -> Unit = {},
onResetComposerMode: () -> Unit = {},
onComposerTextChange: (CharSequence) -> Unit = {},
onAddAttachment:() -> Unit = {},
onAddAttachment: () -> Unit = {},
) {
val text = composerText.orEmpty()
Row(modifier.padding(
horizontal = 12.dp,
vertical = 8.dp
), verticalAlignment = Alignment.Bottom) {
Row(
modifier.padding(
horizontal = 12.dp,
vertical = 8.dp
), verticalAlignment = Alignment.Bottom
) {
AttachmentButton(onClick = onAddAttachment, modifier = Modifier.padding(vertical = 6.dp))
Spacer(modifier = Modifier.width(12.dp))
var lineCount by remember { mutableStateOf(0) }
@ -134,7 +136,7 @@ fun TextComposer(
lineCount = it.lineCount
},
textStyle = defaultTypography.copy(color = MaterialTheme.colorScheme.primary),
cursorBrush = SolidColor(LocalColors.current.accentColor),
cursorBrush = SolidColor(ElementTheme.legacyColors.accentColor),
decorationBox = { innerTextField ->
TextFieldDefaults.DecorationBox(
value = text,
@ -146,7 +148,7 @@ fun TextComposer(
contentPadding = PaddingValues(top = 10.dp, bottom = 10.dp, start = 12.dp, end = 42.dp),
interactionSource = remember { MutableInteractionSource() },
placeholder = {
Text(stringResource(StringR.string.common_message), style = defaultTypography)
Text(stringResource(CommonStrings.common_message), style = defaultTypography)
},
colors = TextFieldDefaults.colors(
unfocusedTextColor = MaterialTheme.colorScheme.secondary,
@ -206,18 +208,20 @@ private fun EditingModeView(
onResetComposerMode: () -> Unit,
modifier: Modifier = Modifier,
) {
Row(horizontalArrangement = Arrangement.spacedBy(6.dp),
Row(
horizontalArrangement = Arrangement.spacedBy(6.dp),
modifier = modifier
.fillMaxWidth()
.padding(horizontal = 12.dp, vertical = 8.dp)) {
.padding(horizontal = 12.dp, vertical = 8.dp)
) {
Icon(
resourceId = VectorIcons.Edit,
contentDescription = stringResource(R.string.editing),
contentDescription = stringResource(CommonStrings.common_editing),
tint = MaterialTheme.colorScheme.secondary,
modifier = Modifier.size(16.dp),
)
Text(
stringResource(R.string.editing),
stringResource(CommonStrings.common_editing),
style = ElementTextStyles.Regular.caption2,
textAlign = TextAlign.Start,
color = MaterialTheme.colorScheme.secondary,
@ -225,7 +229,7 @@ private fun EditingModeView(
)
Icon(
imageVector = Icons.Default.Close,
contentDescription = stringResource(StringR.string.action_close),
contentDescription = stringResource(CommonStrings.action_close),
tint = MaterialTheme.colorScheme.secondary,
modifier = Modifier
.size(16.dp)
@ -248,16 +252,11 @@ private fun ReplyToModeView(
onResetComposerMode: () -> Unit,
modifier: Modifier = Modifier,
) {
val paddings = if (attachmentThumbnailInfo != null) {
PaddingValues(start = 4.dp, end = 12.dp, top = 4.dp, bottom = 4.dp)
} else {
PaddingValues(start = 12.dp, end = 12.dp, top = 8.dp, bottom = 4.dp)
}
Row(
modifier
.clip(RoundedCornerShape(13.dp))
.background(MaterialTheme.colorScheme.surface)
.padding(paddings)
.padding(4.dp)
) {
if (attachmentThumbnailInfo != null) {
AttachmentThumbnail(
@ -267,45 +266,45 @@ private fun ReplyToModeView(
.size(36.dp)
.clip(RoundedCornerShape(9.dp))
)
Spacer(modifier = Modifier.width(8.dp))
}
Column(verticalArrangement = Arrangement.SpaceEvenly) {
Row(
horizontalArrangement = Arrangement.spacedBy(6.dp),
modifier = Modifier.fillMaxWidth()
) {
Text(
senderName,
style = ElementTextStyles.Regular.caption2.copy(fontWeight = FontWeight.Medium),
textAlign = TextAlign.Start,
color = MaterialTheme.colorScheme.primary,
modifier = Modifier.weight(1f)
)
Icon(
imageVector = Icons.Default.Close,
contentDescription = stringResource(StringR.string.action_close),
tint = MaterialTheme.colorScheme.secondary,
modifier = Modifier
.size(16.dp)
.clickable(
enabled = true,
onClick = onResetComposerMode,
interactionSource = MutableInteractionSource(),
indication = rememberRipple(bounded = false)
),
)
}
Spacer(modifier = Modifier.width(8.dp))
Column(
modifier = Modifier
.weight(1f)
.align(Alignment.CenterVertically)
) {
Text(
text = senderName,
modifier = Modifier.fillMaxWidth(),
style = ElementTextStyles.Regular.caption2.copy(fontWeight = FontWeight.Medium),
textAlign = TextAlign.Start,
color = MaterialTheme.colorScheme.primary,
)
Text(
modifier = Modifier.fillMaxWidth(),
text = text.orEmpty(),
style = ElementTextStyles.Regular.caption1,
textAlign = TextAlign.Start,
color = LocalColors.current.placeholder,
color = MaterialTheme.colorScheme.secondary,
maxLines = if (attachmentThumbnailInfo != null) 1 else 2,
overflow = TextOverflow.Ellipsis,
)
}
Icon(
imageVector = Icons.Default.Close,
contentDescription = stringResource(CommonStrings.action_close),
tint = MaterialTheme.colorScheme.secondary,
modifier = Modifier
.padding(end = 4.dp, top = 4.dp, start = 16.dp, bottom = 16.dp)
.size(16.dp)
.clickable(
enabled = true,
onClick = onResetComposerMode,
interactionSource = MutableInteractionSource(),
indication = rememberRipple(bounded = false)
),
)
}
}
@ -347,7 +346,7 @@ private fun BoxScope.SendButton(
Box(
modifier = modifier
.clip(CircleShape)
.background(if (canSendMessage) LocalColors.current.accentColor else Color.Transparent)
.background(if (canSendMessage) ElementTheme.legacyColors.accentColor else Color.Transparent)
.size(30.dp)
.align(Alignment.BottomEnd)
.applyIf(composerMode !is MessageComposerMode.Edit, ifTrue = {
@ -367,14 +366,14 @@ private fun BoxScope.SendButton(
else -> R.drawable.ic_send
}
val contentDescription = when (composerMode) {
is MessageComposerMode.Edit -> stringResource(StringR.string.action_edit)
else -> stringResource(StringR.string.action_send)
is MessageComposerMode.Edit -> stringResource(CommonStrings.action_edit)
else -> stringResource(CommonStrings.action_send)
}
Icon(
modifier = Modifier.size(16.dp),
resourceId = iconId,
contentDescription = contentDescription,
tint = if (canSendMessage) Color.White else LocalColors.current.quaternary
tint = if (canSendMessage) Color.White else ElementTheme.legacyColors.quaternary
)
}
}

View file

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2022 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:color="?attr/vctr_content_quinary" />
<item android:state_pressed="true" android:color="?attr/colorSecondary" />
<item android:state_hovered="true" android:color="?attr/colorSecondary" />
<item android:state_selected="true" android:color="?attr/colorSecondary" />
<item android:color="?attr/vctr_content_tertiary" />
</selector>

View file

@ -1,36 +0,0 @@
<!--
~ Copyright (c) 2022 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.
-->
<vector android:autoMirrored="true"
android:height="25dp"
android:viewportHeight="25"
android:viewportWidth="25"
android:width="25dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<path
android:fillColor="#00000000"
android:pathData="M13.9217,19.5H16.0147C18.4917,19.5 20.4997,17.4106 20.4997,14.8333C20.4997,12.256 18.4917,10.1666 16.0147,10.1666H6.5449"
android:strokeColor="#000000"
android:strokeLineCap="round"
android:strokeWidth="2" />
<path
android:fillColor="#00000000"
android:pathData="M9.1988,5.5L4.5,10.214L9.1988,14.9281"
android:strokeColor="#000000"
android:strokeLineCap="round"
android:strokeLineJoin="round"
android:strokeWidth="2" />
</vector>

View file

@ -1,27 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2022 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.
-->
<resources>
<dimen name="composer_min_height">56dp</dimen>
<dimen name="composer_attachment_size">52dp</dimen>
<dimen name="composer_attachment_margin">1dp</dimen>
<dimen name="rich_text_composer_corner_radius_single_line">28dp</dimen>
<dimen name="rich_text_composer_corner_radius_expanded">14dp</dimen>
<dimen name="rich_text_composer_menu_item_size">44dp</dimen>
</resources>

View file

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2022 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.
-->
<resources>
<string name="editing">Editing</string>
<string name="replying_to">Replying to %s</string>
<string name="quoting">Quoting</string>
</resources>

21
libraries/theme/README.md Normal file
View file

@ -0,0 +1,21 @@
# Theme Module
This module contains the theme tokens for the application, including those auto-generated from [Compound](https://github.com/vector-im/compound-design-tokens) and its mappings.
## Usage
The module contains public tokens and color schemes that are later used in `MaterialTheme` and added to `ElementTheme` for use in the application.
All tokens can be accessed through the `ElementTheme` object, which contains the following properties:
* `ElementTheme.legacyColors`: contains legacy colors and custom colors not present in either Material or Compound. Usage of these colors should be avoided, and they're usually prefixed in Figma with the `Zzz/` prefix or have no name at all.
* `ElementTheme.materialColors`: contains all Material color tokens. In Figma, they're prefixed with `M3/`. It's an alias to `MaterialTheme.colorScheme`.
* `ElementTheme.colors`: contains all Compound semantic color tokens. In Figma, they're prefixed with either `Light/` or `Dark/`.
* `ElementTheme.materialTypography`: contains the Material `Typography` values. In Figma, they're prefixed with `M3/`. It's an alias to `MaterialTheme.typography`.
* `ElementTheme.typography`: contains the Compound `TypographyTokens` values. In Figma, they're prefixed with `Android/font/`.
## Adding new tokens
All new tokens **should** come from Compound and added to the `compound.generated` package. To map the literal tokens to the semantic ones, you'll have to update both `compoundColorsLight` and `compoundColorsDark` in `CompoundColors.kt`.
As we're still migrating to using Compound tokens, it's possible that you might need to add some tokens manually. In that case, you should add them to `LegacyColors.kt` and map them later in `ElementColors.kt` so they can be used in light and dark themes. However, keep in mind this is just a temporary step, as those tokens should either be added later to Compound or replaced by Compound tokens in the future.

View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2022 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.
*/
plugins {
id("io.element.android-compose-library")
alias(libs.plugins.ksp)
}
android {
namespace = "io.element.android.libraries.theme"
dependencies {
ksp(libs.showkase.processor)
kspTest(libs.showkase.processor)
implementation(libs.accompanist.systemui)
}
}

View file

@ -14,14 +14,27 @@
* limitations under the License.
*/
package io.element.android.libraries.designsystem.theme
package io.element.android.libraries.theme
import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.graphics.Color
import io.element.android.libraries.theme.compound.generated.internal.DarkDesignTokens
import io.element.android.libraries.theme.compound.generated.internal.LightDesignTokens
import io.element.android.libraries.theme.compound.generated.SemanticColors
/**
* Element Android legacy color palette.
*
* ## IMPORTANT!
* **We should not add any new colors here, all new colors should come from [SemanticColors] instead.**
*
* If a design needs you to add a different color here, talk to some designer first, as they'll probably be using
* the legacy color palette.
*/
@Deprecated("Use SemanticColors instead")
@Stable
class ElementColors(
messageFromMeBackground: Color,
@ -30,9 +43,6 @@ class ElementColors(
quaternary: Color,
quinary: Color,
gray300: Color,
gray400: Color,
gray1400: Color,
textActionCritical: Color,
accentColor: Color,
placeholder: Color,
isLight: Boolean
@ -50,16 +60,7 @@ class ElementColors(
var quinary by mutableStateOf(quinary)
private set
var gray300 by mutableStateOf(gray400)
private set
var gray400 by mutableStateOf(gray400)
private set
var gray1400 by mutableStateOf(gray1400)
private set
var textActionCritical by mutableStateOf(textActionCritical)
var gray300 by mutableStateOf(gray300)
private set
var accentColor by mutableStateOf(accentColor)
@ -78,9 +79,6 @@ class ElementColors(
quaternary: Color = this.quaternary,
quinary: Color = this.quinary,
gray300: Color = this.gray300,
gray400: Color = this.gray400,
gray1400: Color = this.gray1400,
textActionCritical: Color = this.textActionCritical,
accentColor: Color = this.accentColor,
placeholder: Color = this.placeholder,
isLight: Boolean = this.isLight,
@ -91,9 +89,6 @@ class ElementColors(
quaternary = quaternary,
quinary = quinary,
gray300 = gray300,
gray400 = gray400,
gray1400 = gray1400,
textActionCritical = textActionCritical,
accentColor = accentColor,
placeholder = placeholder,
isLight = isLight,
@ -106,11 +101,32 @@ class ElementColors(
quaternary = other.quaternary
quinary = other.quinary
gray300 = other.gray300
gray400 = other.gray400
gray1400 = other.gray1400
textActionCritical = other.textActionCritical
accentColor = other.accentColor
placeholder = other.placeholder
isLight = other.isLight
}
}
internal fun elementColorsLight() = ElementColors(
messageFromMeBackground = SystemGrey5Light,
messageFromOtherBackground = SystemGrey6Light,
messageHighlightedBackground = Azure,
quaternary = Gray_100,
quinary = Gray_50,
gray300 = LightDesignTokens.colorGray300,
accentColor = ElementGreen,
placeholder = LightDesignTokens.colorGray800,
isLight = true,
)
internal fun elementColorsDark() = ElementColors(
messageFromMeBackground = SystemGrey5Dark,
messageFromOtherBackground = SystemGrey6Dark,
messageHighlightedBackground = Azure,
quaternary = Gray_400,
quinary = Gray_450,
gray300 = DarkDesignTokens.colorGray300,
accentColor = ElementGreen,
placeholder = DarkDesignTokens.colorGray800,
isLight = false,
)

View file

@ -14,12 +14,13 @@
* limitations under the License.
*/
package io.element.android.libraries.designsystem.theme
package io.element.android.libraries.theme
import android.os.Build
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.ColorScheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Typography
import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.runtime.Composable
@ -33,33 +34,88 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import com.google.accompanist.systemuicontroller.SystemUiController
import com.google.accompanist.systemuicontroller.rememberSystemUiController
import io.element.android.libraries.theme.compound.compoundColorsDark
import io.element.android.libraries.theme.compound.compoundColorsLight
import io.element.android.libraries.theme.compound.compoundTypography
import io.element.android.libraries.theme.compound.generated.SemanticColors
import io.element.android.libraries.theme.compound.generated.TypographyTokens
/**
* Inspired from https://medium.com/@lucasyujideveloper/54cbcbde1ace
*/
object ElementTheme {
val colors: ElementColors
/**
* The current [ElementColors] provided by [ElementTheme]. Usage of these colors is discouraged.
* In Figma, they usually have the `Zzz` prefix or have no name at all.
*/
val legacyColors: ElementColors
@Composable
@ReadOnlyComposable
get() = LocalColors.current
get() = LocalLegacyColors.current
/**
* The current [SemanticColors] provided by [ElementTheme].
* These come from Compound and are the recommended colors to use for custom components.
* In Figma, these colors usually have the `Light/` or `Dark/` prefix.
*/
val colors: SemanticColors
@Composable
@ReadOnlyComposable
get() = LocalCompoundColors.current
/**
* The current Material 3 [ColorScheme] provided by [ElementTheme], coming from [MaterialTheme].
* In Figma, these colors usually have the `M3/` prefix.
*/
val materialColors: ColorScheme
@Composable
@ReadOnlyComposable
get() = MaterialTheme.colorScheme
/**
* Material 3 [Typography] tokens. In Figma, these have the `M3/` prefix.
*/
val materialTypography: Typography
@Composable
@ReadOnlyComposable
get() = MaterialTheme.typography
/**
* Compound [Typography] tokens. In Figma, these have the `Android/font/` prefix.
*/
val typography: TypographyTokens = TypographyTokens
/**
* Returns whether the theme version used is the light or the dark one.
*/
val isLightTheme: Boolean
@Composable
@ReadOnlyComposable
get() = LocalCompoundColors.current.isLight
}
/* Global variables (application level) */
val LocalColors = staticCompositionLocalOf { elementColorsLight() }
internal val LocalLegacyColors = staticCompositionLocalOf { elementColorsLight() }
internal val LocalCompoundColors = staticCompositionLocalOf { compoundColorsLight }
@Composable
fun ElementTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
dynamicColor: Boolean = false, /* true to enable MaterialYou */
colors: ElementColors = if (darkTheme) elementColorsDark() else elementColorsLight(),
legacyColors: ElementColors = if (darkTheme) elementColorsDark() else elementColorsLight(),
compoundColors: SemanticColors = if (darkTheme) compoundColorsDark else compoundColorsLight,
materialLightColors: ColorScheme = materialColorSchemeLight,
materialDarkColors: ColorScheme = materialColorSchemeDark,
typography: Typography = compoundTypography,
content: @Composable () -> Unit,
) {
val systemUiController = rememberSystemUiController()
val currentColor = remember(darkTheme) {
colors.copy()
}.apply { updateColorsFrom(colors) }
val currentLegacyColor = remember(darkTheme) {
legacyColors.copy()
}.apply { updateColorsFrom(legacyColors) }
val currentCompoundColor = remember(darkTheme) {
compoundColors.copy()
}.apply { updateColorsFrom(compoundColors) }
val colorScheme = when {
dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
val context = LocalContext.current
@ -72,11 +128,12 @@ fun ElementTheme(
systemUiController.applyTheme(colorScheme = colorScheme, darkTheme = darkTheme)
}
CompositionLocalProvider(
LocalColors provides currentColor,
LocalLegacyColors provides currentLegacyColor,
LocalCompoundColors provides currentCompoundColor,
) {
MaterialTheme(
colorScheme = colorScheme,
// TODO typography =
typography = typography,
content = content
)
}
@ -92,7 +149,7 @@ fun ForcedDarkElementTheme(
) {
val systemUiController = rememberSystemUiController()
val colorScheme = MaterialTheme.colorScheme
val wasDarkTheme = !ElementTheme.colors.isLight
val wasDarkTheme = !ElementTheme.legacyColors.isLight
DisposableEffect(Unit) {
onDispose {
systemUiController.applyTheme(colorScheme, wasDarkTheme)

View file

@ -14,11 +14,18 @@
* limitations under the License.
*/
package io.element.android.libraries.designsystem
package io.element.android.libraries.theme
import androidx.compose.ui.graphics.Color
import com.airbnb.android.showkase.annotation.ShowkaseColor
// =================================================================================================
// IMPORTANT!
// We should not be adding any new colors here. This file is only for legacy colors.
// In fact, we should try to remove any references to these colors as we
// iterate through the designs. All new colors should come from Compound's Design Tokens.
// =================================================================================================
@ShowkaseColor(name = "LightGrey", group = "Material Design")
val LightGrey = Color(0x993C3C43)
@ -69,19 +76,3 @@ val ElementOrange = Color(0xFFD9B072)
val Vermilion = Color(0xFFFF5B55)
val LinkColor = Color(0xFF0086E6)
// Compound colors
val TextColorCriticalLight = Color(0xFFD51928)
val TextColorCriticalDark = Color(0xfffd3e3c)
val Compound_Gray_300_Light = Color(0xFFF0F2F5)
val Compound_Gray_300_Dark = Color(0xFF1D1F24)
val Compound_Gray_400_Light = Color(0xFFE1E6EC)
val Compound_Gray_400_Dark = Color(0xFF26282D)
val Compound_Gray_800_Light = Color(0xFF818A95)
val Compound_Gray_800_Dark = Color(0xFF656C76)
val Compound_Gray_1400_Light = Color(0xFF1B1D22)
val Compound_Gray_1400_Dark = Color(0xFFEBEEF2)

View file

@ -0,0 +1,106 @@
/*
* 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.theme
import androidx.compose.material3.darkColorScheme
import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import io.element.android.libraries.theme.compound.generated.internal.DarkDesignTokens
import io.element.android.libraries.theme.compound.generated.internal.LightDesignTokens
import io.element.android.libraries.theme.previews.ColorsSchemePreview
internal val materialColorSchemeLight = lightColorScheme(
primary = LightDesignTokens.colorGray1400,
onPrimary = LightDesignTokens.colorThemeBg,
primaryContainer = LightDesignTokens.colorThemeBg,
onPrimaryContainer = LightDesignTokens.colorGray1400,
inversePrimary = LightDesignTokens.colorThemeBg,
secondary = LightDesignTokens.colorGray900,
onSecondary = LightDesignTokens.colorThemeBg,
secondaryContainer = LightDesignTokens.colorGray400,
onSecondaryContainer = LightDesignTokens.colorGray1400,
tertiary = LightDesignTokens.colorGray900,
onTertiary = LightDesignTokens.colorThemeBg,
tertiaryContainer = LightDesignTokens.colorGray1400,
onTertiaryContainer = LightDesignTokens.colorThemeBg,
background = LightDesignTokens.colorThemeBg,
onBackground = LightDesignTokens.colorGray1400,
surface = LightDesignTokens.colorThemeBg,
onSurface = LightDesignTokens.colorGray1400,
surfaceVariant = LightDesignTokens.colorGray400,
onSurfaceVariant = LightDesignTokens.colorGray1400,
surfaceTint = LightDesignTokens.colorGray1000,
inverseSurface = LightDesignTokens.colorGray1300,
inverseOnSurface = LightDesignTokens.colorThemeBg,
error = LightDesignTokens.colorRed900,
onError = LightDesignTokens.colorThemeBg,
errorContainer = LightDesignTokens.colorRed400,
onErrorContainer = LightDesignTokens.colorRed900,
outline = LightDesignTokens.colorGray800,
outlineVariant = LightDesignTokens.colorAlphaGray400,
scrim = LightDesignTokens.colorGray1400,
)
internal val materialColorSchemeDark = darkColorScheme(
primary = DarkDesignTokens.colorGray1400,
onPrimary = DarkDesignTokens.colorThemeBg,
primaryContainer = DarkDesignTokens.colorThemeBg,
onPrimaryContainer = DarkDesignTokens.colorGray1400,
inversePrimary = DarkDesignTokens.colorThemeBg,
secondary = DarkDesignTokens.colorGray900,
onSecondary = DarkDesignTokens.colorThemeBg,
secondaryContainer = DarkDesignTokens.colorGray400,
onSecondaryContainer = DarkDesignTokens.colorGray1400,
tertiary = DarkDesignTokens.colorGray900,
onTertiary = DarkDesignTokens.colorThemeBg,
tertiaryContainer = DarkDesignTokens.colorGray1400,
onTertiaryContainer = DarkDesignTokens.colorThemeBg,
background = DarkDesignTokens.colorThemeBg,
onBackground = DarkDesignTokens.colorGray1400,
surface = DarkDesignTokens.colorThemeBg,
onSurface = DarkDesignTokens.colorGray1400,
surfaceVariant = DarkDesignTokens.colorGray400,
onSurfaceVariant = DarkDesignTokens.colorGray1400,
surfaceTint = DarkDesignTokens.colorGray1000,
inverseSurface = DarkDesignTokens.colorGray1300,
inverseOnSurface = DarkDesignTokens.colorThemeBg,
error = DarkDesignTokens.colorRed900,
onError = DarkDesignTokens.colorThemeBg,
errorContainer = DarkDesignTokens.colorRed400,
onErrorContainer = DarkDesignTokens.colorRed900,
outline = DarkDesignTokens.colorGray800,
outlineVariant = DarkDesignTokens.colorAlphaGray400,
scrim = DarkDesignTokens.colorGray300,
)
@Preview
@Composable
fun ColorsSchemePreviewLight() = ColorsSchemePreview(
Color.Black,
Color.White,
materialColorSchemeLight,
)
@Preview
@Composable
fun ColorsSchemePreviewDark() = ColorsSchemePreview(
Color.White,
Color.Black,
materialColorSchemeDark,
)

View file

@ -0,0 +1,133 @@
/*
* 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.theme.compound
import io.element.android.libraries.theme.compound.generated.internal.DarkDesignTokens
import io.element.android.libraries.theme.compound.generated.internal.LightDesignTokens
import io.element.android.libraries.theme.compound.generated.SemanticColors
internal val compoundColorsLight = SemanticColors(
textPrimary = LightDesignTokens.colorGray1400,
textSecondary = LightDesignTokens.colorGray900,
textPlaceholder = LightDesignTokens.colorGray800,
textDisabled = LightDesignTokens.colorGray800,
textActionPrimary = LightDesignTokens.colorGray1400,
textActionAccent = LightDesignTokens.colorGreen900,
textLinkExternal = LightDesignTokens.colorBlue900,
textCriticalPrimary = LightDesignTokens.colorRed900,
textSuccessPrimary = LightDesignTokens.colorGreen900,
textInfoPrimary = LightDesignTokens.colorBlue900,
textOnSolidPrimary = LightDesignTokens.colorThemeBg,
bgSubtlePrimary = LightDesignTokens.colorGray400,
bgSubtleSecondary = LightDesignTokens.colorBgSubtleSecondaryLevel0,
bgCanvasDefault = LightDesignTokens.colorBgCanvasDefaultLevel1,
bgCanvasDisabled = LightDesignTokens.colorGray200,
bgActionPrimaryRest = LightDesignTokens.colorGray1400,
bgActionPrimaryHovered = LightDesignTokens.colorGray1200,
bgActionPrimaryPressed = LightDesignTokens.colorGray1100,
bgActionPrimaryDisabled = LightDesignTokens.colorGray700,
bgActionSecondaryRest = LightDesignTokens.colorThemeBg,
bgActionSecondaryHovered = LightDesignTokens.colorAlphaGray200,
bgActionSecondaryPressed = LightDesignTokens.colorAlphaGray300,
bgCriticalPrimary = LightDesignTokens.colorRed900,
bgCriticalHovered = LightDesignTokens.colorRed1000,
bgCriticalSubtle = LightDesignTokens.colorRed200,
bgCriticalSubtleHovered = LightDesignTokens.colorRed300,
bgSuccessSubtle = LightDesignTokens.colorGreen200,
bgInfoSubtle = LightDesignTokens.colorBlue200,
borderDisabled = LightDesignTokens.colorGray500,
borderFocused = LightDesignTokens.colorBlue900,
borderInteractivePrimary = LightDesignTokens.colorGray800,
borderInteractiveSecondary = LightDesignTokens.colorGray600,
borderInteractiveHovered = LightDesignTokens.colorGray1100,
borderCriticalPrimary = LightDesignTokens.colorRed900,
borderCriticalHovered = LightDesignTokens.colorRed1000,
borderCriticalSubtle = LightDesignTokens.colorRed500,
borderSuccessSubtle = LightDesignTokens.colorGreen500,
borderInfoSubtle = LightDesignTokens.colorBlue500,
iconPrimary = LightDesignTokens.colorGray1400,
iconSecondary = LightDesignTokens.colorGray900,
iconTertiary = LightDesignTokens.colorGray800,
iconQuaternary = LightDesignTokens.colorGray700,
iconDisabled = LightDesignTokens.colorGray700,
iconPrimaryAlpha = LightDesignTokens.colorAlphaGray1400,
iconSecondaryAlpha = LightDesignTokens.colorAlphaGray900,
iconTertiaryAlpha = LightDesignTokens.colorAlphaGray800,
iconQuaternaryAlpha = LightDesignTokens.colorAlphaGray700,
iconAccentTertiary = LightDesignTokens.colorGreen800,
iconCriticalPrimary = LightDesignTokens.colorRed900,
iconSuccessPrimary = LightDesignTokens.colorGreen900,
iconInfoPrimary = LightDesignTokens.colorBlue900,
iconOnSolidPrimary = LightDesignTokens.colorThemeBg,
isLight = true,
)
internal val compoundColorsDark = SemanticColors(
textPrimary = DarkDesignTokens.colorGray1400,
textSecondary = DarkDesignTokens.colorGray900,
textPlaceholder = DarkDesignTokens.colorGray800,
textDisabled = DarkDesignTokens.colorGray800,
textActionPrimary = DarkDesignTokens.colorGray1400,
textActionAccent = DarkDesignTokens.colorGreen900,
textLinkExternal = DarkDesignTokens.colorBlue900,
textCriticalPrimary = DarkDesignTokens.colorRed900,
textSuccessPrimary = DarkDesignTokens.colorGreen900,
textInfoPrimary = DarkDesignTokens.colorBlue900,
textOnSolidPrimary = DarkDesignTokens.colorThemeBg,
bgSubtlePrimary = DarkDesignTokens.colorGray400,
bgSubtleSecondary = DarkDesignTokens.colorBgSubtleSecondaryLevel0,
bgCanvasDefault = DarkDesignTokens.colorBgCanvasDefaultLevel1,
bgCanvasDisabled = DarkDesignTokens.colorGray200,
bgActionPrimaryRest = DarkDesignTokens.colorGray1400,
bgActionPrimaryHovered = DarkDesignTokens.colorGray1200,
bgActionPrimaryPressed = DarkDesignTokens.colorGray1100,
bgActionPrimaryDisabled = DarkDesignTokens.colorGray700,
bgActionSecondaryRest = DarkDesignTokens.colorThemeBg,
bgActionSecondaryHovered = DarkDesignTokens.colorAlphaGray200,
bgActionSecondaryPressed = DarkDesignTokens.colorAlphaGray300,
bgCriticalPrimary = DarkDesignTokens.colorRed900,
bgCriticalHovered = DarkDesignTokens.colorRed1000,
bgCriticalSubtle = DarkDesignTokens.colorRed200,
bgCriticalSubtleHovered = DarkDesignTokens.colorRed300,
bgSuccessSubtle = DarkDesignTokens.colorGreen200,
bgInfoSubtle = DarkDesignTokens.colorBlue200,
borderDisabled = DarkDesignTokens.colorGray500,
borderFocused = DarkDesignTokens.colorBlue900,
borderInteractivePrimary = DarkDesignTokens.colorGray800,
borderInteractiveSecondary = DarkDesignTokens.colorGray600,
borderInteractiveHovered = DarkDesignTokens.colorGray1100,
borderCriticalPrimary = DarkDesignTokens.colorRed900,
borderCriticalHovered = DarkDesignTokens.colorRed1000,
borderCriticalSubtle = DarkDesignTokens.colorRed500,
borderSuccessSubtle = DarkDesignTokens.colorGreen500,
borderInfoSubtle = DarkDesignTokens.colorBlue500,
iconPrimary = DarkDesignTokens.colorGray1400,
iconSecondary = DarkDesignTokens.colorGray900,
iconTertiary = DarkDesignTokens.colorGray800,
iconQuaternary = DarkDesignTokens.colorGray700,
iconDisabled = DarkDesignTokens.colorGray700,
iconPrimaryAlpha = DarkDesignTokens.colorAlphaGray1400,
iconSecondaryAlpha = DarkDesignTokens.colorAlphaGray900,
iconTertiaryAlpha = DarkDesignTokens.colorAlphaGray800,
iconQuaternaryAlpha = DarkDesignTokens.colorAlphaGray700,
iconAccentTertiary = DarkDesignTokens.colorGreen800,
iconCriticalPrimary = DarkDesignTokens.colorRed900,
iconSuccessPrimary = DarkDesignTokens.colorGreen900,
iconInfoPrimary = DarkDesignTokens.colorBlue900,
iconOnSolidPrimary = DarkDesignTokens.colorThemeBg,
isLight = false,
)

View file

@ -0,0 +1,98 @@
/*
* 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.theme.compound
import androidx.compose.material3.Typography
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.em
import androidx.compose.ui.unit.sp
import io.element.android.libraries.theme.compound.generated.TypographyTokens
import com.airbnb.android.showkase.annotation.ShowkaseTypography
// 32px (Material) vs 34px, it's the closest one
@ShowkaseTypography(name = "M3 Headline Large", group = "Compound")
internal val compoundHeadingXlRegular = TypographyTokens.fontHeadingXlRegular
// both are 28px
@ShowkaseTypography(name = "M3 Headline Medium", group = "Compound")
internal val compoundHeadingLgRegular = TypographyTokens.fontHeadingLgRegular
// These are the default M3 values, but we're setting them manually so an update in M3 doesn't break our designs
@ShowkaseTypography(name = "M3 Headline Small", group = "Compound")
internal val defaultHeadlineSmall = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.Normal,
lineHeight = 32.sp,
fontSize = 24.sp,
letterSpacing = 0.em,
)
// 22px (Material) vs 20px, it's the closest one
@ShowkaseTypography(name = "M3 Title Large", group = "Compound")
internal val compoundHeadingMdRegular = TypographyTokens.fontHeadingMdRegular
// 16px both
@ShowkaseTypography(name = "M3 Title Medium", group = "Compound")
internal val compoundBodyLgMedium = TypographyTokens.fontBodyLgMedium
// 14px both
@ShowkaseTypography(name = "M3 Title Small", group = "Compound")
internal val compoundBodyMdMedium = TypographyTokens.fontBodyMdMedium
// 16px both
@ShowkaseTypography(name = "M3 Body Large", group = "Compound")
internal val compoundBodyLgRegular = TypographyTokens.fontBodyLgRegular
// 14px both
@ShowkaseTypography(name = "M3 Body Medium", group = "Compound")
internal val compoundBodyMdRegular = TypographyTokens.fontBodyMdRegular
// 12px both
@ShowkaseTypography(name = "M3 Body Small", group = "Compound")
internal val compoundBodySmRegular = TypographyTokens.fontBodySmRegular
// 14px both, Title Small uses the same token so we have to declare it twice
@ShowkaseTypography(name = "M3 Label Large", group = "Compound")
internal val compoundBodyMdMedium_LabelLarge = TypographyTokens.fontBodyMdMedium
// 12px both
@ShowkaseTypography(name = "M3 Label Medium", group = "Compound")
internal val compoundBodySmMedium = TypographyTokens.fontBodySmMedium
// 11px both
@ShowkaseTypography(name = "M3 Label Small", group = "Compound")
internal val compoundBodyXsMedium = TypographyTokens.fontBodyXsMedium
internal val compoundTypography = Typography(
// displayLarge = , 57px (Material) size. We have no equivalent
// displayMedium = , 45px (Material) size. We have no equivalent
// displaySmall = , 36px (Material) size. We have no equivalent
headlineLarge = compoundHeadingXlRegular,
headlineMedium = compoundHeadingLgRegular,
headlineSmall = defaultHeadlineSmall,
titleLarge = compoundHeadingMdRegular,
titleMedium = compoundBodyLgMedium,
titleSmall = compoundBodyMdMedium,
bodyLarge = compoundBodyLgRegular,
bodyMedium = compoundBodyMdRegular,
bodySmall = compoundBodySmRegular,
labelLarge = compoundBodyMdMedium_LabelLarge,
labelMedium = compoundBodySmMedium,
labelSmall = compoundBodyXsMedium,
)

View file

@ -0,0 +1 @@
Files inside this package are generated automatically from the Compound project (https://github.com/vector-im/compound-design-tokens) and will be batch-replaced when new tokens are generated.

View file

@ -0,0 +1,421 @@
/*
* 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.
*/
@file:Suppress("all")
package io.element.android.libraries.theme.compound.generated
import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.compose.ui.graphics.Color
// Do not edit directly
// Generated on Tue, 27 Jun 2023 11:49:05 GMT
/**
* This class holds all the semantic tokens of the Compound theme.
*/
@Stable
class SemanticColors(
bgActionPrimaryDisabled: Color,
bgActionPrimaryHovered: Color,
bgActionPrimaryPressed: Color,
bgActionPrimaryRest: Color,
bgActionSecondaryHovered: Color,
bgActionSecondaryPressed: Color,
bgActionSecondaryRest: Color,
bgCanvasDefault: Color,
bgCanvasDisabled: Color,
bgCriticalHovered: Color,
bgCriticalPrimary: Color,
bgCriticalSubtle: Color,
bgCriticalSubtleHovered: Color,
bgInfoSubtle: Color,
bgSubtlePrimary: Color,
bgSubtleSecondary: Color,
bgSuccessSubtle: Color,
borderCriticalHovered: Color,
borderCriticalPrimary: Color,
borderCriticalSubtle: Color,
borderDisabled: Color,
borderFocused: Color,
borderInfoSubtle: Color,
borderInteractiveHovered: Color,
borderInteractivePrimary: Color,
borderInteractiveSecondary: Color,
borderSuccessSubtle: Color,
iconAccentTertiary: Color,
iconCriticalPrimary: Color,
iconDisabled: Color,
iconInfoPrimary: Color,
iconOnSolidPrimary: Color,
iconPrimary: Color,
iconPrimaryAlpha: Color,
iconQuaternary: Color,
iconQuaternaryAlpha: Color,
iconSecondary: Color,
iconSecondaryAlpha: Color,
iconSuccessPrimary: Color,
iconTertiary: Color,
iconTertiaryAlpha: Color,
textActionAccent: Color,
textActionPrimary: Color,
textCriticalPrimary: Color,
textDisabled: Color,
textInfoPrimary: Color,
textLinkExternal: Color,
textOnSolidPrimary: Color,
textPlaceholder: Color,
textPrimary: Color,
textSecondary: Color,
textSuccessPrimary: Color,
isLight: Boolean,
) {
var isLight by mutableStateOf(isLight)
private set
/** Background colour for primary actions. State: Disabled. */
var bgActionPrimaryDisabled by mutableStateOf(bgActionPrimaryDisabled)
private set
/** Background colour for primary actions. State: Hover. */
var bgActionPrimaryHovered by mutableStateOf(bgActionPrimaryHovered)
private set
/** Background colour for primary actions. State: Pressed. */
var bgActionPrimaryPressed by mutableStateOf(bgActionPrimaryPressed)
private set
/** Background colour for primary actions. State: Rest. */
var bgActionPrimaryRest by mutableStateOf(bgActionPrimaryRest)
private set
/** Background colour for secondary actions. State: Hover. */
var bgActionSecondaryHovered by mutableStateOf(bgActionSecondaryHovered)
private set
/** Background colour for secondary actions. State: Pressed. */
var bgActionSecondaryPressed by mutableStateOf(bgActionSecondaryPressed)
private set
/** Background colour for secondary actions. State: Rest. */
var bgActionSecondaryRest by mutableStateOf(bgActionSecondaryRest)
private set
/** Default global background for the user interface.
Elevation: Default (Level 0) */
var bgCanvasDefault by mutableStateOf(bgCanvasDefault)
private set
/** Default background for disabled elements. There's no minimum contrast requirement. */
var bgCanvasDisabled by mutableStateOf(bgCanvasDisabled)
private set
/** High-contrast background color for critical state. State: Hover. */
var bgCriticalHovered by mutableStateOf(bgCriticalHovered)
private set
/** High-contrast background color for critical state. State: Rest. */
var bgCriticalPrimary by mutableStateOf(bgCriticalPrimary)
private set
/** Default subtle critical surfaces. State: Rest. */
var bgCriticalSubtle by mutableStateOf(bgCriticalSubtle)
private set
/** Default subtle critical surfaces. State: Hover. */
var bgCriticalSubtleHovered by mutableStateOf(bgCriticalSubtleHovered)
private set
/** Subtle background colour for informational elements. State: Rest. */
var bgInfoSubtle by mutableStateOf(bgInfoSubtle)
private set
/** Medium contrast surfaces.
Elevation: Default (Level 2). */
var bgSubtlePrimary by mutableStateOf(bgSubtlePrimary)
private set
/** Low contrast surfaces.
Elevation: Default (Level 1). */
var bgSubtleSecondary by mutableStateOf(bgSubtleSecondary)
private set
/** Subtle background colour for success state elements. State: Rest. */
var bgSuccessSubtle by mutableStateOf(bgSuccessSubtle)
private set
/** High-contrast border for critical state. State: Hover. */
var borderCriticalHovered by mutableStateOf(borderCriticalHovered)
private set
/** High-contrast border for critical state. State: Rest. */
var borderCriticalPrimary by mutableStateOf(borderCriticalPrimary)
private set
/** Subtle border colour for critical state elements. */
var borderCriticalSubtle by mutableStateOf(borderCriticalSubtle)
private set
/** Used for borders of disabled elements. There's no minimum contrast requirement. */
var borderDisabled by mutableStateOf(borderDisabled)
private set
/** Used for the focus state outline. */
var borderFocused by mutableStateOf(borderFocused)
private set
/** Subtle border colour for informational elements. */
var borderInfoSubtle by mutableStateOf(borderInfoSubtle)
private set
/** Default contrast for accessible interactive element borders. State: Hover. */
var borderInteractiveHovered by mutableStateOf(borderInteractiveHovered)
private set
/** Default contrast for accessible interactive element borders. State: Rest. */
var borderInteractivePrimary by mutableStateOf(borderInteractivePrimary)
private set
/** ⚠️ Lowest contrast for non-accessible interactive element borders, <3:1. Only use for non-essential borders. Do not rely exclusively on them. State: Rest. */
var borderInteractiveSecondary by mutableStateOf(borderInteractiveSecondary)
private set
/** Subtle border colour for success state elements. */
var borderSuccessSubtle by mutableStateOf(borderSuccessSubtle)
private set
/** Lowest contrast accessible accent icons. */
var iconAccentTertiary by mutableStateOf(iconAccentTertiary)
private set
/** High-contrast icon for critical state. State: Rest. */
var iconCriticalPrimary by mutableStateOf(iconCriticalPrimary)
private set
/** Use for icons in disabled elements. There's no minimum contrast requirement. */
var iconDisabled by mutableStateOf(iconDisabled)
private set
/** High-contrast icon for informational elements. */
var iconInfoPrimary by mutableStateOf(iconInfoPrimary)
private set
/** Highest contrast icon color on top of high-contrast solid backgrounds like primary, accent, or destructive actions. */
var iconOnSolidPrimary by mutableStateOf(iconOnSolidPrimary)
private set
/** Highest contrast icons. */
var iconPrimary by mutableStateOf(iconPrimary)
private set
/** Translucent version of primary icon. Refer to it for intended use. */
var iconPrimaryAlpha by mutableStateOf(iconPrimaryAlpha)
private set
/** ⚠️ Lowest contrast non-accessible icons, <3:1. Only use for non-essential icons. Do not rely exclusively on them. */
var iconQuaternary by mutableStateOf(iconQuaternary)
private set
/** Translucent version of quaternary icon. Refer to it for intended use. */
var iconQuaternaryAlpha by mutableStateOf(iconQuaternaryAlpha)
private set
/** Lower contrast icons. */
var iconSecondary by mutableStateOf(iconSecondary)
private set
/** Translucent version of secondary icon. Refer to it for intended use. */
var iconSecondaryAlpha by mutableStateOf(iconSecondaryAlpha)
private set
/** High-contrast icon for success state elements. */
var iconSuccessPrimary by mutableStateOf(iconSuccessPrimary)
private set
/** Lowest contrast accessible icons. */
var iconTertiary by mutableStateOf(iconTertiary)
private set
/** Translucent version of tertiary icon. Refer to it for intended use. */
var iconTertiaryAlpha by mutableStateOf(iconTertiaryAlpha)
private set
/** Accent text colour for plain actions. */
var textActionAccent by mutableStateOf(textActionAccent)
private set
/** Default text colour for plain actions. */
var textActionPrimary by mutableStateOf(textActionPrimary)
private set
/** Text colour for destructive plain actions. */
var textCriticalPrimary by mutableStateOf(textCriticalPrimary)
private set
/** Use for regular text in disabled elements. There's no minimum contrast requirement. */
var textDisabled by mutableStateOf(textDisabled)
private set
/** Accent text colour for informational elements. */
var textInfoPrimary by mutableStateOf(textInfoPrimary)
private set
/** Text colour for external links. */
var textLinkExternal by mutableStateOf(textLinkExternal)
private set
/** For use as text color on top of high-contrast solid backgrounds like primary, accent, or destructive actions. */
var textOnSolidPrimary by mutableStateOf(textOnSolidPrimary)
private set
/** Use for placeholder text. Placeholder text should be non-essential. Do not rely exclusively on it. */
var textPlaceholder by mutableStateOf(textPlaceholder)
private set
/** Highest contrast text. */
var textPrimary by mutableStateOf(textPrimary)
private set
/** Lowest contrast text. */
var textSecondary by mutableStateOf(textSecondary)
private set
/** Accent text colour for success state elements. */
var textSuccessPrimary by mutableStateOf(textSuccessPrimary)
private set
fun copy(
bgActionPrimaryDisabled: Color = this.bgActionPrimaryDisabled,
bgActionPrimaryHovered: Color = this.bgActionPrimaryHovered,
bgActionPrimaryPressed: Color = this.bgActionPrimaryPressed,
bgActionPrimaryRest: Color = this.bgActionPrimaryRest,
bgActionSecondaryHovered: Color = this.bgActionSecondaryHovered,
bgActionSecondaryPressed: Color = this.bgActionSecondaryPressed,
bgActionSecondaryRest: Color = this.bgActionSecondaryRest,
bgCanvasDefault: Color = this.bgCanvasDefault,
bgCanvasDisabled: Color = this.bgCanvasDisabled,
bgCriticalHovered: Color = this.bgCriticalHovered,
bgCriticalPrimary: Color = this.bgCriticalPrimary,
bgCriticalSubtle: Color = this.bgCriticalSubtle,
bgCriticalSubtleHovered: Color = this.bgCriticalSubtleHovered,
bgInfoSubtle: Color = this.bgInfoSubtle,
bgSubtlePrimary: Color = this.bgSubtlePrimary,
bgSubtleSecondary: Color = this.bgSubtleSecondary,
bgSuccessSubtle: Color = this.bgSuccessSubtle,
borderCriticalHovered: Color = this.borderCriticalHovered,
borderCriticalPrimary: Color = this.borderCriticalPrimary,
borderCriticalSubtle: Color = this.borderCriticalSubtle,
borderDisabled: Color = this.borderDisabled,
borderFocused: Color = this.borderFocused,
borderInfoSubtle: Color = this.borderInfoSubtle,
borderInteractiveHovered: Color = this.borderInteractiveHovered,
borderInteractivePrimary: Color = this.borderInteractivePrimary,
borderInteractiveSecondary: Color = this.borderInteractiveSecondary,
borderSuccessSubtle: Color = this.borderSuccessSubtle,
iconAccentTertiary: Color = this.iconAccentTertiary,
iconCriticalPrimary: Color = this.iconCriticalPrimary,
iconDisabled: Color = this.iconDisabled,
iconInfoPrimary: Color = this.iconInfoPrimary,
iconOnSolidPrimary: Color = this.iconOnSolidPrimary,
iconPrimary: Color = this.iconPrimary,
iconPrimaryAlpha: Color = this.iconPrimaryAlpha,
iconQuaternary: Color = this.iconQuaternary,
iconQuaternaryAlpha: Color = this.iconQuaternaryAlpha,
iconSecondary: Color = this.iconSecondary,
iconSecondaryAlpha: Color = this.iconSecondaryAlpha,
iconSuccessPrimary: Color = this.iconSuccessPrimary,
iconTertiary: Color = this.iconTertiary,
iconTertiaryAlpha: Color = this.iconTertiaryAlpha,
textActionAccent: Color = this.textActionAccent,
textActionPrimary: Color = this.textActionPrimary,
textCriticalPrimary: Color = this.textCriticalPrimary,
textDisabled: Color = this.textDisabled,
textInfoPrimary: Color = this.textInfoPrimary,
textLinkExternal: Color = this.textLinkExternal,
textOnSolidPrimary: Color = this.textOnSolidPrimary,
textPlaceholder: Color = this.textPlaceholder,
textPrimary: Color = this.textPrimary,
textSecondary: Color = this.textSecondary,
textSuccessPrimary: Color = this.textSuccessPrimary,
isLight: Boolean = this.isLight,
) = SemanticColors(
bgActionPrimaryDisabled = bgActionPrimaryDisabled,
bgActionPrimaryHovered = bgActionPrimaryHovered,
bgActionPrimaryPressed = bgActionPrimaryPressed,
bgActionPrimaryRest = bgActionPrimaryRest,
bgActionSecondaryHovered = bgActionSecondaryHovered,
bgActionSecondaryPressed = bgActionSecondaryPressed,
bgActionSecondaryRest = bgActionSecondaryRest,
bgCanvasDefault = bgCanvasDefault,
bgCanvasDisabled = bgCanvasDisabled,
bgCriticalHovered = bgCriticalHovered,
bgCriticalPrimary = bgCriticalPrimary,
bgCriticalSubtle = bgCriticalSubtle,
bgCriticalSubtleHovered = bgCriticalSubtleHovered,
bgInfoSubtle = bgInfoSubtle,
bgSubtlePrimary = bgSubtlePrimary,
bgSubtleSecondary = bgSubtleSecondary,
bgSuccessSubtle = bgSuccessSubtle,
borderCriticalHovered = borderCriticalHovered,
borderCriticalPrimary = borderCriticalPrimary,
borderCriticalSubtle = borderCriticalSubtle,
borderDisabled = borderDisabled,
borderFocused = borderFocused,
borderInfoSubtle = borderInfoSubtle,
borderInteractiveHovered = borderInteractiveHovered,
borderInteractivePrimary = borderInteractivePrimary,
borderInteractiveSecondary = borderInteractiveSecondary,
borderSuccessSubtle = borderSuccessSubtle,
iconAccentTertiary = iconAccentTertiary,
iconCriticalPrimary = iconCriticalPrimary,
iconDisabled = iconDisabled,
iconInfoPrimary = iconInfoPrimary,
iconOnSolidPrimary = iconOnSolidPrimary,
iconPrimary = iconPrimary,
iconPrimaryAlpha = iconPrimaryAlpha,
iconQuaternary = iconQuaternary,
iconQuaternaryAlpha = iconQuaternaryAlpha,
iconSecondary = iconSecondary,
iconSecondaryAlpha = iconSecondaryAlpha,
iconSuccessPrimary = iconSuccessPrimary,
iconTertiary = iconTertiary,
iconTertiaryAlpha = iconTertiaryAlpha,
textActionAccent = textActionAccent,
textActionPrimary = textActionPrimary,
textCriticalPrimary = textCriticalPrimary,
textDisabled = textDisabled,
textInfoPrimary = textInfoPrimary,
textLinkExternal = textLinkExternal,
textOnSolidPrimary = textOnSolidPrimary,
textPlaceholder = textPlaceholder,
textPrimary = textPrimary,
textSecondary = textSecondary,
textSuccessPrimary = textSuccessPrimary,
isLight = isLight,
)
fun updateColorsFrom(other: SemanticColors) {
bgActionPrimaryDisabled = other.bgActionPrimaryDisabled
bgActionPrimaryHovered = other.bgActionPrimaryHovered
bgActionPrimaryPressed = other.bgActionPrimaryPressed
bgActionPrimaryRest = other.bgActionPrimaryRest
bgActionSecondaryHovered = other.bgActionSecondaryHovered
bgActionSecondaryPressed = other.bgActionSecondaryPressed
bgActionSecondaryRest = other.bgActionSecondaryRest
bgCanvasDefault = other.bgCanvasDefault
bgCanvasDisabled = other.bgCanvasDisabled
bgCriticalHovered = other.bgCriticalHovered
bgCriticalPrimary = other.bgCriticalPrimary
bgCriticalSubtle = other.bgCriticalSubtle
bgCriticalSubtleHovered = other.bgCriticalSubtleHovered
bgInfoSubtle = other.bgInfoSubtle
bgSubtlePrimary = other.bgSubtlePrimary
bgSubtleSecondary = other.bgSubtleSecondary
bgSuccessSubtle = other.bgSuccessSubtle
borderCriticalHovered = other.borderCriticalHovered
borderCriticalPrimary = other.borderCriticalPrimary
borderCriticalSubtle = other.borderCriticalSubtle
borderDisabled = other.borderDisabled
borderFocused = other.borderFocused
borderInfoSubtle = other.borderInfoSubtle
borderInteractiveHovered = other.borderInteractiveHovered
borderInteractivePrimary = other.borderInteractivePrimary
borderInteractiveSecondary = other.borderInteractiveSecondary
borderSuccessSubtle = other.borderSuccessSubtle
iconAccentTertiary = other.iconAccentTertiary
iconCriticalPrimary = other.iconCriticalPrimary
iconDisabled = other.iconDisabled
iconInfoPrimary = other.iconInfoPrimary
iconOnSolidPrimary = other.iconOnSolidPrimary
iconPrimary = other.iconPrimary
iconPrimaryAlpha = other.iconPrimaryAlpha
iconQuaternary = other.iconQuaternary
iconQuaternaryAlpha = other.iconQuaternaryAlpha
iconSecondary = other.iconSecondary
iconSecondaryAlpha = other.iconSecondaryAlpha
iconSuccessPrimary = other.iconSuccessPrimary
iconTertiary = other.iconTertiary
iconTertiaryAlpha = other.iconTertiaryAlpha
textActionAccent = other.textActionAccent
textActionPrimary = other.textActionPrimary
textCriticalPrimary = other.textCriticalPrimary
textDisabled = other.textDisabled
textInfoPrimary = other.textInfoPrimary
textLinkExternal = other.textLinkExternal
textOnSolidPrimary = other.textOnSolidPrimary
textPlaceholder = other.textPlaceholder
textPrimary = other.textPrimary
textSecondary = other.textSecondary
textSuccessPrimary = other.textSuccessPrimary
isLight = other.isLight
}
}

View file

@ -0,0 +1,144 @@
/*
* 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.
*/
// Do not edit directly
// Generated on Tue, 27 Jun 2023 13:31:52 GMT
@file:Suppress("all")
package io.element.android.libraries.theme.compound.generated
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.em
import androidx.compose.ui.unit.sp
object TypographyTokens {
val fontBodyLgMedium = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.W500,
lineHeight = 22.sp,
fontSize = 16.sp,
letterSpacing = 0.015629999999999998.em,
)
val fontBodyLgRegular = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.W400,
lineHeight = 22.sp,
fontSize = 16.sp,
letterSpacing = 0.015629999999999998.em,
)
val fontBodyMdMedium = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.W500,
lineHeight = 20.sp,
fontSize = 14.sp,
letterSpacing = 0.01786.em,
)
val fontBodyMdRegular = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.W400,
lineHeight = 20.sp,
fontSize = 14.sp,
letterSpacing = 0.01786.em,
)
val fontBodySmMedium = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.W500,
lineHeight = 17.sp,
fontSize = 12.sp,
letterSpacing = 0.03333.em,
)
val fontBodySmRegular = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.W400,
lineHeight = 17.sp,
fontSize = 12.sp,
letterSpacing = 0.03333.em,
)
val fontBodyXsMedium = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.W500,
lineHeight = 15.sp,
fontSize = 11.sp,
letterSpacing = 0.04545.em,
)
val fontBodyXsRegular = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.W400,
lineHeight = 15.sp,
fontSize = 11.sp,
letterSpacing = 0.04545.em,
)
val fontHeadingLgBold = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.W700,
lineHeight = 34.sp,
fontSize = 28.sp,
letterSpacing = 0.em,
)
val fontHeadingLgRegular = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.W400,
lineHeight = 34.sp,
fontSize = 28.sp,
letterSpacing = 0.em,
)
val fontHeadingMdBold = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.W700,
lineHeight = 27.sp,
fontSize = 22.sp,
letterSpacing = 0.em,
)
val fontHeadingMdRegular = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.W400,
lineHeight = 27.sp,
fontSize = 22.sp,
letterSpacing = 0.em,
)
val fontHeadingSmMedium = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.W500,
lineHeight = 25.sp,
fontSize = 20.sp,
letterSpacing = 0.em,
)
val fontHeadingSmRegular = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.W400,
lineHeight = 25.sp,
fontSize = 20.sp,
letterSpacing = 0.em,
)
val fontHeadingXlBold = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.W700,
lineHeight = 41.sp,
fontSize = 34.sp,
letterSpacing = 0.em,
)
val fontHeadingXlRegular = TextStyle(
fontFamily = FontFamily.Default,
fontWeight = FontWeight.W400,
lineHeight = 41.sp,
fontSize = 34.sp,
letterSpacing = 0.em,
)
}

View file

@ -0,0 +1,335 @@
/*
* 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.
*/
@file:Suppress("all")
package io.element.android.libraries.theme.compound.generated.internal
import androidx.compose.ui.graphics.Color
internal object DarkDesignTokens {
val colorAlphaPink1400 = Color(0xffffebef)
val colorAlphaPink1300 = Color(0xffffd1db)
val colorAlphaPink1200 = Color(0xffffadc0)
val colorAlphaPink1100 = Color(0xfffe86a4)
val colorAlphaPink1000 = Color(0xfaff6691)
val colorAlphaPink900 = Color(0xf5fe4382)
val colorAlphaPink800 = Color(0xccfe1b79)
val colorAlphaPink700 = Color(0x94fd1277)
val colorAlphaPink600 = Color(0x75fb0473)
val colorAlphaPink500 = Color(0xff6b0036)
val colorAlphaPink400 = Color(0xff570024)
val colorAlphaPink300 = Color(0xff470019)
val colorAlphaPink200 = Color(0xff3d0012)
val colorAlphaPink100 = Color(0xff38000f)
val colorAlphaFuchsia1400 = Color(0xfafdecfe)
val colorAlphaFuchsia1300 = Color(0xf2fde0ff)
val colorAlphaFuchsia1200 = Color(0xe8fac3fe)
val colorAlphaFuchsia1100 = Color(0xdbfaa4fe)
val colorAlphaFuchsia1000 = Color(0xd4f790fe)
val colorAlphaFuchsia900 = Color(0xccf172fd)
val colorAlphaFuchsia800 = Color(0xb5eb44fd)
val colorAlphaFuchsia700 = Color(0x8ad82ffe)
val colorAlphaFuchsia600 = Color(0x70d21fff)
val colorAlphaFuchsia500 = Color(0x61ca0aff)
val colorAlphaFuchsia400 = Color(0xff45005c)
val colorAlphaFuchsia300 = Color(0xff36004d)
val colorAlphaFuchsia200 = Color(0xff2d0042)
val colorAlphaFuchsia100 = Color(0xff28003d)
val colorAlphaPurple1400 = Color(0xffeeebff)
val colorAlphaPurple1300 = Color(0xffdfdbff)
val colorAlphaPurple1200 = Color(0xffc7bdff)
val colorAlphaPurple1100 = Color(0xffab9afe)
val colorAlphaPurple1000 = Color(0xfca28bfe)
val colorAlphaPurple900 = Color(0xfa9271fe)
val colorAlphaPurple800 = Color(0xeb7f4dff)
val colorAlphaPurple700 = Color(0xc2712bfd)
val colorAlphaPurple600 = Color(0xab690dfd)
val colorAlphaPurple500 = Color(0xff3d009e)
val colorAlphaPurple400 = Color(0xff2d0080)
val colorAlphaPurple300 = Color(0xff22006b)
val colorAlphaPurple200 = Color(0xff1d005c)
val colorAlphaPurple100 = Color(0xff1a0057)
val colorAlphaBlue1400 = Color(0xffe6effe)
val colorAlphaBlue1300 = Color(0xfccde1fe)
val colorAlphaBlue1200 = Color(0xf7a3c8ff)
val colorAlphaBlue1100 = Color(0xf57cb2fd)
val colorAlphaBlue1000 = Color(0xf062a0fe)
val colorAlphaBlue900 = Color(0xeb4491fd)
val colorAlphaBlue800 = Color(0xd61077fe)
val colorAlphaBlue700 = Color(0xa30665fe)
val colorAlphaBlue600 = Color(0x87015afe)
val colorAlphaBlue500 = Color(0xa1003cbd)
val colorAlphaBlue400 = Color(0xff001e70)
val colorAlphaBlue300 = Color(0xff001366)
val colorAlphaBlue200 = Color(0xff00095c)
val colorAlphaBlue100 = Color(0xff00055c)
val colorAlphaCyan1400 = Color(0xf5e1fbfe)
val colorAlphaCyan1300 = Color(0xebc9f7fd)
val colorAlphaCyan1200 = Color(0xd98af1ff)
val colorAlphaCyan1100 = Color(0xc926e7fd)
val colorAlphaCyan1000 = Color(0xe000bfe0)
val colorAlphaCyan900 = Color(0xff0091bd)
val colorAlphaCyan800 = Color(0xe0007ebd)
val colorAlphaCyan700 = Color(0xff00538a)
val colorAlphaCyan600 = Color(0xff003f75)
val colorAlphaCyan500 = Color(0xff003366)
val colorAlphaCyan400 = Color(0xff00265c)
val colorAlphaCyan300 = Color(0xff001b4d)
val colorAlphaCyan200 = Color(0xff001447)
val colorAlphaCyan100 = Color(0xff001142)
val colorAlphaGreen1400 = Color(0xf5e2fdf1)
val colorAlphaGreen1300 = Color(0xe8c4fde2)
val colorAlphaGreen1200 = Color(0xd486fdce)
val colorAlphaGreen1100 = Color(0xbd26fdbc)
val colorAlphaGreen1000 = Color(0xa61bfebd)
val colorAlphaGreen900 = Color(0x9412fdbe)
val colorAlphaGreen800 = Color(0xff007a62)
val colorAlphaGreen700 = Color(0xff005c45)
val colorAlphaGreen600 = Color(0xff004732)
val colorAlphaGreen500 = Color(0xff003d29)
val colorAlphaGreen400 = Color(0xff002e1b)
val colorAlphaGreen300 = Color(0xff002412)
val colorAlphaGreen200 = Color(0xff001f0e)
val colorAlphaGreen100 = Color(0xff001f0c)
val colorAlphaLime1400 = Color(0xf7e1fdd8)
val colorAlphaLime1300 = Color(0xebc3ffad)
val colorAlphaLime1200 = Color(0xd68dff5c)
val colorAlphaLime1100 = Color(0xbd71fd35)
val colorAlphaLime1000 = Color(0xa860fc2c)
val colorAlphaLime900 = Color(0x9454fd26)
val colorAlphaLime800 = Color(0x732dfd0d)
val colorAlphaLime700 = Color(0xff005c00)
val colorAlphaLime600 = Color(0xff004d00)
val colorAlphaLime500 = Color(0xff003d00)
val colorAlphaLime400 = Color(0xff002e00)
val colorAlphaLime300 = Color(0xff002900)
val colorAlphaLime200 = Color(0xff001f00)
val colorAlphaLime100 = Color(0xff001a00)
val colorAlphaYellow1400 = Color(0xffffedb3)
val colorAlphaYellow1300 = Color(0xfffeda58)
val colorAlphaYellow1200 = Color(0xf0fdc50d)
val colorAlphaYellow1100 = Color(0xffdba100)
val colorAlphaYellow1000 = Color(0xffcc8b00)
val colorAlphaYellow900 = Color(0xffbd7b00)
val colorAlphaYellow800 = Color(0xff9e5c00)
val colorAlphaYellow700 = Color(0xeb854200)
val colorAlphaYellow600 = Color(0xde753300)
val colorAlphaYellow500 = Color(0xff5c2300)
val colorAlphaYellow400 = Color(0xff4d1400)
val colorAlphaYellow300 = Color(0xff420900)
val colorAlphaYellow200 = Color(0xff380300)
val colorAlphaYellow100 = Color(0xff380000)
val colorAlphaOrange1400 = Color(0xffffeadb)
val colorAlphaOrange1300 = Color(0xffffd4b8)
val colorAlphaOrange1200 = Color(0xfcfdb781)
val colorAlphaOrange1100 = Color(0xf7fd953f)
val colorAlphaOrange1000 = Color(0xebfe8310)
val colorAlphaOrange900 = Color(0xd9fe740b)
val colorAlphaOrange800 = Color(0xb5ff5900)
val colorAlphaOrange700 = Color(0xbdc72800)
val colorAlphaOrange600 = Color(0xff850400)
val colorAlphaOrange500 = Color(0xff700000)
val colorAlphaOrange400 = Color(0xff570000)
val colorAlphaOrange300 = Color(0xff470000)
val colorAlphaOrange200 = Color(0xff3d0000)
val colorAlphaOrange100 = Color(0xff380000)
val colorAlphaRed1400 = Color(0xffffe8e5)
val colorAlphaRed1300 = Color(0xffffd3cc)
val colorAlphaRed1200 = Color(0xffffaea3)
val colorAlphaRed1100 = Color(0xffff857a)
val colorAlphaRed1000 = Color(0xffff645c)
val colorAlphaRed900 = Color(0xfffd3d3a)
val colorAlphaRed800 = Color(0xcffe2530)
val colorAlphaRed700 = Color(0x99fe0b24)
val colorAlphaRed600 = Color(0xff850009)
val colorAlphaRed500 = Color(0xff700000)
val colorAlphaRed400 = Color(0xff5c0000)
val colorAlphaRed300 = Color(0xff470000)
val colorAlphaRed200 = Color(0xff3d0000)
val colorAlphaRed100 = Color(0xff380000)
val colorAlphaGray1400 = Color(0xf2f6f9fe)
val colorAlphaGray1300 = Color(0xe3f2f7fd)
val colorAlphaGray1200 = Color(0xc9edf4fc)
val colorAlphaGray1100 = Color(0xade7f0fe)
val colorAlphaGray1000 = Color(0x9ce1eefe)
val colorAlphaGray900 = Color(0x8ae1effe)
val colorAlphaGray800 = Color(0x69e0edff)
val colorAlphaGray700 = Color(0x45e7f1fd)
val colorAlphaGray600 = Color(0x33eceff8)
val colorAlphaGray500 = Color(0x26f4f7fa)
val colorAlphaGray400 = Color(0x1aede7f4)
val colorAlphaGray300 = Color(0x0fe9dbf0)
val colorAlphaGray200 = Color(0x0ad9c3df)
val colorAlphaGray100 = Color(0x05d8dbdf)
val colorPink1400 = Color(0xffffe8ed)
val colorPink1300 = Color(0xffffd2dc)
val colorPink1200 = Color(0xffffabbe)
val colorPink1100 = Color(0xfffe84a2)
val colorPink1000 = Color(0xfffa658f)
val colorPink900 = Color(0xfff4427d)
val colorPink800 = Color(0xffce1865)
val colorPink700 = Color(0xff99114f)
val colorPink600 = Color(0xff7c0c41)
val colorPink500 = Color(0xff6d0036)
val colorPink400 = Color(0xff550024)
val colorPink300 = Color(0xff450018)
val colorPink200 = Color(0xff3c0012)
val colorPink100 = Color(0xff37000f)
val colorFuchsia1400 = Color(0xfff8e9f9)
val colorFuchsia1300 = Color(0xfff1d4f3)
val colorFuchsia1200 = Color(0xffe5b1e9)
val colorFuchsia1100 = Color(0xffd991de)
val colorFuchsia1000 = Color(0xffcf78d7)
val colorFuchsia900 = Color(0xffc560cf)
val colorFuchsia800 = Color(0xffaa36ba)
val colorFuchsia700 = Color(0xff7d2394)
val colorFuchsia600 = Color(0xff65177d)
val colorFuchsia500 = Color(0xff560f6f)
val colorFuchsia400 = Color(0xff46005e)
val colorFuchsia300 = Color(0xff37004e)
val colorFuchsia200 = Color(0xff2e0044)
val colorFuchsia100 = Color(0xff28003d)
val colorPurple1400 = Color(0xffeeebff)
val colorPurple1300 = Color(0xffdedaff)
val colorPurple1200 = Color(0xffc4baff)
val colorPurple1100 = Color(0xffad9cfe)
val colorPurple1000 = Color(0xff9e87fc)
val colorPurple900 = Color(0xff9171f9)
val colorPurple800 = Color(0xff7849ec)
val colorPurple700 = Color(0xff5a27c6)
val colorPurple600 = Color(0xff4a0db1)
val colorPurple500 = Color(0xff3d009e)
val colorPurple400 = Color(0xff2c0080)
val colorPurple300 = Color(0xff22006a)
val colorPurple200 = Color(0xff1c005a)
val colorPurple100 = Color(0xff1a0055)
val colorBlue1400 = Color(0xffe4eefe)
val colorBlue1300 = Color(0xffcbdffc)
val colorBlue1200 = Color(0xffa1c4f8)
val colorBlue1100 = Color(0xff7aacf4)
val colorBlue1000 = Color(0xff5e99f0)
val colorBlue900 = Color(0xff4187eb)
val colorBlue800 = Color(0xff0e67d9)
val colorBlue700 = Color(0xff0b49ab)
val colorBlue600 = Color(0xff083891)
val colorBlue500 = Color(0xff062d80)
val colorBlue400 = Color(0xff001e6f)
val colorBlue300 = Color(0xff001264)
val colorBlue200 = Color(0xff00095d)
val colorBlue100 = Color(0xff00055a)
val colorCyan1400 = Color(0xffdbf2f5)
val colorCyan1300 = Color(0xffb8e5eb)
val colorCyan1200 = Color(0xff78d0dc)
val colorCyan1100 = Color(0xff21bacd)
val colorCyan1000 = Color(0xff02a7c6)
val colorCyan900 = Color(0xff0093be)
val colorCyan800 = Color(0xff0271aa)
val colorCyan700 = Color(0xff005188)
val colorCyan600 = Color(0xff003f75)
val colorCyan500 = Color(0xff003468)
val colorCyan400 = Color(0xff002559)
val colorCyan300 = Color(0xff001b4e)
val colorCyan200 = Color(0xff001448)
val colorCyan100 = Color(0xff001144)
val colorGreen1400 = Color(0xffd9f4e7)
val colorGreen1300 = Color(0xffb5e8d1)
val colorGreen1200 = Color(0xff72d5ae)
val colorGreen1100 = Color(0xff1fc090)
val colorGreen1000 = Color(0xff17ac84)
val colorGreen900 = Color(0xff129a78)
val colorGreen800 = Color(0xff007a62)
val colorGreen700 = Color(0xff005a43)
val colorGreen600 = Color(0xff004832)
val colorGreen500 = Color(0xff003d29)
val colorGreen400 = Color(0xff002e1b)
val colorGreen300 = Color(0xff002513)
val colorGreen200 = Color(0xff001f0e)
val colorGreen100 = Color(0xff001c0b)
val colorLime1400 = Color(0xffdaf6d0)
val colorLime1300 = Color(0xffb6eca3)
val colorLime1200 = Color(0xff77d94f)
val colorLime1100 = Color(0xff56c02c)
val colorLime1000 = Color(0xff47ad26)
val colorLime900 = Color(0xff389b20)
val colorLime800 = Color(0xff1d7c13)
val colorLime700 = Color(0xff005c00)
val colorLime600 = Color(0xff004a00)
val colorLime500 = Color(0xff003e00)
val colorLime400 = Color(0xff003000)
val colorLime300 = Color(0xff002600)
val colorLime200 = Color(0xff002000)
val colorLime100 = Color(0xff001b00)
val colorYellow1400 = Color(0xffffedb1)
val colorYellow1300 = Color(0xfffedb58)
val colorYellow1200 = Color(0xffefbb0b)
val colorYellow1100 = Color(0xffdb9f00)
val colorYellow1000 = Color(0xffcc8c00)
val colorYellow900 = Color(0xffbc7a00)
val colorYellow800 = Color(0xff9d5b00)
val colorYellow700 = Color(0xff7c3e02)
val colorYellow600 = Color(0xff682e03)
val colorYellow500 = Color(0xff5c2400)
val colorYellow400 = Color(0xff4c1400)
val colorYellow300 = Color(0xff410900)
val colorYellow200 = Color(0xff3a0300)
val colorYellow100 = Color(0xff360000)
val colorOrange1400 = Color(0xffffeadb)
val colorOrange1300 = Color(0xffffd5b9)
val colorOrange1200 = Color(0xfffbb37e)
val colorOrange1100 = Color(0xfff6913d)
val colorOrange1000 = Color(0xffeb7a12)
val colorOrange900 = Color(0xffda670d)
val colorOrange800 = Color(0xffb94607)
val colorOrange700 = Color(0xff972206)
val colorOrange600 = Color(0xff830500)
val colorOrange500 = Color(0xff710000)
val colorOrange400 = Color(0xff580000)
val colorOrange300 = Color(0xff470000)
val colorOrange200 = Color(0xff3c0000)
val colorOrange100 = Color(0xff380000)
val colorRed1400 = Color(0xffffe9e6)
val colorRed1300 = Color(0xffffd4cd)
val colorRed1200 = Color(0xffffaea4)
val colorRed1100 = Color(0xffff877c)
val colorRed1000 = Color(0xffff665d)
val colorRed900 = Color(0xfffd3e3c)
val colorRed800 = Color(0xffd1212a)
val colorRed700 = Color(0xff9f0d1e)
val colorRed600 = Color(0xff830009)
val colorRed500 = Color(0xff710000)
val colorRed400 = Color(0xff590000)
val colorRed300 = Color(0xff470000)
val colorRed200 = Color(0xff3e0000)
val colorRed100 = Color(0xff370000)
val colorGray1400 = Color(0xffebeef2)
val colorGray1300 = Color(0xffd9dee4)
val colorGray1200 = Color(0xffbdc3cc)
val colorGray1100 = Color(0xffa3aab4)
val colorGray1000 = Color(0xff9199a4)
val colorGray900 = Color(0xff808994)
val colorGray800 = Color(0xff656c76)
val colorGray700 = Color(0xff4a4f55)
val colorGray600 = Color(0xff3c3f44)
val colorGray500 = Color(0xff323539)
val colorGray400 = Color(0xff26282d)
val colorGray300 = Color(0xff1d1f24)
val colorGray200 = Color(0xff181a1f)
val colorGray100 = Color(0xff14171b)
val colorThemeBg = Color(0xff101317)
val colorBgSubtleSecondaryLevel0 = colorThemeBg
val colorBgCanvasDefaultLevel1 = colorGray300
}

View file

@ -0,0 +1,335 @@
/*
* 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.
*/
@file:Suppress("all")
package io.element.android.libraries.theme.compound.generated.internal;
import androidx.compose.ui.graphics.Color
internal object LightDesignTokens {
val colorAlphaPink1400 = Color(0xff420017)
val colorAlphaPink1300 = Color(0xff61002c)
val colorAlphaPink1200 = Color(0xfa79013d)
val colorAlphaPink1100 = Color(0xf79e004c)
val colorAlphaPink1000 = Color(0xf7b60256)
val colorAlphaPink900 = Color(0xf5cf025e)
val colorAlphaPink800 = Color(0xbff50052)
val colorAlphaPink700 = Color(0x78ff0040)
val colorAlphaPink600 = Color(0x54ff053f)
val colorAlphaPink500 = Color(0x3dff0037)
val colorAlphaPink400 = Color(0x21ff0037)
val colorAlphaPink300 = Color(0x14ff1447)
val colorAlphaPink200 = Color(0x0aff0537)
val colorAlphaPink100 = Color(0x05ff0537)
val colorAlphaFuchsia1400 = Color(0xff34004d)
val colorAlphaFuchsia1300 = Color(0xff4d0066)
val colorAlphaFuchsia1200 = Color(0xed5d0279)
val colorAlphaFuchsia1100 = Color(0xe073038c)
val colorAlphaFuchsia1000 = Color(0xd6820198)
val colorAlphaFuchsia900 = Color(0xcc9900ad)
val colorAlphaFuchsia800 = Color(0xa3ab03ba)
val colorAlphaFuchsia700 = Color(0x6eaa04b9)
val colorAlphaFuchsia600 = Color(0x4fb207bb)
val colorAlphaFuchsia500 = Color(0x3bb407c0)
val colorAlphaFuchsia400 = Color(0x21bd09c3)
val colorAlphaFuchsia300 = Color(0x12b60cc6)
val colorAlphaFuchsia200 = Color(0x0ab505cc)
val colorAlphaFuchsia100 = Color(0x05cc05cc)
val colorAlphaPurple1400 = Color(0xff200066)
val colorAlphaPurple1300 = Color(0xff34008f)
val colorAlphaPurple1200 = Color(0xfc4a02b6)
val colorAlphaPurple1100 = Color(0xdb4303c4)
val colorAlphaPurple1000 = Color(0xc94502d4)
val colorAlphaPurple900 = Color(0xba4902ed)
val colorAlphaPurple800 = Color(0x8f3b01f9)
val colorAlphaPurple700 = Color(0x613305ff)
val colorAlphaPurple600 = Color(0x452b05ff)
val colorAlphaPurple500 = Color(0x332605ff)
val colorAlphaPurple400 = Color(0x1f2f0fff)
val colorAlphaPurple300 = Color(0x12381aff)
val colorAlphaPurple200 = Color(0x0a5338ff)
val colorAlphaPurple100 = Color(0x053838ff)
val colorAlphaBlue1400 = Color(0xff000e66)
val colorAlphaBlue1300 = Color(0xff012579)
val colorAlphaBlue1200 = Color(0xfc013693)
val colorAlphaBlue1100 = Color(0xfa0148b2)
val colorAlphaBlue1000 = Color(0xfc0256c5)
val colorAlphaBlue900 = Color(0xfc0165df)
val colorAlphaBlue800 = Color(0xbf0062eb)
val colorAlphaBlue700 = Color(0x820264ed)
val colorAlphaBlue600 = Color(0x5e0663ef)
val colorAlphaBlue500 = Color(0x47096cf6)
val colorAlphaBlue400 = Color(0x290b6af9)
val colorAlphaBlue300 = Color(0x170a70ff)
val colorAlphaBlue200 = Color(0x0d2474ff)
val colorAlphaBlue100 = Color(0x08389cff)
val colorAlphaCyan1400 = Color(0xff001a52)
val colorAlphaCyan1300 = Color(0xff002c61)
val colorAlphaCyan1200 = Color(0xff003f75)
val colorAlphaCyan1100 = Color(0xff00568f)
val colorAlphaCyan1000 = Color(0xff00649e)
val colorAlphaCyan900 = Color(0xff0074ad)
val colorAlphaCyan800 = Color(0xff0095c2)
val colorAlphaCyan700 = Color(0xeb01b7cb)
val colorAlphaCyan600 = Color(0x8a01aac1)
val colorAlphaCyan500 = Color(0x6605abbd)
val colorAlphaCyan400 = Color(0x3800aabd)
val colorAlphaCyan300 = Color(0x1c00a8c2)
val colorAlphaCyan200 = Color(0x0f16abbb)
val colorAlphaCyan100 = Color(0x0816bbbb)
val colorAlphaGreen1400 = Color(0xff002411)
val colorAlphaGreen1300 = Color(0xff00331f)
val colorAlphaGreen1200 = Color(0xff004732)
val colorAlphaGreen1100 = Color(0xff005c45)
val colorAlphaGreen1000 = Color(0xff006b52)
val colorAlphaGreen900 = Color(0xff007a62)
val colorAlphaGreen800 = Color(0xff009975)
val colorAlphaGreen700 = Color(0xf501c18a)
val colorAlphaGreen600 = Color(0x8f01b76e)
val colorAlphaGreen500 = Color(0x6904b96a)
val colorAlphaGreen400 = Color(0x3b07b661)
val colorAlphaGreen300 = Color(0x1c00b85c)
val colorAlphaGreen200 = Color(0x0f16bb69)
val colorAlphaGreen100 = Color(0x0816bb79)
val colorAlphaLime1400 = Color(0xff002400)
val colorAlphaLime1300 = Color(0xff003800)
val colorAlphaLime1200 = Color(0xff004d00)
val colorAlphaLime1100 = Color(0xff006100)
val colorAlphaLime1000 = Color(0xff007000)
val colorAlphaLime900 = Color(0xf5107902)
val colorAlphaLime800 = Color(0xe8209301)
val colorAlphaLime700 = Color(0xdb39bd00)
val colorAlphaLime600 = Color(0xb540ce03)
val colorAlphaLime500 = Color(0x8237ca02)
val colorAlphaLime400 = Color(0x473ace09)
val colorAlphaLime300 = Color(0x262ecf02)
val colorAlphaLime200 = Color(0x1238d40c)
val colorAlphaLime100 = Color(0x0a4fcd1d)
val colorAlphaYellow1400 = Color(0xff420700)
val colorAlphaYellow1300 = Color(0xff571b00)
val colorAlphaYellow1200 = Color(0xff6b2e00)
val colorAlphaYellow1100 = Color(0xff804000)
val colorAlphaYellow1000 = Color(0xff8f4c00)
val colorAlphaYellow900 = Color(0xff9e5a00)
val colorAlphaYellow800 = Color(0xffbd7b00)
val colorAlphaYellow700 = Color(0xffe0a500)
val colorAlphaYellow600 = Color(0xfff0bc00)
val colorAlphaYellow500 = Color(0xfffacc00)
val colorAlphaYellow400 = Color(0x7dffc905)
val colorAlphaYellow300 = Color(0x40ffc905)
val colorAlphaYellow200 = Color(0x21ffc70f)
val colorAlphaYellow100 = Color(0x0fffcd05)
val colorAlphaOrange1400 = Color(0xff470000)
val colorAlphaOrange1300 = Color(0xff610000)
val colorAlphaOrange1200 = Color(0xff850000)
val colorAlphaOrange1100 = Color(0xff992100)
val colorAlphaOrange1000 = Color(0xffad3400)
val colorAlphaOrange900 = Color(0xffbd4500)
val colorAlphaOrange800 = Color(0xffdb6600)
val colorAlphaOrange700 = Color(0xbff56e00)
val colorAlphaOrange600 = Color(0x85fc6f03)
val colorAlphaOrange500 = Color(0x5eff6a00)
val colorAlphaOrange400 = Color(0x38ff6d05)
val colorAlphaOrange300 = Color(0x1cff6c0a)
val colorAlphaOrange200 = Color(0x12ff7d1a)
val colorAlphaOrange100 = Color(0x0aff8138)
val colorAlphaRed1400 = Color(0xff470000)
val colorAlphaRed1300 = Color(0xff610000)
val colorAlphaRed1200 = Color(0xff850007)
val colorAlphaRed1100 = Color(0xfca2011c)
val colorAlphaRed1000 = Color(0xf2bb0217)
val colorAlphaRed900 = Color(0xe8cf0213)
val colorAlphaRed800 = Color(0xc4ff0505)
val colorAlphaRed700 = Color(0x80ff1a05)
val colorAlphaRed600 = Color(0x5cff2205)
val colorAlphaRed500 = Color(0x45ff2605)
val colorAlphaRed400 = Color(0x26ff2b0a)
val colorAlphaRed300 = Color(0x14ff3814)
val colorAlphaRed200 = Color(0x0aff391f)
val colorAlphaRed100 = Color(0x08ff5938)
val colorAlphaGray1400 = Color(0xe6020408)
val colorAlphaGray1300 = Color(0xd603050c)
val colorAlphaGray1200 = Color(0xc402070d)
val colorAlphaGray1100 = Color(0xb5030b16)
val colorAlphaGray1000 = Color(0xa8030c1b)
val colorAlphaGray900 = Color(0x9c031021)
val colorAlphaGray800 = Color(0x8003152b)
val colorAlphaGray700 = Color(0x59011532)
val colorAlphaGray600 = Color(0x42011d3c)
val colorAlphaGray500 = Color(0x33052448)
val colorAlphaGray400 = Color(0x1f052e61)
val colorAlphaGray300 = Color(0x0f052657)
val colorAlphaGray200 = Color(0x0a366881)
val colorAlphaGray100 = Color(0x0536699b)
val colorPink1400 = Color(0xff430017)
val colorPink1300 = Color(0xff5f002b)
val colorPink1200 = Color(0xff7e0642)
val colorPink1100 = Color(0xff9f0850)
val colorPink1000 = Color(0xffb80a5b)
val colorPink900 = Color(0xffd20c65)
val colorPink800 = Color(0xfff7407d)
val colorPink700 = Color(0xffff88a6)
val colorPink600 = Color(0xffffadc0)
val colorPink500 = Color(0xffffc2cf)
val colorPink400 = Color(0xffffdee5)
val colorPink300 = Color(0xffffecf0)
val colorPink200 = Color(0xfffff5f7)
val colorPink100 = Color(0xfffffafb)
val colorFuchsia1400 = Color(0xff34004c)
val colorFuchsia1300 = Color(0xff4e0068)
val colorFuchsia1200 = Color(0xff671481)
val colorFuchsia1100 = Color(0xff822198)
val colorFuchsia1000 = Color(0xff972aaa)
val colorFuchsia900 = Color(0xffad33bd)
val colorFuchsia800 = Color(0xffc85ed1)
val colorFuchsia700 = Color(0xffdb93e1)
val colorFuchsia600 = Color(0xffe7b2ea)
val colorFuchsia500 = Color(0xffedc6f0)
val colorFuchsia400 = Color(0xfff6dff7)
val colorFuchsia300 = Color(0xfffaeefb)
val colorFuchsia200 = Color(0xfffcf5fd)
val colorFuchsia100 = Color(0xfffefafe)
val colorPurple1400 = Color(0xff200066)
val colorPurple1300 = Color(0xff33008d)
val colorPurple1200 = Color(0xff4c05b5)
val colorPurple1100 = Color(0xff5d26cd)
val colorPurple1000 = Color(0xff6b37de)
val colorPurple900 = Color(0xff7a47f1)
val colorPurple800 = Color(0xff9271fd)
val colorPurple700 = Color(0xffb1a0ff)
val colorPurple600 = Color(0xffc5bbff)
val colorPurple500 = Color(0xffd4cdff)
val colorPurple400 = Color(0xffe6e2ff)
val colorPurple300 = Color(0xfff1efff)
val colorPurple200 = Color(0xfff8f7ff)
val colorPurple100 = Color(0xfffbfbff)
val colorBlue1400 = Color(0xff000e65)
val colorBlue1300 = Color(0xff012478)
val colorBlue1200 = Color(0xff043894)
val colorBlue1100 = Color(0xff064ab1)
val colorBlue1000 = Color(0xff0558c7)
val colorBlue900 = Color(0xff0467dd)
val colorBlue800 = Color(0xff4088ee)
val colorBlue700 = Color(0xff7eaff6)
val colorBlue600 = Color(0xffa3c6fa)
val colorBlue500 = Color(0xffbad5fc)
val colorBlue400 = Color(0xffd8e7fe)
val colorBlue300 = Color(0xffe9f2ff)
val colorBlue200 = Color(0xfff4f8ff)
val colorBlue100 = Color(0xfff9fcff)
val colorCyan1400 = Color(0xff00194f)
val colorCyan1300 = Color(0xff002b61)
val colorCyan1200 = Color(0xff004077)
val colorCyan1100 = Color(0xff00548c)
val colorCyan1000 = Color(0xff00629c)
val colorCyan900 = Color(0xff0072ac)
val colorCyan800 = Color(0xff0094c0)
val colorCyan700 = Color(0xff15becf)
val colorCyan600 = Color(0xff76d1dd)
val colorCyan500 = Color(0xff9bdde5)
val colorCyan400 = Color(0xffc7ecf0)
val colorCyan300 = Color(0xffe3f5f8)
val colorCyan200 = Color(0xfff1fafb)
val colorCyan100 = Color(0xfff8fdfd)
val colorGreen1400 = Color(0xff002311)
val colorGreen1300 = Color(0xff003420)
val colorGreen1200 = Color(0xff004933)
val colorGreen1100 = Color(0xff005c45)
val colorGreen1000 = Color(0xff006b52)
val colorGreen900 = Color(0xff007a61)
val colorGreen800 = Color(0xff009b78)
val colorGreen700 = Color(0xff0bc491)
val colorGreen600 = Color(0xff71d7ae)
val colorGreen500 = Color(0xff98e1c1)
val colorGreen400 = Color(0xffc6eedb)
val colorGreen300 = Color(0xffe3f7ed)
val colorGreen200 = Color(0xfff1fbf6)
val colorGreen100 = Color(0xfff8fdfb)
val colorLime1400 = Color(0xff002400)
val colorLime1300 = Color(0xff003600)
val colorLime1200 = Color(0xff004b00)
val colorLime1100 = Color(0xff005f00)
val colorLime1000 = Color(0xff006e00)
val colorLime900 = Color(0xff197d0c)
val colorLime800 = Color(0xff359d18)
val colorLime700 = Color(0xff54c424)
val colorLime600 = Color(0xff76db4c)
val colorLime500 = Color(0xff99e57e)
val colorLime400 = Color(0xffc8f1ba)
val colorLime300 = Color(0xffe0f8d9)
val colorLime200 = Color(0xfff1fcee)
val colorLime100 = Color(0xfff8fdf6)
val colorYellow1400 = Color(0xff410600)
val colorYellow1300 = Color(0xff541a00)
val colorYellow1200 = Color(0xff692e00)
val colorYellow1100 = Color(0xff803f00)
val colorYellow1000 = Color(0xff8f4d00)
val colorYellow900 = Color(0xff9f5b00)
val colorYellow800 = Color(0xffbe7a00)
val colorYellow700 = Color(0xffdea200)
val colorYellow600 = Color(0xfff1bd00)
val colorYellow500 = Color(0xfffbce00)
val colorYellow400 = Color(0xffffe484)
val colorYellow300 = Color(0xfffff2c1)
val colorYellow200 = Color(0xfffff8e0)
val colorYellow100 = Color(0xfffffcf0)
val colorOrange1400 = Color(0xff450000)
val colorOrange1300 = Color(0xff620000)
val colorOrange1200 = Color(0xff850000)
val colorOrange1100 = Color(0xff9b2200)
val colorOrange1000 = Color(0xffac3300)
val colorOrange900 = Color(0xffbc4500)
val colorOrange800 = Color(0xffdc6700)
val colorOrange700 = Color(0xfff89440)
val colorOrange600 = Color(0xfffdb37c)
val colorOrange500 = Color(0xffffc8a1)
val colorOrange400 = Color(0xffffdfc8)
val colorOrange300 = Color(0xffffefe4)
val colorOrange200 = Color(0xfffff6ef)
val colorOrange100 = Color(0xfffffaf7)
val colorRed1400 = Color(0xff450000)
val colorRed1300 = Color(0xff620000)
val colorRed1200 = Color(0xff850006)
val colorRed1100 = Color(0xffa4041d)
val colorRed1000 = Color(0xffbc0f22)
val colorRed900 = Color(0xffd51928)
val colorRed800 = Color(0xffff3d3d)
val colorRed700 = Color(0xffff8c81)
val colorRed600 = Color(0xffffafa5)
val colorRed500 = Color(0xffffc5bc)
val colorRed400 = Color(0xffffdfda)
val colorRed300 = Color(0xffffefec)
val colorRed200 = Color(0xfffff7f6)
val colorRed100 = Color(0xfffffaf9)
val colorGray1400 = Color(0xff1b1d22)
val colorGray1300 = Color(0xff2b2d32)
val colorGray1200 = Color(0xff3c4045)
val colorGray1100 = Color(0xff4c5158)
val colorGray1000 = Color(0xff595e67)
val colorGray900 = Color(0xff656d77)
val colorGray800 = Color(0xff818a95)
val colorGray700 = Color(0xffa6adb7)
val colorGray600 = Color(0xffbdc4cc)
val colorGray500 = Color(0xffcdd3da)
val colorGray400 = Color(0xffe1e6ec)
val colorGray300 = Color(0xfff0f2f5)
val colorGray200 = Color(0xfff7f9fa)
val colorGray100 = Color(0xfffbfcfd)
val colorThemeBg = Color(0xffffffff)
val colorBgSubtleSecondaryLevel0 = colorGray300
val colorBgCanvasDefaultLevel1 = colorThemeBg
}

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.element.android.libraries.designsystem.theme.previews
package io.element.android.libraries.theme.previews
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
@ -28,7 +28,7 @@ import androidx.compose.ui.unit.dp
import kotlinx.collections.immutable.ImmutableMap
@Composable
internal fun ColorListPreview(
fun ColorListPreview(
backgroundColor: Color,
foregroundColor: Color,
colors: ImmutableMap<String, Color>,

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.element.android.libraries.designsystem.theme.previews
package io.element.android.libraries.theme.previews
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
@ -23,17 +23,17 @@ import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.utils.toHrf
import io.element.android.libraries.theme.utils.toHrf
@Composable
internal fun ColorPreview(
fun ColorPreview(
backgroundColor: Color,
foregroundColor: Color,
name: String, color: Color,

View file

@ -14,7 +14,7 @@
* limitations under the License.
*/
package io.element.android.libraries.designsystem.theme.previews
package io.element.android.libraries.theme.previews
import androidx.compose.material3.ColorScheme
import androidx.compose.runtime.Composable

View file

@ -0,0 +1,23 @@
/*
* Copyright (c) 2022 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.theme.showkase
import com.airbnb.android.showkase.annotation.ShowkaseRoot
import com.airbnb.android.showkase.annotation.ShowkaseRootModule
@ShowkaseRoot
class ThemeShowkaseRootModule : ShowkaseRootModule

View file

@ -14,13 +14,13 @@
* limitations under the License.
*/
package io.element.android.libraries.designsystem.utils
package io.element.android.libraries.theme.utils
import androidx.compose.ui.graphics.Color
/**
* Convert color to Human Readable Format.
*/
internal fun Color.toHrf(): String {
fun Color.toHrf(): String {
return "0x" + value.toString(16).take(8).uppercase()
}

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M2.98 16.3l-1.45 4.95a0.94 0.94 0 0 0 0.25 1 0.94 0.94 0 0 0 1 0.25l4.95-1.45a10.23 10.23 0 0 0 2.1 0.71c0.71 0.16 1.45 0.24 2.2 0.24a9.74 9.74 0 0 0 3.9-0.79 10.1 10.1 0 0 0 3.17-2.14c0.9-0.9 1.61-1.95 2.14-3.17a9.74 9.74 0 0 0 0.79-3.9 9.74 9.74 0 0 0-0.8-3.9 10.1 10.1 0 0 0-2.13-3.17c-0.9-0.9-1.96-1.62-3.17-2.14A9.74 9.74 0 0 0 12.03 2a9.74 9.74 0 0 0-3.9 0.79 10.1 10.1 0 0 0-3.18 2.13c-0.9 0.9-1.61 1.96-2.14 3.18A9.74 9.74 0 0 0 2.03 12a10.18 10.18 0 0 0 0.95 4.3Z"/>
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M9.55 17.57c-0.13 0-0.26-0.02-0.38-0.06a0.88 0.88 0 0 1-0.32-0.21L4.55 13c-0.18-0.18-0.27-0.42-0.26-0.71 0-0.3 0.1-0.53 0.28-0.71a0.95 0.95 0 0 1 0.7-0.28 0.95 0.95 0 0 1 0.7 0.28l3.58 3.57 8.47-8.47c0.19-0.19 0.42-0.28 0.72-0.28 0.29 0 0.53 0.1 0.71 0.28 0.18 0.18 0.28 0.42 0.28 0.7 0 0.3-0.1 0.54-0.28 0.72l-9.2 9.2c-0.1 0.1-0.2 0.17-0.33 0.21a1.1 1.1 0 0 1-0.37 0.06Z"/>
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M10.6 13.8l-2.15-2.15a0.95 0.95 0 0 0-0.7-0.28 0.95 0.95 0 0 0-0.7 0.28 0.95 0.95 0 0 0-0.28 0.7 0.95 0.95 0 0 0 0.28 0.7L9.9 15.9c0.2 0.2 0.43 0.3 0.7 0.3 0.27 0 0.5-0.1 0.7-0.3l5.65-5.65a0.95 0.95 0 0 0 0.28-0.7 0.95 0.95 0 0 0-0.28-0.7 0.95 0.95 0 0 0-0.7-0.28 0.95 0.95 0 0 0-0.7 0.28L10.6 13.8ZM12 22a9.74 9.74 0 0 1-3.9-0.79 10.1 10.1 0 0 1-3.17-2.14c-0.9-0.9-1.62-1.95-2.14-3.17A9.74 9.74 0 0 1 2 12a9.74 9.74 0 0 1 0.79-3.9 10.1 10.1 0 0 1 2.14-3.17c0.9-0.9 1.95-1.62 3.17-2.14A9.74 9.74 0 0 1 12 2a9.74 9.74 0 0 1 3.9 0.79 10.1 10.1 0 0 1 3.17 2.14c0.9 0.9 1.62 1.95 2.14 3.17A9.74 9.74 0 0 1 22 12a9.74 9.74 0 0 1-0.79 3.9 10.1 10.1 0 0 1-2.14 3.17c-0.9 0.9-1.95 1.62-3.17 2.14A9.74 9.74 0 0 1 12 22Z"/>
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M12 14.95c-0.13 0-0.26-0.02-0.38-0.06a0.88 0.88 0 0 1-0.32-0.22l-4.63-4.62a0.9 0.9 0 0 1-0.26-0.69 0.98 0.98 0 0 1 0.29-0.68 0.95 0.95 0 0 1 0.7-0.28 0.95 0.95 0 0 1 0.7 0.28l3.9 3.9 3.92-3.93a0.9 0.9 0 0 1 0.7-0.26 0.98 0.98 0 0 1 0.68 0.29 0.95 0.95 0 0 1 0.28 0.7 0.95 0.95 0 0 1-0.28 0.7l-4.6 4.6c-0.1 0.1-0.2 0.17-0.32 0.2A1.1 1.1 0 0 1 12 14.96Z"/>
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M12 13.4l-4.9 4.9a0.95 0.95 0 0 1-0.7 0.28 0.95 0.95 0 0 1-0.7-0.28 0.95 0.95 0 0 1-0.28-0.7 0.95 0.95 0 0 1 0.28-0.7l4.9-4.9-4.9-4.9a0.95 0.95 0 0 1-0.28-0.7 0.95 0.95 0 0 1 0.28-0.7 0.95 0.95 0 0 1 0.7-0.27 0.95 0.95 0 0 1 0.7 0.27l4.9 4.9 4.9-4.9a0.95 0.95 0 0 1 0.7-0.27 0.95 0.95 0 0 1 0.7 0.27 0.95 0.95 0 0 1 0.27 0.7 0.95 0.95 0 0 1-0.27 0.7L13.4 12l4.9 4.9a0.95 0.95 0 0 1 0.28 0.7 0.95 0.95 0 0 1-0.28 0.7 0.95 0.95 0 0 1-0.7 0.27 0.95 0.95 0 0 1-0.7-0.27L12 13.4Z"/>
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M4 18c-0.55 0-1.02-0.2-1.41-0.59A1.93 1.93 0 0 1 2 16V5c0-0.55 0.2-1.02 0.59-1.41A1.93 1.93 0 0 1 4 3h16c0.55 0 1.02 0.2 1.41 0.59C21.81 3.98 22 4.45 22 5v11c0 0.55-0.2 1.02-0.59 1.41A1.93 1.93 0 0 1 20 18H4Zm0-2h16V5H4v11Zm-2 5a0.97 0.97 0 0 1-0.71-0.29A0.97 0.97 0 0 1 1 20c0-0.28 0.1-0.52 0.29-0.71A0.97 0.97 0 0 1 2 19h20c0.28 0 0.52 0.1 0.71 0.29C22.91 19.48 23 19.72 23 20s-0.1 0.52-0.29 0.71A0.97 0.97 0 0 1 22 21H2Z"/>
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M7 21c-0.55 0-1.02-0.2-1.41-0.59A1.93 1.93 0 0 1 5 19V6a0.97 0.97 0 0 1-0.71-0.29A0.97 0.97 0 0 1 4 5c0-0.28 0.1-0.52 0.29-0.71A0.97 0.97 0 0 1 5 4h4a0.97 0.97 0 0 1 0.29-0.71A0.97 0.97 0 0 1 10 3h4a0.97 0.97 0 0 1 0.71 0.29A0.97 0.97 0 0 1 15 4h4a0.97 0.97 0 0 1 0.71 0.29C19.91 4.48 20 4.72 20 5s-0.1 0.52-0.29 0.71A0.97 0.97 0 0 1 19 6v13c0 0.55-0.2 1.02-0.59 1.41A1.93 1.93 0 0 1 17 21H7Zm2-5c0 0.28 0.1 0.52 0.29 0.71C9.48 16.91 9.72 17 10 17s0.52-0.1 0.71-0.29A0.97 0.97 0 0 0 11 16V9a0.97 0.97 0 0 0-0.29-0.71A0.97 0.97 0 0 0 10 8a0.97 0.97 0 0 0-0.71 0.29A0.97 0.97 0 0 0 9 9v7Zm4 0c0 0.28 0.1 0.52 0.29 0.71C13.48 16.91 13.72 17 14 17s0.52-0.1 0.71-0.29A0.97 0.97 0 0 0 15 16V9a0.97 0.97 0 0 0-0.29-0.71A0.97 0.97 0 0 0 14 8a0.97 0.97 0 0 0-0.71 0.29A0.97 0.97 0 0 0 13 9v7Z"/>
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M12 17a0.97 0.97 0 0 0 0.71-0.29A0.97 0.97 0 0 0 13 16a0.97 0.97 0 0 0-0.29-0.71A0.97 0.97 0 0 0 12 15a0.97 0.97 0 0 0-0.71 0.29A0.97 0.97 0 0 0 11 16c0 0.28 0.1 0.52 0.29 0.71C11.48 16.91 11.72 17 12 17Zm0-4c0.28 0 0.52-0.1 0.71-0.29A0.97 0.97 0 0 0 13 12V8a0.97 0.97 0 0 0-0.29-0.71A0.97 0.97 0 0 0 12 7a0.97 0.97 0 0 0-0.71 0.29A0.97 0.97 0 0 0 11 8v4c0 0.28 0.1 0.52 0.29 0.71C11.48 12.91 11.72 13 12 13Zm0 9a9.74 9.74 0 0 1-3.9-0.79 10.1 10.1 0 0 1-3.17-2.14c-0.9-0.9-1.62-1.95-2.14-3.17A9.74 9.74 0 0 1 2 12a9.74 9.74 0 0 1 0.79-3.9 10.1 10.1 0 0 1 2.14-3.17c0.9-0.9 1.95-1.62 3.17-2.14A9.74 9.74 0 0 1 12 2a9.74 9.74 0 0 1 3.9 0.79 10.1 10.1 0 0 1 3.17 2.14c0.9 0.9 1.62 1.95 2.14 3.17A9.74 9.74 0 0 1 22 12a9.74 9.74 0 0 1-0.79 3.9 10.1 10.1 0 0 1-2.14 3.17c-0.9 0.9-1.95 1.62-3.17 2.14A9.74 9.74 0 0 1 12 22Z"/>
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M12 17a0.97 0.97 0 0 0 0.71-0.29A0.97 0.97 0 0 0 13 16v-4a0.97 0.97 0 0 0-0.29-0.71A0.97 0.97 0 0 0 12 11a0.97 0.97 0 0 0-0.71 0.29A0.97 0.97 0 0 0 11 12v4c0 0.28 0.1 0.52 0.29 0.71C11.48 16.91 11.72 17 12 17Zm0-8c0.28 0 0.52-0.1 0.71-0.29A0.97 0.97 0 0 0 13 8a0.97 0.97 0 0 0-0.29-0.71A0.97 0.97 0 0 0 12 7a0.97 0.97 0 0 0-0.71 0.29A0.97 0.97 0 0 0 11 8c0 0.28 0.1 0.52 0.29 0.71C11.48 8.91 11.72 9 12 9Zm0 13a9.74 9.74 0 0 1-3.9-0.79 10.1 10.1 0 0 1-3.17-2.14c-0.9-0.9-1.62-1.95-2.14-3.17A9.74 9.74 0 0 1 2 12a9.74 9.74 0 0 1 0.79-3.9 10.1 10.1 0 0 1 2.14-3.17c0.9-0.9 1.95-1.62 3.17-2.14A9.74 9.74 0 0 1 12 2a9.74 9.74 0 0 1 3.9 0.79 10.1 10.1 0 0 1 3.17 2.14c0.9 0.9 1.62 1.95 2.14 3.17A9.74 9.74 0 0 1 22 12a9.74 9.74 0 0 1-0.79 3.9 10.1 10.1 0 0 1-2.14 3.17c-0.9 0.9-1.95 1.62-3.17 2.14A9.74 9.74 0 0 1 12 22Z"/>
</vector>

Some files were not shown because too many files have changed in this diff Show more