Merge pull request #7141 from element-hq/feature/bma/visualListItem

Iterate on visual list
This commit is contained in:
Benoit Marty
2026-07-03 09:35:31 +02:00
committed by GitHub
24 changed files with 117 additions and 111 deletions
@@ -31,12 +31,12 @@ import io.element.android.compound.tokens.generated.CompoundIcons
import io.element.android.features.analytics.api.AnalyticsOptInEvents import io.element.android.features.analytics.api.AnalyticsOptInEvents
import io.element.android.libraries.designsystem.atomic.molecules.ButtonColumnMolecule import io.element.android.libraries.designsystem.atomic.molecules.ButtonColumnMolecule
import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule
import io.element.android.libraries.designsystem.atomic.organisms.InfoListItem
import io.element.android.libraries.designsystem.atomic.organisms.InfoListOrganism
import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage
import io.element.android.libraries.designsystem.background.OnboardingBackground import io.element.android.libraries.designsystem.background.OnboardingBackground
import io.element.android.libraries.designsystem.components.BigIcon import io.element.android.libraries.designsystem.components.BigIcon
import io.element.android.libraries.designsystem.components.ClickableLinkText import io.element.android.libraries.designsystem.components.ClickableLinkText
import io.element.android.libraries.designsystem.components.visuallist.VisualList
import io.element.android.libraries.designsystem.components.visuallist.VisualListItemData
import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.text.buildAnnotatedStringWithStyledPart import io.element.android.libraries.designsystem.text.buildAnnotatedStringWithStyledPart
@@ -129,22 +129,21 @@ private fun AnalyticsOptInContent() {
verticalBias = -0.4f verticalBias = -0.4f
) )
) { ) {
InfoListOrganism( VisualList(
items = persistentListOf( items = persistentListOf(
InfoListItem( VisualListItemData(
message = stringResource(id = R.string.screen_analytics_prompt_data_usage), message = stringResource(id = R.string.screen_analytics_prompt_data_usage),
iconVector = CompoundIcons.CheckCircle(), iconVector = CompoundIcons.CheckCircle(),
), ),
InfoListItem( VisualListItemData(
message = stringResource(id = R.string.screen_analytics_prompt_third_party_sharing), message = stringResource(id = R.string.screen_analytics_prompt_third_party_sharing),
iconVector = CompoundIcons.CheckCircle(), iconVector = CompoundIcons.CheckCircle(),
), ),
InfoListItem( VisualListItemData(
message = stringResource(id = R.string.screen_analytics_prompt_settings), message = stringResource(id = R.string.screen_analytics_prompt_settings),
iconVector = CompoundIcons.CheckCircle(), iconVector = CompoundIcons.CheckCircle(),
), ),
), ),
textStyle = ElementTheme.typography.fontBodyLgMedium,
iconTint = ElementTheme.colors.iconSuccessPrimary, iconTint = ElementTheme.colors.iconSuccessPrimary,
) )
} }
@@ -36,10 +36,10 @@ import io.element.android.features.announcement.impl.AnnouncementState
import io.element.android.features.announcement.impl.AnnouncementStateProvider import io.element.android.features.announcement.impl.AnnouncementStateProvider
import io.element.android.libraries.designsystem.atomic.molecules.ButtonColumnMolecule import io.element.android.libraries.designsystem.atomic.molecules.ButtonColumnMolecule
import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule
import io.element.android.libraries.designsystem.atomic.organisms.InfoListItem
import io.element.android.libraries.designsystem.atomic.organisms.InfoListOrganism
import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage
import io.element.android.libraries.designsystem.components.BigIcon import io.element.android.libraries.designsystem.components.BigIcon
import io.element.android.libraries.designsystem.components.visuallist.VisualList
import io.element.android.libraries.designsystem.components.visuallist.VisualListItemData
import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.Button import io.element.android.libraries.designsystem.theme.components.Button
@@ -134,11 +134,9 @@ private fun FullscreenAnnouncementContent(
Column( Column(
modifier = modifier.fillMaxSize(), modifier = modifier.fillMaxSize(),
) { ) {
InfoListOrganism( VisualList(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
items = announcement.items(), items = announcement.items(),
textStyle = ElementTheme.typography.fontBodyLgMedium,
iconTint = ElementTheme.colors.iconSecondary,
iconSize = 24.dp iconSize = 24.dp
) )
announcement.notice()?.let { notice -> announcement.notice()?.let { notice ->
@@ -186,25 +184,25 @@ private fun Announcement.Fullscreen.icon() = when (this) {
} }
@Composable @Composable
private fun Announcement.Fullscreen.items(): ImmutableList<InfoListItem> = when (this) { private fun Announcement.Fullscreen.items(): ImmutableList<VisualListItemData> = when (this) {
Announcement.Fullscreen.Space -> persistentListOf( Announcement.Fullscreen.Space -> persistentListOf(
InfoListItem( VisualListItemData(
message = "View spaces you\'ve created or joined", message = "View spaces you\'ve created or joined",
iconVector = CompoundIcons.VisibilityOn(), iconVector = CompoundIcons.VisibilityOn(),
), ),
InfoListItem( VisualListItemData(
message = "Accept or decline invites to spaces", message = "Accept or decline invites to spaces",
iconVector = CompoundIcons.Email(), iconVector = CompoundIcons.Email(),
), ),
InfoListItem( VisualListItemData(
message = "Discover any rooms you can join in your spaces", message = "Discover any rooms you can join in your spaces",
iconVector = CompoundIcons.Search(), iconVector = CompoundIcons.Search(),
), ),
InfoListItem( VisualListItemData(
message = "Join public spaces", message = "Join public spaces",
iconVector = CompoundIcons.Explore(), iconVector = CompoundIcons.Explore(),
), ),
InfoListItem( VisualListItemData(
message = "Leave any spaces you’ve joined", message = "Leave any spaces you’ve joined",
iconVector = CompoundIcons.Leave(), iconVector = CompoundIcons.Leave(),
), ),
@@ -48,11 +48,11 @@ import io.element.android.compound.tokens.generated.CompoundIcons
import io.element.android.features.deactivation.impl.R import io.element.android.features.deactivation.impl.R
import io.element.android.features.logout.impl.ui.AccountDeactivationActionDialog import io.element.android.features.logout.impl.ui.AccountDeactivationActionDialog
import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncAction
import io.element.android.libraries.designsystem.atomic.organisms.InfoListItem
import io.element.android.libraries.designsystem.atomic.organisms.InfoListOrganism
import io.element.android.libraries.designsystem.components.button.BackButton import io.element.android.libraries.designsystem.components.button.BackButton
import io.element.android.libraries.designsystem.components.form.textFieldState import io.element.android.libraries.designsystem.components.form.textFieldState
import io.element.android.libraries.designsystem.components.list.SwitchListItem import io.element.android.libraries.designsystem.components.list.SwitchListItem
import io.element.android.libraries.designsystem.components.visuallist.VisualList
import io.element.android.libraries.designsystem.components.visuallist.VisualListItemData
import io.element.android.libraries.designsystem.modifiers.onTabOrEnterKeyFocusNext import io.element.android.libraries.designsystem.modifiers.onTabOrEnterKeyFocusNext
import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.preview.PreviewsDayNight
@@ -175,9 +175,9 @@ private fun Content(
style = ElementTheme.typography.fontBodyMdRegular, style = ElementTheme.typography.fontBodyMdRegular,
color = ElementTheme.colors.textSecondary, color = ElementTheme.colors.textSecondary,
) )
InfoListOrganism( VisualList(
items = persistentListOf( items = persistentListOf(
InfoListItem( VisualListItemData(
message = buildAnnotatedStringWithStyledPart( message = buildAnnotatedStringWithStyledPart(
R.string.screen_deactivate_account_list_item_1, R.string.screen_deactivate_account_list_item_1,
R.string.screen_deactivate_account_list_item_1_bold_part, R.string.screen_deactivate_account_list_item_1_bold_part,
@@ -194,7 +194,7 @@ private fun Content(
) )
}, },
), ),
InfoListItem( VisualListItemData(
message = stringResource(R.string.screen_deactivate_account_list_item_2), message = stringResource(R.string.screen_deactivate_account_list_item_2),
iconComposable = { iconComposable = {
Icon( Icon(
@@ -205,7 +205,7 @@ private fun Content(
) )
}, },
), ),
InfoListItem( VisualListItemData(
message = stringResource(R.string.screen_deactivate_account_list_item_3), message = stringResource(R.string.screen_deactivate_account_list_item_3),
iconComposable = { iconComposable = {
Icon( Icon(
@@ -216,7 +216,7 @@ private fun Content(
) )
}, },
), ),
InfoListItem( VisualListItemData(
message = stringResource(R.string.screen_deactivate_account_list_item_4), message = stringResource(R.string.screen_deactivate_account_list_item_4),
iconComposable = { iconComposable = {
Icon( Icon(
@@ -22,11 +22,11 @@ import androidx.compose.ui.unit.dp
import io.element.android.compound.theme.ElementTheme import io.element.android.compound.theme.ElementTheme
import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.compound.tokens.generated.CompoundIcons
import io.element.android.features.securebackup.impl.R import io.element.android.features.securebackup.impl.R
import io.element.android.libraries.designsystem.atomic.organisms.InfoListItem
import io.element.android.libraries.designsystem.atomic.organisms.InfoListOrganism
import io.element.android.libraries.designsystem.atomic.pages.FlowStepPage import io.element.android.libraries.designsystem.atomic.pages.FlowStepPage
import io.element.android.libraries.designsystem.components.BigIcon import io.element.android.libraries.designsystem.components.BigIcon
import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog
import io.element.android.libraries.designsystem.components.visuallist.VisualList
import io.element.android.libraries.designsystem.components.visuallist.VisualListItemData
import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.Button import io.element.android.libraries.designsystem.theme.components.Button
@@ -79,10 +79,10 @@ private fun Content() {
modifier = Modifier.padding(top = 8.dp, bottom = 40.dp), modifier = Modifier.padding(top = 8.dp, bottom = 40.dp),
verticalArrangement = Arrangement.spacedBy(24.dp), verticalArrangement = Arrangement.spacedBy(24.dp),
) { ) {
InfoListOrganism( VisualList(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
items = persistentListOf( items = persistentListOf(
InfoListItem( VisualListItemData(
message = stringResource(R.string.screen_encryption_reset_bullet_1), message = stringResource(R.string.screen_encryption_reset_bullet_1),
iconComposable = { iconComposable = {
Icon( Icon(
@@ -93,7 +93,7 @@ private fun Content() {
) )
}, },
), ),
InfoListItem( VisualListItemData(
message = stringResource(R.string.screen_encryption_reset_bullet_2), message = stringResource(R.string.screen_encryption_reset_bullet_2),
iconComposable = { iconComposable = {
Icon( Icon(
@@ -104,7 +104,7 @@ private fun Content() {
) )
}, },
), ),
InfoListItem( VisualListItemData(
message = stringResource(R.string.screen_encryption_reset_bullet_3), message = stringResource(R.string.screen_encryption_reset_bullet_3),
iconComposable = { iconComposable = {
Icon( Icon(
@@ -21,14 +21,13 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import io.element.android.compound.theme.ElementTheme
import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.compound.tokens.generated.CompoundIcons
import io.element.android.libraries.designsystem.atomic.molecules.ButtonColumnMolecule import io.element.android.libraries.designsystem.atomic.molecules.ButtonColumnMolecule
import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule
import io.element.android.libraries.designsystem.atomic.organisms.InfoListItem
import io.element.android.libraries.designsystem.atomic.organisms.InfoListOrganism
import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage import io.element.android.libraries.designsystem.atomic.pages.HeaderFooterPage
import io.element.android.libraries.designsystem.components.BigIcon import io.element.android.libraries.designsystem.components.BigIcon
import io.element.android.libraries.designsystem.components.visuallist.VisualList
import io.element.android.libraries.designsystem.components.visuallist.VisualListItemData
import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.Button import io.element.android.libraries.designsystem.theme.components.Button
@@ -75,23 +74,21 @@ private fun SignedOutContent() {
verticalBias = -0.4f verticalBias = -0.4f
) )
) { ) {
InfoListOrganism( VisualList(
items = persistentListOf( items = persistentListOf(
InfoListItem( VisualListItemData(
message = stringResource(id = R.string.screen_signed_out_reason_1), message = stringResource(id = R.string.screen_signed_out_reason_1),
iconVector = CompoundIcons.Lock(), iconVector = CompoundIcons.Lock(),
), ),
InfoListItem( VisualListItemData(
message = stringResource(id = R.string.screen_signed_out_reason_2), message = stringResource(id = R.string.screen_signed_out_reason_2),
iconVector = CompoundIcons.Devices(), iconVector = CompoundIcons.Devices(),
), ),
InfoListItem( VisualListItemData(
message = stringResource(id = R.string.screen_signed_out_reason_3), message = stringResource(id = R.string.screen_signed_out_reason_3),
iconVector = CompoundIcons.Block(), iconVector = CompoundIcons.Block(),
), ),
), ),
textStyle = ElementTheme.typography.fontBodyMdMedium,
iconTint = ElementTheme.colors.iconSecondary,
) )
} }
} }
@@ -6,25 +6,19 @@
* Please see LICENSE files in the repository root for full details. * 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.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.LocalTextStyle
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import io.element.android.compound.theme.ElementTheme 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.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight 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.Icon
@@ -32,14 +26,17 @@ import io.element.android.libraries.designsystem.theme.components.Text
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
/**
* Ref: https://www.figma.com/design/G1xy0HDZKJf5TCRFmKb5d5/Compound-Android-Components?node-id=2001-140
*/
@Composable @Composable
fun InfoListOrganism( fun VisualList(
items: ImmutableList<InfoListItem>, items: ImmutableList<VisualListItemData>,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
backgroundColor: Color = ElementTheme.colors.bgSubtleSecondary, backgroundColor: Color = ElementTheme.colors.bgSubtleSecondary,
iconTint: Color = LocalContentColor.current, iconTint: Color = ElementTheme.colors.iconSecondary,
iconSize: Dp = 20.dp, iconSize: Dp = 20.dp,
textStyle: TextStyle = LocalTextStyle.current, textStyle: TextStyle = ElementTheme.typography.fontBodyMdMedium,
textColor: Color = ElementTheme.colors.textPrimary, textColor: Color = ElementTheme.colors.textPrimary,
verticalArrangement: Arrangement.Vertical = Arrangement.spacedBy(4.dp), verticalArrangement: Arrangement.Vertical = Arrangement.spacedBy(4.dp),
) { ) {
@@ -49,12 +46,12 @@ fun InfoListOrganism(
) { ) {
for ((index, item) in items.withIndex()) { for ((index, item) in items.withIndex()) {
val position = when { val position = when {
items.size == 1 -> InfoListItemPosition.Single items.size == 1 -> VisualListItemPosition.Single
index == 0 -> InfoListItemPosition.Top index == 0 -> VisualListItemPosition.Top
index == items.size - 1 -> InfoListItemPosition.Bottom index == items.size - 1 -> VisualListItemPosition.Bottom
else -> InfoListItemPosition.Middle else -> VisualListItemPosition.Middle
} }
InfoListItemMolecule( VisualListItem(
message = { message = {
if (item.message is AnnotatedString) { if (item.message is AnnotatedString) {
Text( Text(
@@ -96,22 +93,15 @@ fun InfoListOrganism(
} }
} }
data class InfoListItem(
val message: CharSequence,
@DrawableRes val iconId: Int? = null,
val iconVector: ImageVector? = null,
val iconComposable: @Composable () -> Unit = {},
)
@PreviewsDayNight @PreviewsDayNight
@Composable @Composable
internal fun InfoListOrganismPreview() = ElementPreview { internal fun VisualListPreview() = ElementPreview {
val items = persistentListOf( val items = persistentListOf(
InfoListItem(message = "A top item"), VisualListItemData(message = "A top item"),
InfoListItem(message = "A middle item"), VisualListItemData(message = "A middle item"),
InfoListItem(message = "A bottom item"), VisualListItemData(message = "A bottom item"),
) )
InfoListOrganism( VisualList(
items = items, items = items,
) )
} }
@@ -6,7 +6,7 @@
* Please see LICENSE files in the repository root for full details. * 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.background
import androidx.compose.foundation.layout.Arrangement 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.Icon
import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.Text
/**
* Ref: https://www.figma.com/design/G1xy0HDZKJf5TCRFmKb5d5/Compound-Android-Components?node-id=2001-159
*/
@Composable @Composable
fun InfoListItemMolecule( fun VisualListItem(
message: @Composable () -> Unit, message: @Composable () -> Unit,
position: InfoListItemPosition, position: VisualListItemPosition,
backgroundColor: Color, backgroundColor: Color,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
icon: @Composable () -> Unit = {}, icon: @Composable () -> Unit = {},
@@ -38,10 +41,10 @@ fun InfoListItemMolecule(
val radius = 14.dp val radius = 14.dp
val backgroundShape = remember(position) { val backgroundShape = remember(position) {
when (position) { when (position) {
InfoListItemPosition.Single -> RoundedCornerShape(radius) VisualListItemPosition.Single -> RoundedCornerShape(radius)
InfoListItemPosition.Top -> RoundedCornerShape(topStart = radius, topEnd = radius) VisualListItemPosition.Top -> RoundedCornerShape(topStart = radius, topEnd = radius)
InfoListItemPosition.Middle -> RoundedCornerShape(0.dp) VisualListItemPosition.Middle -> RoundedCornerShape(0.dp)
InfoListItemPosition.Bottom -> RoundedCornerShape(bottomStart = radius, bottomEnd = radius) VisualListItemPosition.Bottom -> RoundedCornerShape(bottomStart = radius, bottomEnd = radius)
} }
} }
Row( Row(
@@ -61,42 +64,42 @@ fun InfoListItemMolecule(
@PreviewsDayNight @PreviewsDayNight
@Composable @Composable
internal fun InfoListItemMoleculePreview() { internal fun VisualListItemPreview() {
ElementPreview { ElementPreview {
val color = ElementTheme.colors.bgSubtleSecondary val color = ElementTheme.colors.bgSubtleSecondary
Column( Column(
modifier = Modifier.padding(10.dp), modifier = Modifier.padding(10.dp),
verticalArrangement = Arrangement.spacedBy(8.dp), verticalArrangement = Arrangement.spacedBy(8.dp),
) { ) {
InfoListItemMolecule( VisualListItem(
message = { Text("A single item") }, message = { Text("A single item") },
icon = { Icon(imageVector = CompoundIcons.InfoSolid(), contentDescription = null) }, icon = { Icon(imageVector = CompoundIcons.InfoSolid(), contentDescription = null) },
position = InfoListItemPosition.Single, position = VisualListItemPosition.Single,
backgroundColor = color, backgroundColor = color,
) )
InfoListItemMolecule( VisualListItem(
message = { Text("A top item") }, message = { Text("A top item") },
icon = { Icon(imageVector = CompoundIcons.InfoSolid(), contentDescription = null) }, icon = { Icon(imageVector = CompoundIcons.InfoSolid(), contentDescription = null) },
position = InfoListItemPosition.Top, position = VisualListItemPosition.Top,
backgroundColor = color, backgroundColor = color,
) )
InfoListItemMolecule( VisualListItem(
message = { Text("A middle item") }, message = { Text("A middle item") },
icon = { Icon(imageVector = CompoundIcons.InfoSolid(), contentDescription = null) }, icon = { Icon(imageVector = CompoundIcons.InfoSolid(), contentDescription = null) },
position = InfoListItemPosition.Middle, position = VisualListItemPosition.Middle,
backgroundColor = color, backgroundColor = color,
) )
InfoListItemMolecule( VisualListItem(
message = { Text("A bottom item") }, message = { Text("A bottom item") },
icon = { Icon(imageVector = CompoundIcons.InfoSolid(), contentDescription = null) }, icon = { Icon(imageVector = CompoundIcons.InfoSolid(), contentDescription = null) },
position = InfoListItemPosition.Bottom, position = VisualListItemPosition.Bottom,
backgroundColor = color, backgroundColor = color,
) )
} }
} }
} }
enum class InfoListItemPosition { enum class VisualListItemPosition {
Top, Top,
Middle, Middle,
Bottom, 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 = {},
)