From 53e80e6b5ddcdc3d8e94e506cf04419ace87a7e9 Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Fri, 11 Aug 2023 15:09:51 +0200 Subject: [PATCH] [Compound] Implement DropdownMenu customisations. (#1050) * Compound: implement `DropdownMenu` customisations. * Update screenshots * Add changelog * Address review comments --------- Co-authored-by: ElementBot --- changelog.d/1050.misc | 1 + .../roomdetails/impl/RoomDetailsView.kt | 3 +- .../impl/components/RoomListTopBar.kt | 5 +- .../theme/components/DropdownMenu.kt | 12 ++- .../theme/components/DropdownMenuItem.kt | 81 +++++++++++++------ .../theme/components/previews/MenuPreview.kt | 4 +- ...MenuItemPreview_0_null,NEXUS_5,1.0,en].png | 4 +- 7 files changed, 71 insertions(+), 39 deletions(-) create mode 100644 changelog.d/1050.misc diff --git a/changelog.d/1050.misc b/changelog.d/1050.misc new file mode 100644 index 0000000000..5a32d00d15 --- /dev/null +++ b/changelog.d/1050.misc @@ -0,0 +1 @@ +Compound: implement `DropdownMenu` customisations. diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt index 3ec597e525..51754ca6de 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt @@ -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. diff --git a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt index c144ef8671..001c048e4e 100644 --- a/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt +++ b/features/roomlist/impl/src/main/kotlin/io/element/android/features/roomlist/impl/components/RoomListTopBar.kt @@ -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, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/DropdownMenu.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/DropdownMenu.kt index 175c0fb402..c0160bb7f8 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/DropdownMenu.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/DropdownMenu.kt @@ -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 diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/DropdownMenuItem.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/DropdownMenuItem.kt index b8c18f99c6..f8e0fc2b78 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/DropdownMenuItem.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/DropdownMenuItem.kt @@ -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) }, + ) + } } diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/previews/MenuPreview.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/previews/MenuPreview.kt index 8e7da6926e..2ca04f1008 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/previews/MenuPreview.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/previews/MenuPreview.kt @@ -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, diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Menus_DropdownMenuItemPreview_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Menus_DropdownMenuItemPreview_0_null,NEXUS_5,1.0,en].png index 4c91805426..305257631f 100644 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Menus_DropdownMenuItemPreview_0_null,NEXUS_5,1.0,en].png +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.theme.components_null_Menus_DropdownMenuItemPreview_0_null,NEXUS_5,1.0,en].png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1765f4842cbd6e3c1b7daa9a9cc13fc0f4c47ff73c2cb1fdd7f3d2377eea0553 -size 9053 +oid sha256:e425d58f766655f1003c595637ab7387cdf74ba7ae7862bf2f137f3ffd33f3f3 +size 21202