[Compound] Platform components (Lists) (#990)

Co-authored-by: ElementBot <benoitm+elementbot@element.io>
This commit is contained in:
Jorge Martin Espinosa
2023-08-21 10:34:57 +02:00
committed by GitHub
parent 41baa54f01
commit b36667844d
48 changed files with 850 additions and 0 deletions

1
changelog.d/990.misc Normal file
View File

@@ -0,0 +1 @@
Compound: add `ListItem` and `ListSectionHeader` components.

View File

@@ -26,6 +26,8 @@ object PreviewGroup {
const val Dividers = "Dividers"
const val FABs = "Floating Action Buttons"
const val Icons = "Icons"
const val ListItems = "List items"
const val ListSections = "List sections"
const val Menus = "Menus"
const val Preferences = "Preferences"
const val Progress = "Progress Indicators"

View File

@@ -0,0 +1,426 @@
/*
* Copyright (c) 2023 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.element.android.libraries.designsystem.theme.components
import androidx.compose.foundation.clickable
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Share
import androidx.compose.material3.ListItemDefaults
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.LocalTextStyle
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
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.text.style.TextOverflow
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.theme.ElementTheme
// Designs: https://www.figma.com/file/G1xy0HDZKJf5TCRFmKb5d5/Compound-Android-Components?type=design&node-id=425%3A24208&mode=design&t=G5hCfkLB6GgXDuWe-1
/**
* A List Item component to be used in lists and menus with simple layouts, matching the Material 3 guidelines.
* @param headlineContent The main content of the list item, usually a text.
* @param modifier The modifier to be applied to the list item.
* @param supportingContent The content to be displayed below the headline content.
* @param leadingContent The content to be displayed before the headline content.
* @param trailingContent The content to be displayed after the headline content.
* @param style The style to use for the list item. This may change the color and text styles of the contents. [ListItemStyle.Default] is used by default.
* @param enabled Whether the list item is enabled. When disabled, will change the color of the headline content and the leading content to use disabled tokens.
* @param onClick The callback to be called when the list item is clicked.
*/
@Suppress("LongParameterList")
@Composable
fun ListItem(
headlineContent: @Composable () -> Unit,
modifier: Modifier = Modifier,
supportingContent: @Composable (() -> Unit)? = null,
leadingContent: @Composable (() -> Unit)? = null,
trailingContent: @Composable (() -> Unit)? = null,
style: ListItemStyle = ListItemStyle.Default,
enabled: Boolean = true,
onClick: (() -> Unit)? = null,
) {
val headlineColor = if (enabled) when (style) {
ListItemStyle.Destructive -> ElementTheme.colors.textCriticalPrimary
else -> ElementTheme.colors.textPrimary
} else {
// We cannot apply a disabled color by default: https://issuetracker.google.com/issues/280480132
ElementTheme.colors.textDisabled
}
val supportingContentColor = if (enabled) {
ElementTheme.materialColors.onSurfaceVariant
} else {
// We cannot apply a disabled color by default: https://issuetracker.google.com/issues/280480132
ElementTheme.colors.textDisabled
}
val leadingTrailingContentColor = if (enabled) when (style) {
ListItemStyle.Primary -> ElementTheme.colors.iconPrimary
ListItemStyle.Destructive -> ElementTheme.colors.iconCriticalPrimary
else -> ElementTheme.colors.iconTertiary
} else {
// We cannot apply a disabled color by default: https://issuetracker.google.com/issues/280480132
ElementTheme.colors.iconDisabled
}
val decoratedHeadlineContent: @Composable () -> Unit = {
CompositionLocalProvider(
LocalTextStyle provides ElementTheme.materialTypography.bodyLarge,
LocalContentColor provides headlineColor,
) {
headlineContent()
}
}
val decoratedSupportingContent: (@Composable () -> Unit)? = supportingContent?.let { content ->
{
CompositionLocalProvider(
LocalTextStyle provides ElementTheme.materialTypography.bodyMedium,
LocalContentColor provides supportingContentColor,
) {
content()
}
}
}
val decoratedLeadingContent: (@Composable () -> Unit)? = leadingContent?.let { content ->
{
CompositionLocalProvider(
LocalContentColor provides leadingTrailingContentColor,
) {
content()
}
}
}
val decoratedTrailingContent: (@Composable () -> Unit)? = trailingContent?.let { content ->
{
CompositionLocalProvider(
LocalContentColor provides leadingTrailingContentColor,
LocalTextStyle provides ElementTheme.typography.fontBodyMdRegular,
) {
content()
}
}
}
androidx.compose.material3.ListItem(
headlineContent = decoratedHeadlineContent,
modifier = modifier.clickable(enabled = enabled && onClick != null, onClick = onClick ?: {}),
overlineContent = null,
supportingContent = decoratedSupportingContent,
leadingContent = decoratedLeadingContent,
trailingContent = decoratedTrailingContent,
colors = ListItemDefaults.colors(), // These aren't really used since we need the workaround for the disabled state color
tonalElevation = 0.dp,
shadowElevation = 0.dp,
)
}
/**
* The style to use for a [ListItem].
*/
sealed interface ListItemStyle {
object Default : ListItemStyle
object Primary: ListItemStyle
object Destructive : ListItemStyle
}
// region: Simple list item
@Preview(name = "List item (3 lines) - Simple", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemThreeLinesSimplePreview() = PreviewItems.ThreeLinesListItemPreview()
@Preview(name = "List item (2 lines) - Simple", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemTwoLinesSimplePreview() = PreviewItems.TwoLinesListItemPreview()
@Preview(name = "List item (1 line) - Simple", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemSingleLineSimplePreview() = PreviewItems.OneLineListItemPreview()
// endregion
// region: Trailing Checkbox
@Preview(name = "List item (3 lines) - Trailing Checkbox", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemThreeLinesTrailingCheckBoxPreview() = PreviewItems.ThreeLinesListItemPreview(trailingContent = PreviewItems.checkbox())
@Preview(name = "List item (2 lines) - Trailing Checkbox", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemTwoLinesTrailingCheckBoxPreview() = PreviewItems.TwoLinesListItemPreview(trailingContent = PreviewItems.checkbox())
@Preview(name = "List item (1 line) - Trailing Checkbox", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemSingleLineTrailingCheckBoxPreview() = PreviewItems.OneLineListItemPreview(trailingContent = PreviewItems.checkbox())
// endregion
// region: Trailing RadioButton
@Preview(name = "List item (3 lines) - Trailing RadioButton", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemThreeLinesTrailingRadioButtonPreview() = PreviewItems.ThreeLinesListItemPreview(trailingContent = PreviewItems.radioButton())
@Preview(name = "List item (2 lines) - Trailing RadioButton", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemTwoLinesTrailingRadioButtonPreview() = PreviewItems.TwoLinesListItemPreview(trailingContent = PreviewItems.radioButton())
@Preview(name = "List item (1 line) - Trailing RadioButton", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemSingleLineTrailingRadioButtonPreview() = PreviewItems.OneLineListItemPreview(trailingContent = PreviewItems.radioButton())
// endregion
// region: Trailing Switch
@Preview(name = "List item (3 lines) - Trailing Switch", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemThreeLinesTrailingSwitchPreview() = PreviewItems.ThreeLinesListItemPreview(trailingContent = PreviewItems.switch())
@Preview(name = "List item (2 lines) - Trailing Switch", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemTwoLinesTrailingSwitchPreview() = PreviewItems.TwoLinesListItemPreview(trailingContent = PreviewItems.switch())
@Preview(name = "List item (1 line) - Trailing Switch", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemSingleLineTrailingSwitchPreview() = PreviewItems.OneLineListItemPreview(trailingContent = PreviewItems.switch())
// endregion
// region: Trailing Icon
@Preview(name = "List item (3 lines) - Trailing Icon", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemThreeLinesTrailingIconPreview() = PreviewItems.ThreeLinesListItemPreview(trailingContent = PreviewItems.icon())
@Preview(name = "List item (2 lines) - Trailing Icon", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemTwoLinesTrailingIconPreview() = PreviewItems.TwoLinesListItemPreview(trailingContent = PreviewItems.icon())
@Preview(name = "List item (1 line) - Trailing Icon", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemSingleLineTrailingIconPreview() = PreviewItems.OneLineListItemPreview(trailingContent = PreviewItems.icon())
// endregion
// region: Leading Checkbox
@Preview(name = "List item (3 lines) - Leading Checkbox", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemThreeLinesLeadingCheckboxPreview() = PreviewItems.ThreeLinesListItemPreview(leadingContent = PreviewItems.checkbox())
@Preview(name = "List item (2 lines) - Leading Checkbox", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemTwoLinesLeadingCheckboxPreview() = PreviewItems.TwoLinesListItemPreview(leadingContent = PreviewItems.checkbox())
@Preview(name = "List item (1 line) - Leading Checkbox", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemSingleLineLeadingCheckboxPreview() = PreviewItems.OneLineListItemPreview(leadingContent = PreviewItems.checkbox())
// endregion
// region: Leading RadioButton
@Preview(name = "List item (3 lines) - Leading RadioButton", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemThreeLinesLeadingRadioButtonPreview() = PreviewItems.ThreeLinesListItemPreview(leadingContent = PreviewItems.radioButton())
@Preview(name = "List item (2 lines) - Leading RadioButton", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemTwoLinesLeadingRadioButtonPreview() = PreviewItems.TwoLinesListItemPreview(leadingContent = PreviewItems.radioButton())
@Preview(name = "List item (1 line) - Leading RadioButton", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemSingleLineLeadingRadioButtonPreview() = PreviewItems.OneLineListItemPreview(leadingContent = PreviewItems.radioButton())
// endregion
// region: Leading Switch
@Preview(name = "List item (3 lines) - Leading Switch", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemThreeLinesLeadingSwitchPreview() = PreviewItems.ThreeLinesListItemPreview(leadingContent = PreviewItems.switch())
@Preview(name = "List item (2 lines) - Leading Switch", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemTwoLinesLeadingSwitchPreview() = PreviewItems.TwoLinesListItemPreview(leadingContent = PreviewItems.switch())
@Preview(name = "List item (1 line) - Leading Switch", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemSingleLineLeadingSwitchPreview() = PreviewItems.OneLineListItemPreview(leadingContent = PreviewItems.switch())
// endregion
// region: Leading Icon
@Preview(name = "List item (3 lines) - Leading Icon", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemThreeLinesLeadingIconPreview() = PreviewItems.ThreeLinesListItemPreview(leadingContent = PreviewItems.icon())
@Preview(name = "List item (2 lines) - Leading Icon", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemTwoLinesLeadingIconPreview() = PreviewItems.TwoLinesListItemPreview(leadingContent = PreviewItems.icon())
@Preview(name = "List item (1 line) - Leading Icon", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemSingleLineLeadingIconPreview() = PreviewItems.OneLineListItemPreview(leadingContent = PreviewItems.icon())
// endregion
// region: Both Icons
@Preview(name = "List item (3 lines) - Both Icons", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemThreeLinesBothIconsPreview() = PreviewItems.ThreeLinesListItemPreview(
leadingContent = PreviewItems.icon(),
trailingContent = PreviewItems.icon()
)
@Preview(name = "List item (2 lines) - Both Icons", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemTwoLinesBothIconsPreview() = PreviewItems.TwoLinesListItemPreview(
leadingContent = PreviewItems.icon(),
trailingContent = PreviewItems.icon()
)
@Preview(name = "List item (1 line) - Both Icons", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemSingleLineBothIconsPreview() = PreviewItems.OneLineListItemPreview(
leadingContent = PreviewItems.icon(),
trailingContent = PreviewItems.icon()
)
// endregion
// region: Primary action
@Preview(name = "List item - Primary action & Icon", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemPrimaryActionWithIconPreview() = PreviewItems.OneLineListItemPreview(
style = ListItemStyle.Primary,
leadingContent = PreviewItems.icon(),
)
// endregion
// region: Error state
@Preview(name = "List item - Error", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemErrorPreview() = PreviewItems.OneLineListItemPreview(style = ListItemStyle.Destructive)
@Preview(name = "List item - Error & Icon", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemErrorWithIconPreview() = PreviewItems.OneLineListItemPreview(
style = ListItemStyle.Destructive,
leadingContent = PreviewItems.icon(),
)
// endregion
// region: Disabled state
@Preview(name = "List item - Disabled", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemDisabledPreview() = PreviewItems.OneLineListItemPreview(enabled = false)
@Preview(name = "List item - Disabled & Icon", group = PreviewGroup.ListItems)
@Composable
internal fun ListItemDisabledWithIconPreview() = PreviewItems.OneLineListItemPreview(
enabled = false,
leadingContent = PreviewItems.icon(),
)
// endregion
@Suppress("ModifierMissing")
private object PreviewItems {
@Composable
fun ThreeLinesListItemPreview(
modifier: Modifier = Modifier,
leadingContent: @Composable (() -> Unit)? = null,
trailingContent: @Composable (() -> Unit)? = null,
) {
ElementThemedPreview {
ListItem(
headlineContent = PreviewItems.headline(),
supportingContent = PreviewItems.text(),
leadingContent = leadingContent,
trailingContent = trailingContent,
modifier = modifier,
)
}
}
@Composable
fun TwoLinesListItemPreview(
modifier: Modifier = Modifier,
leadingContent: @Composable (() -> Unit)? = null,
trailingContent: @Composable (() -> Unit)? = null,
) {
ElementThemedPreview {
ListItem(
headlineContent = PreviewItems.headline(),
supportingContent = PreviewItems.textSingleLine(),
leadingContent = leadingContent,
trailingContent = trailingContent,
modifier = modifier,
)
}
}
@Composable
fun OneLineListItemPreview(
modifier: Modifier = Modifier,
leadingContent: @Composable (() -> Unit)? = null,
trailingContent: @Composable (() -> Unit)? = null,
style: ListItemStyle = ListItemStyle.Default,
enabled: Boolean = true,
) {
ElementThemedPreview {
ListItem(
headlineContent = PreviewItems.headline(),
leadingContent = leadingContent,
trailingContent = trailingContent,
enabled = enabled,
style = style,
modifier = modifier,
)
}
}
@Composable
fun headline() = @Composable {
Text("List item")
}
@Composable
fun text() = @Composable {
Text("Supporting line text lorem ipsum dolor sit amet, consectetur.")
}
@Composable
fun textSingleLine() = @Composable {
Text("Supporting line text lorem ipsum dolor sit amet, consectetur.", overflow = TextOverflow.Ellipsis, maxLines = 1)
}
@Composable
fun checkbox() = @Composable {
var checked by remember { mutableStateOf(false) }
Checkbox(checked = checked, onCheckedChange = { checked = !checked })
}
@Composable
fun radioButton() = @Composable {
var checked by remember { mutableStateOf(false) }
RadioButton(selected = checked, onClick = { checked = !checked })
}
@Composable
fun switch() = @Composable {
var checked by remember { mutableStateOf(false) }
Switch(checked = checked, onCheckedChange = { checked = !checked })
}
@Composable
fun icon() = @Composable {
Icon(imageVector = Icons.Outlined.Share, contentDescription = null)
}
}

View File

@@ -0,0 +1,289 @@
/*
* Copyright (c) 2023 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.element.android.libraries.designsystem.theme.components
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Share
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.LocalTextStyle
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.AnnotatedString
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.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.theme.ElementTheme
// Designs: https://www.figma.com/file/G1xy0HDZKJf5TCRFmKb5d5/Compound-Android-Components?type=design&node-id=425%3A24208&mode=design&t=G5hCfkLB6GgXDuWe-1
/**
* List section header.
* @param title The title of the section.
* @param modifier The modifier to be applied to the section.
* @param hasDivider Whether to show a divider above the section or not. Default is `true`.
* @param description A description for the section. It's empty by default.
*/
@Composable
fun ListSectionHeader(
title: String,
modifier: Modifier = Modifier,
hasDivider: Boolean = true,
description: @Composable () -> Unit = {},
) {
Column(modifier.fillMaxWidth()) {
if (hasDivider) {
HorizontalDivider(modifier = Modifier.padding(top = 16.dp))
}
Column(
modifier = Modifier.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
Text(
text = title,
style = ElementTheme.typography.fontBodyLgMedium,
color = ElementTheme.colors.textPrimary,
)
CompositionLocalProvider(
LocalTextStyle provides ElementTheme.typography.fontBodySmRegular,
LocalContentColor provides ElementTheme.colors.textSecondary,
) {
description()
}
}
}
}
/**
* List supporting text item. Used to display an explanation in the list with a pre-formatted style.
* @param text The text to display.
* @param modifier The modifier to be applied to the text.
* @param contentPadding The padding to apply to the text. Default is [ListSupportingTextDefaults.Padding.Default].
*/
@Composable
fun ListSupportingText(
text: String,
modifier: Modifier = Modifier,
contentPadding: ListSupportingTextDefaults.Padding = ListSupportingTextDefaults.Padding.Default,
) {
Text(
text = text,
modifier = modifier.padding(contentPadding.paddingValues()),
style = ElementTheme.typography.fontBodySmRegular,
color = ElementTheme.colors.textSecondary,
)
}
/**
* List supporting text item. Used to display an explanation in the list with a pre-formatted style.
* @param annotatedString The annotated string to display.
* @param modifier The modifier to be applied to the text.
* @param contentPadding The padding to apply to the text. Default is [ListSupportingTextDefaults.Padding.Default].
*/
@Composable
fun ListSupportingText(
annotatedString: AnnotatedString,
modifier: Modifier = Modifier,
contentPadding: ListSupportingTextDefaults.Padding = ListSupportingTextDefaults.Padding.Default,
) {
Text(
text = annotatedString,
modifier = modifier.padding(contentPadding.paddingValues()),
style = ElementTheme.typography.fontBodySmRegular,
color = ElementTheme.colors.textSecondary,
)
}
object ListSupportingTextDefaults {
/** Specifies the padding to use for the supporting text. */
sealed interface Padding {
/** No padding. */
object None : Padding
/** Default padding, it will align fine with a [ListItem] with no leading content. */
object Default : Padding
/** It will align to a [ListItem] with an [Icon] or [Checkbox] as leading content. */
object SmallLeadingContent : Padding
/** It will align to with a [ListItem] with a [Switch] as leading content. */
object LargeLeadingContent : Padding
/** It will align to with a [ListItem] with a custom start [padding]. */
data class Custom(val padding: Dp) : Padding
private fun startPadding(): Dp = when (this) {
None -> 0.dp
Default -> 16.dp
SmallLeadingContent -> 56.dp
LargeLeadingContent -> 84.dp
is Custom -> padding
}
private fun endPadding(): Dp = when (this) {
None -> 0.dp
else -> 24.dp
}
private fun bottomPadding(): Dp = when (this) {
None -> 0.dp
else -> 12.dp
}
fun paddingValues() = PaddingValues(
top = 0.dp,
bottom = bottomPadding(),
start = startPadding(),
end = endPadding()
)
}
}
// region: List header previews
@Preview(group = PreviewGroup.ListSections, name = "List section header")
@Composable
internal fun ListSectionHeaderPreview() {
ElementThemedPreview {
ListSectionHeader(
title = "List section",
hasDivider = false,
)
}
}
@Preview(group = PreviewGroup.ListSections, name = "List section header with divider")
@Composable
internal fun ListSectionHeaderWithDividerPreview() {
ElementThemedPreview {
ListSectionHeader(
title = "List section",
hasDivider = true,
)
}
}
@Preview(group = PreviewGroup.ListSections, name = "List section header with description")
@Composable
internal fun ListSectionHeaderWithDescriptionPreview() {
ElementThemedPreview {
ListSectionHeader(
title = "List section",
description = {
ListSupportingText(
text = "Supporting line text lorem ipsum dolor sit amet, consectetur. Read more",
contentPadding = ListSupportingTextDefaults.Padding.None,
)
},
hasDivider = false,
)
}
}
@Preview(group = PreviewGroup.ListSections, name = "List section header with description and divider")
@Composable
internal fun ListSectionHeaderWithDescriptionAndDividerPreview() {
ElementThemedPreview {
ListSectionHeader(
title = "List section",
description = {
ListSupportingText(
text = "Supporting line text lorem ipsum dolor sit amet, consectetur. Read more",
contentPadding = ListSupportingTextDefaults.Padding.None,
)
},
hasDivider = true,
)
}
}
// endregion
// region: List supporting text previews
@Preview(group = PreviewGroup.ListSections, name = "List supporting text - no padding")
@Composable
internal fun ListSupportingTextNoPaddingPreview() {
ElementThemedPreview {
ListSupportingText(
text = "Supporting line text lorem ipsum dolor sit amet, consectetur. Read more",
contentPadding = ListSupportingTextDefaults.Padding.None,
)
}
}
@Preview(group = PreviewGroup.ListSections, name = "List supporting text - default padding")
@Composable
internal fun ListSupportingTextDefaultPaddingPreview() {
ElementThemedPreview {
Column {
ListItem(headlineContent = { Text("A title") })
ListSupportingText(
text = "Supporting line text lorem ipsum dolor sit amet, consectetur. Read more",
contentPadding = ListSupportingTextDefaults.Padding.Default,
)
}
}
}
@Preview(group = PreviewGroup.ListSections, name = "List supporting text - small padding")
@Composable
internal fun ListSupportingTextSmallPaddingPreview() {
ElementThemedPreview {
Column {
ListItem(headlineContent = { Text("A title") }, leadingContent = { Icon(Icons.Default.Share, null) })
ListSupportingText(
text = "Supporting line text lorem ipsum dolor sit amet, consectetur. Read more",
contentPadding = ListSupportingTextDefaults.Padding.SmallLeadingContent,
)
}
}
}
@Preview(group = PreviewGroup.ListSections, name = "List supporting text - large padding")
@Composable
internal fun ListSupportingTextLargePaddingPreview() {
ElementThemedPreview {
Column {
ListItem(headlineContent = { Text("A title") }, leadingContent = { Switch(checked = true, onCheckedChange = null) })
ListSupportingText(
text = "Supporting line text lorem ipsum dolor sit amet, consectetur. Read more",
contentPadding = ListSupportingTextDefaults.Padding.LargeLeadingContent,
)
}
}
}
@Preview(group = PreviewGroup.ListSections, name = "List supporting text - custom padding")
@Composable
internal fun ListSupportingTextCustomPaddingPreview() {
ElementThemedPreview {
Column {
ListItem(headlineContent = { Text("A title") })
ListSupportingText(
text = "Supporting line text lorem ipsum dolor sit amet, consectetur. Read more",
contentPadding = ListSupportingTextDefaults.Padding.Custom(24.dp),
)
}
}
}
// endregion