[Compound] Implement DropdownMenu customisations. (#1050)

* Compound: implement `DropdownMenu` customisations.

* Update screenshots

* Add changelog

* Address review comments

---------

Co-authored-by: ElementBot <benoitm+elementbot@element.io>
This commit is contained in:
Jorge Martin Espinosa 2023-08-11 15:09:51 +02:00 committed by GitHub
parent a77b59824c
commit f35272c4fe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 71 additions and 39 deletions

1
changelog.d/1050.misc Normal file
View file

@ -0,0 +1 @@
Compound: implement `DropdownMenu` customisations.

View file

@ -67,7 +67,6 @@ import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.preview.LargeHeightPreview
import io.element.android.libraries.designsystem.theme.components.DropdownMenu
import io.element.android.libraries.designsystem.theme.components.DropdownMenuItem
import io.element.android.libraries.designsystem.theme.components.DropdownMenuItemText
import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.theme.components.IconButton
import io.element.android.libraries.designsystem.theme.components.Scaffold
@ -195,7 +194,7 @@ internal fun RoomDetailsTopBar(
onDismissRequest = { showMenu = false },
) {
DropdownMenuItem(
text = { DropdownMenuItemText(stringResource(id = CommonStrings.action_edit)) },
text = { Text(stringResource(id = CommonStrings.action_edit)) },
onClick = {
// Explicitly close the menu before handling the action, as otherwise it stays open during the
// transition and renders really badly.

View file

@ -48,7 +48,6 @@ import io.element.android.libraries.designsystem.text.toSp
import io.element.android.libraries.designsystem.theme.aliasScreenTitle
import io.element.android.libraries.designsystem.theme.components.DropdownMenu
import io.element.android.libraries.designsystem.theme.components.DropdownMenuItem
import io.element.android.libraries.designsystem.theme.components.DropdownMenuItemText
import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.theme.components.IconButton
import io.element.android.libraries.designsystem.theme.components.MediumTopAppBar
@ -169,7 +168,7 @@ private fun DefaultRoomListTopBar(
showMenu = false
onMenuActionClicked(RoomListMenuAction.InviteFriends)
},
text = { DropdownMenuItemText(stringResource(id = CommonStrings.action_invite)) },
text = { Text(stringResource(id = CommonStrings.action_invite)) },
leadingIcon = {
Icon(
Icons.Outlined.Share,
@ -183,7 +182,7 @@ private fun DefaultRoomListTopBar(
showMenu = false
onMenuActionClicked(RoomListMenuAction.ReportBug)
},
text = { DropdownMenuItemText(stringResource(id = CommonStrings.common_report_a_bug)) },
text = { Text(stringResource(id = CommonStrings.common_report_a_bug)) },
leadingIcon = {
Icon(
Icons.Outlined.BugReport,

View file

@ -26,7 +26,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.PopupProperties
import io.element.android.libraries.theme.ElementTheme
private val minMenuWidth = 200.dp
// Figma designs: https://www.figma.com/file/G1xy0HDZKJf5TCRFmKb5d5/Compound-Android-Components?type=design&node-id=1032%3A44063&mode=design&t=rsNegTbEVLYAXL76-1
@Composable
fun DropdownMenu(
@ -38,19 +38,17 @@ fun DropdownMenu(
properties: PopupProperties = PopupProperties(focusable = true),
content: @Composable ColumnScope.() -> Unit
) {
val bgColor = if (ElementTheme.isLightTheme) {
ElementTheme.materialColors.background
} else {
ElementTheme.colors.bgSubtlePrimary
}
// Note: the internal shape corner radius should be 8dp, but there is a 4p value hardcoded in the internal Surface component
androidx.compose.material3.DropdownMenu(
expanded = expanded,
onDismissRequest = onDismissRequest,
modifier = modifier
.background(color = bgColor)
.background(color = ElementTheme.colors.bgCanvasDefault)
.widthIn(min = minMenuWidth),
offset = offset,
properties = properties,
content = content
)
}
private val minMenuWidth = 200.dp

View file

@ -17,20 +17,26 @@
package io.element.android.libraries.designsystem.theme.components
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowRight
import androidx.compose.material.icons.filled.BugReport
import androidx.compose.material.icons.filled.Share
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.MenuDefaults
import androidx.compose.material3.MenuItemColors
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
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
// Figma designs: https://www.figma.com/file/G1xy0HDZKJf5TCRFmKb5d5/Compound-Android-Components?type=design&node-id=1032%3A44063&mode=design&t=rsNegTbEVLYAXL76-1
@Composable
fun DropdownMenuItem(
text: @Composable () -> Unit,
@ -39,34 +45,37 @@ fun DropdownMenuItem(
leadingIcon: @Composable (() -> Unit)? = null,
trailingIcon: @Composable (() -> Unit)? = null,
enabled: Boolean = true,
colors: MenuItemColors = MenuDefaults.itemColors(),
contentPadding: PaddingValues = MenuDefaults.DropdownMenuItemContentPadding,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
) {
androidx.compose.material3.DropdownMenuItem(
text = text,
text = {
CompositionLocalProvider(LocalTextStyle provides MaterialTheme.typography.bodyLarge) {
text()
}
},
onClick = onClick,
modifier = modifier,
leadingIcon = leadingIcon,
trailingIcon = trailingIcon,
enabled = enabled,
colors = colors,
contentPadding = contentPadding,
colors = DropDownMenuItemDefaults.colors(),
contentPadding = DropDownMenuItemDefaults.contentPadding,
interactionSource = interactionSource
)
}
@Composable
fun DropdownMenuItemText(
text: String,
modifier: Modifier = Modifier,
) {
Text(
text = text,
color = ElementTheme.materialColors.primary,
style = ElementTheme.typography.fontBodyLgRegular,
modifier = modifier,
internal object DropDownMenuItemDefaults {
@Composable
fun colors() = MenuDefaults.itemColors(
textColor = ElementTheme.colors.textPrimary,
leadingIconColor = ElementTheme.colors.iconPrimary,
trailingIconColor = ElementTheme.colors.iconSecondary,
disabledTextColor = ElementTheme.colors.textDisabled,
disabledLeadingIconColor = ElementTheme.colors.iconDisabled,
disabledTrailingIconColor = ElementTheme.colors.iconDisabled,
)
val contentPadding = PaddingValues(all = 12.dp)
}
@Preview(group = PreviewGroup.Menus)
@ -75,10 +84,36 @@ internal fun DropdownMenuItemPreview() = ElementThemedPreview { ContentToPreview
@Composable
private fun ContentToPreview() {
DropdownMenuItem(
text = { DropdownMenuItemText(text = "Item") },
onClick = {},
leadingIcon = { Icon(Icons.Default.BugReport, contentDescription = null) },
trailingIcon = { Icon(Icons.Default.Share, contentDescription = null) },
)
Column {
DropdownMenuItem(
text = { Text(text = "Item") },
onClick = {},
trailingIcon = { Icon(Icons.Default.ArrowRight, contentDescription = null) },
)
Divider()
DropdownMenuItem(
text = { Text(text = "Item") },
onClick = {},
leadingIcon = { Icon(Icons.Default.BugReport, contentDescription = null) },
)
DropdownMenuItem(
text = { Text(text = "Item") },
onClick = {},
leadingIcon = { Icon(Icons.Default.BugReport, contentDescription = null) },
trailingIcon = { Icon(Icons.Default.ArrowRight, contentDescription = null) },
)
DropdownMenuItem(
text = { Text(text = "Item") },
onClick = {},
enabled = false,
leadingIcon = { Icon(Icons.Default.BugReport, contentDescription = null) },
trailingIcon = { Icon(Icons.Default.ArrowRight, contentDescription = null) },
)
Divider()
DropdownMenuItem(
text = { Text(text = "Multiline\nItem") },
onClick = {},
trailingIcon = { Icon(Icons.Default.ArrowRight, contentDescription = null) },
)
}
}

View file

@ -30,8 +30,8 @@ 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.DropdownMenu
import io.element.android.libraries.designsystem.theme.components.DropdownMenuItem
import io.element.android.libraries.designsystem.theme.components.DropdownMenuItemText
import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.theme.components.Text
@Preview(group = PreviewGroup.Menus)
@Composable
@ -57,7 +57,7 @@ internal fun MenuPreview() {
null
}
DropdownMenuItem(
text = { DropdownMenuItemText(text = "Item $i") },
text = { Text(text = "Item $i") },
onClick = { isExpanded = false },
leadingIcon = leadingIcon,
trailingIcon = trailingIcon,

View file

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1765f4842cbd6e3c1b7daa9a9cc13fc0f4c47ff73c2cb1fdd7f3d2377eea0553
size 9053
oid sha256:e425d58f766655f1003c595637ab7387cdf74ba7ae7862bf2f137f3ffd33f3f3
size 21202