forked from mirrors/gecko-dev
Bug 1891342 - Part 4: Implement enabled, disabled, active and warning states for MenuItem r=android-reviewers,007
Differential Revision: https://phabricator.services.mozilla.com/D207394
This commit is contained in:
parent
1be42fab76
commit
3ba1aab119
2 changed files with 165 additions and 11 deletions
|
|
@ -125,32 +125,32 @@ private fun LibraryMenuGroup(
|
||||||
MenuGroup {
|
MenuGroup {
|
||||||
MenuItem(
|
MenuItem(
|
||||||
label = stringResource(id = R.string.library_bookmarks),
|
label = stringResource(id = R.string.library_bookmarks),
|
||||||
onClick = onBookmarksMenuClick,
|
|
||||||
beforeIconPainter = painterResource(id = R.drawable.mozac_ic_bookmark_tray_fill_24),
|
beforeIconPainter = painterResource(id = R.drawable.mozac_ic_bookmark_tray_fill_24),
|
||||||
|
onClick = onBookmarksMenuClick,
|
||||||
)
|
)
|
||||||
|
|
||||||
Divider(color = FirefoxTheme.colors.borderSecondary)
|
Divider(color = FirefoxTheme.colors.borderSecondary)
|
||||||
|
|
||||||
MenuItem(
|
MenuItem(
|
||||||
label = stringResource(id = R.string.library_history),
|
label = stringResource(id = R.string.library_history),
|
||||||
onClick = onHistoryMenuClick,
|
|
||||||
beforeIconPainter = painterResource(id = R.drawable.mozac_ic_history_24),
|
beforeIconPainter = painterResource(id = R.drawable.mozac_ic_history_24),
|
||||||
|
onClick = onHistoryMenuClick,
|
||||||
)
|
)
|
||||||
|
|
||||||
Divider(color = FirefoxTheme.colors.borderSecondary)
|
Divider(color = FirefoxTheme.colors.borderSecondary)
|
||||||
|
|
||||||
MenuItem(
|
MenuItem(
|
||||||
label = stringResource(id = R.string.library_downloads),
|
label = stringResource(id = R.string.library_downloads),
|
||||||
onClick = onDownloadsMenuClick,
|
|
||||||
beforeIconPainter = painterResource(id = R.drawable.mozac_ic_download_24),
|
beforeIconPainter = painterResource(id = R.drawable.mozac_ic_download_24),
|
||||||
|
onClick = onDownloadsMenuClick,
|
||||||
)
|
)
|
||||||
|
|
||||||
Divider(color = FirefoxTheme.colors.borderSecondary)
|
Divider(color = FirefoxTheme.colors.borderSecondary)
|
||||||
|
|
||||||
MenuItem(
|
MenuItem(
|
||||||
label = stringResource(id = R.string.browser_menu_passwords),
|
label = stringResource(id = R.string.browser_menu_passwords),
|
||||||
onClick = onPasswordsMenuClick,
|
|
||||||
beforeIconPainter = painterResource(id = R.drawable.mozac_ic_login_24),
|
beforeIconPainter = painterResource(id = R.drawable.mozac_ic_login_24),
|
||||||
|
onClick = onPasswordsMenuClick,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,39 +4,56 @@
|
||||||
|
|
||||||
package org.mozilla.fenix.components.menu.compose
|
package org.mozilla.fenix.components.menu.compose
|
||||||
|
|
||||||
|
import androidx.compose.foundation.background
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material.Icon
|
import androidx.compose.material.Icon
|
||||||
import androidx.compose.material.IconButton
|
import androidx.compose.material.IconButton
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.painter.Painter
|
import androidx.compose.ui.graphics.painter.Painter
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import org.mozilla.fenix.R
|
||||||
|
import org.mozilla.fenix.compose.Divider
|
||||||
|
import org.mozilla.fenix.compose.annotation.LightDarkPreview
|
||||||
import org.mozilla.fenix.compose.list.IconListItem
|
import org.mozilla.fenix.compose.list.IconListItem
|
||||||
import org.mozilla.fenix.theme.FirefoxTheme
|
import org.mozilla.fenix.theme.FirefoxTheme
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper around [IconListItem] for menu items that appear in a [MenuGroup].
|
* An [IconListItem] wrapper for menu items in a [MenuGroup] with an optional icon at the end.
|
||||||
*
|
*
|
||||||
* @param label The label in the list item.
|
* @param label The label in the menu item.
|
||||||
* @param description An optional description text below the label.
|
|
||||||
* @param onClick Invoked when the user clicks on the item.
|
|
||||||
* @param beforeIconPainter [Painter] used to display an [Icon] before the list item.
|
* @param beforeIconPainter [Painter] used to display an [Icon] before the list item.
|
||||||
* @param beforeIconDescription Content description of the icon.
|
* @param beforeIconDescription Content description of the icon.
|
||||||
|
* @param description An optional description text below the label.
|
||||||
|
* @param state The state of the menu item to display.
|
||||||
|
* @param onClick Invoked when the user clicks on the item.
|
||||||
* @param afterIconPainter [Painter] used to display an [IconButton] after the list item.
|
* @param afterIconPainter [Painter] used to display an [IconButton] after the list item.
|
||||||
* @param afterIconDescription Content description of the icon.
|
* @param afterIconDescription Content description of the icon.
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
internal fun MenuItem(
|
internal fun MenuItem(
|
||||||
label: String,
|
label: String,
|
||||||
description: String? = null,
|
|
||||||
onClick: (() -> Unit)? = null,
|
|
||||||
beforeIconPainter: Painter,
|
beforeIconPainter: Painter,
|
||||||
beforeIconDescription: String? = null,
|
beforeIconDescription: String? = null,
|
||||||
|
description: String? = null,
|
||||||
|
state: MenuItemState = MenuItemState.ENABLED,
|
||||||
|
onClick: (() -> Unit)? = null,
|
||||||
afterIconPainter: Painter? = null,
|
afterIconPainter: Painter? = null,
|
||||||
afterIconDescription: String? = null,
|
afterIconDescription: String? = null,
|
||||||
) {
|
) {
|
||||||
val iconTint = FirefoxTheme.colors.iconSecondary
|
val labelTextColor = getLabelTextColor(state = state)
|
||||||
|
val iconTint = getIconTint(state = state)
|
||||||
|
val enabled = state != MenuItemState.DISABLED
|
||||||
|
|
||||||
IconListItem(
|
IconListItem(
|
||||||
label = label,
|
label = label,
|
||||||
|
labelTextColor = labelTextColor,
|
||||||
description = description,
|
description = description,
|
||||||
|
enabled = enabled,
|
||||||
onClick = onClick,
|
onClick = onClick,
|
||||||
beforeIconPainter = beforeIconPainter,
|
beforeIconPainter = beforeIconPainter,
|
||||||
beforeIconDescription = beforeIconDescription,
|
beforeIconDescription = beforeIconDescription,
|
||||||
|
|
@ -46,3 +63,140 @@ internal fun MenuItem(
|
||||||
afterIconTint = iconTint,
|
afterIconTint = iconTint,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An [IconListItem] wrapper for menu items in a [MenuGroup] with an optional text button at the end.
|
||||||
|
*
|
||||||
|
* @param label The label in the menu item.
|
||||||
|
* @param beforeIconPainter [Painter] used to display an [Icon] before the list item.
|
||||||
|
* @param beforeIconDescription Content description of the icon.
|
||||||
|
* @param description An optional description text below the label.
|
||||||
|
* @param state The state of the menu item to display.
|
||||||
|
* @param onClick Invoked when the user clicks on the item.
|
||||||
|
* @param afterButtonText The button text to be displayed after the list item.
|
||||||
|
* @param afterButtonTextColor [Color] to apply to [afterButtonText].
|
||||||
|
* @param onAfterButtonClick Called when the user clicks on the text button.
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
internal fun MenuItem(
|
||||||
|
label: String,
|
||||||
|
beforeIconPainter: Painter,
|
||||||
|
beforeIconDescription: String? = null,
|
||||||
|
description: String? = null,
|
||||||
|
state: MenuItemState = MenuItemState.ENABLED,
|
||||||
|
onClick: (() -> Unit)? = null,
|
||||||
|
afterButtonText: String? = null,
|
||||||
|
afterButtonTextColor: Color = FirefoxTheme.colors.actionPrimary,
|
||||||
|
onAfterButtonClick: (() -> Unit)? = null,
|
||||||
|
) {
|
||||||
|
val labelTextColor = getLabelTextColor(state = state)
|
||||||
|
val iconTint = getIconTint(state = state)
|
||||||
|
val enabled = state != MenuItemState.DISABLED
|
||||||
|
|
||||||
|
IconListItem(
|
||||||
|
label = label,
|
||||||
|
labelTextColor = labelTextColor,
|
||||||
|
description = description,
|
||||||
|
enabled = enabled,
|
||||||
|
onClick = onClick,
|
||||||
|
beforeIconPainter = beforeIconPainter,
|
||||||
|
beforeIconDescription = beforeIconDescription,
|
||||||
|
beforeIconTint = iconTint,
|
||||||
|
afterButtonText = afterButtonText,
|
||||||
|
afterButtonTextColor = afterButtonTextColor,
|
||||||
|
onAfterButtonClick = onAfterButtonClick,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enum containing all the supported state for the menu item.
|
||||||
|
*/
|
||||||
|
enum class MenuItemState {
|
||||||
|
/**
|
||||||
|
* The menu item is enabled.
|
||||||
|
*/
|
||||||
|
ENABLED,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The menu item is disabled and is not clickable.
|
||||||
|
*/
|
||||||
|
DISABLED,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The menu item is highlighted to indicate the feature behind the menu item is active.
|
||||||
|
*/
|
||||||
|
ACTIVE,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The menu item is highlighted to indicate the feature behind the menu item is destructive.
|
||||||
|
*/
|
||||||
|
WARNING,
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun getLabelTextColor(state: MenuItemState): Color {
|
||||||
|
return when (state) {
|
||||||
|
MenuItemState.ACTIVE -> FirefoxTheme.colors.textAccent
|
||||||
|
MenuItemState.WARNING -> FirefoxTheme.colors.textWarning
|
||||||
|
else -> FirefoxTheme.colors.textPrimary
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun getIconTint(state: MenuItemState): Color {
|
||||||
|
return when (state) {
|
||||||
|
MenuItemState.ACTIVE -> FirefoxTheme.colors.iconAccentViolet
|
||||||
|
MenuItemState.WARNING -> FirefoxTheme.colors.iconWarning
|
||||||
|
else -> FirefoxTheme.colors.iconSecondary
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@LightDarkPreview
|
||||||
|
@Composable
|
||||||
|
private fun MenuItemPreview() {
|
||||||
|
FirefoxTheme {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.background(color = FirefoxTheme.colors.layer3)
|
||||||
|
.padding(16.dp),
|
||||||
|
) {
|
||||||
|
MenuGroup {
|
||||||
|
for (state in MenuItemState.entries) {
|
||||||
|
MenuItem(
|
||||||
|
label = stringResource(id = R.string.browser_menu_translations),
|
||||||
|
beforeIconPainter = painterResource(id = R.drawable.mozac_ic_translate_24),
|
||||||
|
state = state,
|
||||||
|
onClick = {},
|
||||||
|
)
|
||||||
|
|
||||||
|
Divider(color = FirefoxTheme.colors.borderSecondary)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (state in MenuItemState.entries) {
|
||||||
|
MenuItem(
|
||||||
|
label = stringResource(id = R.string.browser_menu_extensions),
|
||||||
|
beforeIconPainter = painterResource(id = R.drawable.mozac_ic_extension_24),
|
||||||
|
state = state,
|
||||||
|
onClick = {},
|
||||||
|
afterIconPainter = painterResource(id = R.drawable.mozac_ic_chevron_right_24),
|
||||||
|
)
|
||||||
|
|
||||||
|
Divider(color = FirefoxTheme.colors.borderSecondary)
|
||||||
|
}
|
||||||
|
|
||||||
|
for (state in MenuItemState.entries) {
|
||||||
|
MenuItem(
|
||||||
|
label = stringResource(id = R.string.library_bookmarks),
|
||||||
|
beforeIconPainter = painterResource(id = R.drawable.mozac_ic_bookmark_tray_fill_24),
|
||||||
|
state = state,
|
||||||
|
onClick = {},
|
||||||
|
afterButtonText = stringResource(id = R.string.browser_menu_edit),
|
||||||
|
onAfterButtonClick = {},
|
||||||
|
)
|
||||||
|
|
||||||
|
Divider(color = FirefoxTheme.colors.borderSecondary)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue