Create dedicated package for visual list and add Figma link.

This commit is contained in:
Benoit Marty
2026-07-02 14:45:22 +02:00
parent 58b3830187
commit d8b1a41f56
8 changed files with 95 additions and 81 deletions
@@ -6,9 +6,8 @@
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.libraries.designsystem.atomic.organisms
package io.element.android.libraries.designsystem.components.visuallist
import androidx.annotation.DrawableRes
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.size
@@ -17,14 +16,11 @@ import androidx.compose.material3.LocalTextStyle
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import io.element.android.compound.theme.ElementTheme
import io.element.android.libraries.designsystem.atomic.molecules.InfoListItemMolecule
import io.element.android.libraries.designsystem.atomic.molecules.InfoListItemPosition
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.Icon
@@ -32,9 +28,12 @@ import io.element.android.libraries.designsystem.theme.components.Text
import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf
/**
* Ref: https://www.figma.com/design/G1xy0HDZKJf5TCRFmKb5d5/Compound-Android-Components?node-id=2001-140
*/
@Composable
fun InfoListOrganism(
items: ImmutableList<InfoListItem>,
fun VisualList(
items: ImmutableList<VisualListItemData>,
modifier: Modifier = Modifier,
backgroundColor: Color = ElementTheme.colors.bgSubtleSecondary,
iconTint: Color = LocalContentColor.current,
@@ -49,12 +48,12 @@ fun InfoListOrganism(
) {
for ((index, item) in items.withIndex()) {
val position = when {
items.size == 1 -> InfoListItemPosition.Single
index == 0 -> InfoListItemPosition.Top
index == items.size - 1 -> InfoListItemPosition.Bottom
else -> InfoListItemPosition.Middle
items.size == 1 -> VisualListItemPosition.Single
index == 0 -> VisualListItemPosition.Top
index == items.size - 1 -> VisualListItemPosition.Bottom
else -> VisualListItemPosition.Middle
}
InfoListItemMolecule(
VisualListItem(
message = {
if (item.message is AnnotatedString) {
Text(
@@ -96,22 +95,15 @@ fun InfoListOrganism(
}
}
data class InfoListItem(
val message: CharSequence,
@DrawableRes val iconId: Int? = null,
val iconVector: ImageVector? = null,
val iconComposable: @Composable () -> Unit = {},
)
@PreviewsDayNight
@Composable
internal fun InfoListOrganismPreview() = ElementPreview {
internal fun VisualListPreview() = ElementPreview {
val items = persistentListOf(
InfoListItem(message = "A top item"),
InfoListItem(message = "A middle item"),
InfoListItem(message = "A bottom item"),
VisualListItemData(message = "A top item"),
VisualListItemData(message = "A middle item"),
VisualListItemData(message = "A bottom item"),
)
InfoListOrganism(
VisualList(
items = items,
)
}
@@ -6,7 +6,7 @@
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.libraries.designsystem.atomic.molecules
package io.element.android.libraries.designsystem.components.visuallist
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
@@ -27,10 +27,13 @@ import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.theme.components.Text
/**
* Ref: https://www.figma.com/design/G1xy0HDZKJf5TCRFmKb5d5/Compound-Android-Components?node-id=2001-159
*/
@Composable
fun InfoListItemMolecule(
fun VisualListItem(
message: @Composable () -> Unit,
position: InfoListItemPosition,
position: VisualListItemPosition,
backgroundColor: Color,
modifier: Modifier = Modifier,
icon: @Composable () -> Unit = {},
@@ -38,10 +41,10 @@ fun InfoListItemMolecule(
val radius = 14.dp
val backgroundShape = remember(position) {
when (position) {
InfoListItemPosition.Single -> RoundedCornerShape(radius)
InfoListItemPosition.Top -> RoundedCornerShape(topStart = radius, topEnd = radius)
InfoListItemPosition.Middle -> RoundedCornerShape(0.dp)
InfoListItemPosition.Bottom -> RoundedCornerShape(bottomStart = radius, bottomEnd = radius)
VisualListItemPosition.Single -> RoundedCornerShape(radius)
VisualListItemPosition.Top -> RoundedCornerShape(topStart = radius, topEnd = radius)
VisualListItemPosition.Middle -> RoundedCornerShape(0.dp)
VisualListItemPosition.Bottom -> RoundedCornerShape(bottomStart = radius, bottomEnd = radius)
}
}
Row(
@@ -61,42 +64,42 @@ fun InfoListItemMolecule(
@PreviewsDayNight
@Composable
internal fun InfoListItemMoleculePreview() {
internal fun VisualListItemPreview() {
ElementPreview {
val color = ElementTheme.colors.bgSubtleSecondary
Column(
modifier = Modifier.padding(10.dp),
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
InfoListItemMolecule(
VisualListItem(
message = { Text("A single item") },
icon = { Icon(imageVector = CompoundIcons.InfoSolid(), contentDescription = null) },
position = InfoListItemPosition.Single,
position = VisualListItemPosition.Single,
backgroundColor = color,
)
InfoListItemMolecule(
VisualListItem(
message = { Text("A top item") },
icon = { Icon(imageVector = CompoundIcons.InfoSolid(), contentDescription = null) },
position = InfoListItemPosition.Top,
position = VisualListItemPosition.Top,
backgroundColor = color,
)
InfoListItemMolecule(
VisualListItem(
message = { Text("A middle item") },
icon = { Icon(imageVector = CompoundIcons.InfoSolid(), contentDescription = null) },
position = InfoListItemPosition.Middle,
position = VisualListItemPosition.Middle,
backgroundColor = color,
)
InfoListItemMolecule(
VisualListItem(
message = { Text("A bottom item") },
icon = { Icon(imageVector = CompoundIcons.InfoSolid(), contentDescription = null) },
position = InfoListItemPosition.Bottom,
position = VisualListItemPosition.Bottom,
backgroundColor = color,
)
}
}
}
enum class InfoListItemPosition {
enum class VisualListItemPosition {
Top,
Middle,
Bottom,
@@ -0,0 +1,19 @@
/*
* Copyright (c) 2026 Element Creations Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.libraries.designsystem.components.visuallist
import androidx.annotation.DrawableRes
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.vector.ImageVector
data class VisualListItemData(
val message: CharSequence,
@DrawableRes val iconId: Int? = null,
val iconVector: ImageVector? = null,
val iconComposable: @Composable () -> Unit = {},
)