For #25119 - Add Secondary, Tertiary and Destructive Button composable components

pull/543/head
Gabriel Luong 2 years ago committed by mergify[bot]
parent 882494ccfb
commit 9a965e420d

@ -4,25 +4,23 @@
package org.mozilla.fenix.compose.button
import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Icon
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@ -31,32 +29,39 @@ import org.mozilla.fenix.theme.FirefoxTheme
import org.mozilla.fenix.theme.Theme
/**
* Primary button.
* Base component for buttons.
*
* @param text The button text to be displayed.
* @param icon Optional button icon to be displayed.
* @param textColor [Color] to apply to the button text.
* @param backgroundColor The background [Color] of the button.
* @param icon Optional [Painter] used to display a [Icon] before the button text.
* @param tint Tint [Color] to be applied to the icon.
* @param onClick Invoked when the user clicks on the button.
*/
@Composable
fun PrimaryButton(
fun Button(
text: String,
textColor: Color,
backgroundColor: Color,
icon: Painter? = null,
tint: Color,
onClick: () -> Unit,
) {
Button(
androidx.compose.material.Button(
onClick = onClick,
modifier = Modifier
.clip(RoundedCornerShape(size = 4.dp))
.fillMaxWidth()
.height(36.dp),
elevation = ButtonDefaults.elevation(defaultElevation = 0.dp, pressedElevation = 0.dp),
colors = ButtonDefaults.outlinedButtonColors(backgroundColor = FirefoxTheme.colors.actionPrimary),
colors = ButtonDefaults.outlinedButtonColors(
backgroundColor = backgroundColor,
),
) {
if (icon != null) {
icon?.let { painter ->
Icon(
painter = icon,
painter = painter,
contentDescription = null,
tint = FirefoxTheme.colors.iconOnColor,
tint = tint,
)
Spacer(modifier = Modifier.width(8.dp))
@ -64,22 +69,137 @@ fun PrimaryButton(
Text(
text = text,
color = FirefoxTheme.colors.textOnColorPrimary,
color = textColor,
fontSize = 14.sp,
fontFamily = FontFamily(Font(R.font.metropolis_semibold)),
letterSpacing = 0.sp,
maxLines = 2
letterSpacing = 0.25.sp,
maxLines = 1,
)
}
}
/**
* Primary button.
*
* @param text The button text to be displayed.
* @param icon Optional [Painter] used to display an [Icon] before the button text.
* @param onClick Invoked when the user clicks on the button.
*/
@Composable
@Preview
private fun PrimaryButtonPreview() {
fun PrimaryButton(
text: String,
icon: Painter? = null,
onClick: () -> Unit,
) {
Button(
text = text,
textColor = FirefoxTheme.colors.textActionPrimary,
backgroundColor = FirefoxTheme.colors.actionPrimary,
icon = icon,
tint = FirefoxTheme.colors.iconActionPrimary,
onClick = onClick,
)
}
/**
* Secondary button.
*
* @param text The button text to be displayed.
* @param icon Optional [Painter] used to display an [Icon] before the button text.
* @param onClick Invoked when the user clicks on the button.
*/
@Composable
fun SecondaryButton(
text: String,
icon: Painter? = null,
onClick: () -> Unit,
) {
Button(
text = text,
textColor = FirefoxTheme.colors.textActionSecondary,
backgroundColor = FirefoxTheme.colors.actionSecondary,
icon = icon,
tint = FirefoxTheme.colors.iconActionSecondary,
onClick = onClick,
)
}
/**
* Tertiary button.
*
* @param text The button text to be displayed.
* @param icon Optional [Painter] used to display an [Icon] before the button text.
* @param onClick Invoked when the user clicks on the button.
*/
@Composable
fun TertiaryButton(
text: String,
icon: Painter? = null,
onClick: () -> Unit,
) {
Button(
text = text,
textColor = FirefoxTheme.colors.textActionTertiary,
backgroundColor = FirefoxTheme.colors.actionTertiary,
icon = icon,
tint = FirefoxTheme.colors.iconActionTertiary,
onClick = onClick,
)
}
/**
* Destructive button.
*
* @param text The button text to be displayed.
* @param icon Optional [Painter] used to display an [Icon] before the button text.
* @param onClick Invoked when the user clicks on the button.
*/
@Composable
fun DestructiveButton(
text: String,
icon: Painter? = null,
onClick: () -> Unit,
) {
Button(
text = text,
textColor = FirefoxTheme.colors.textWarningButton,
backgroundColor = FirefoxTheme.colors.actionSecondary,
icon = icon,
tint = FirefoxTheme.colors.iconWarningButton,
onClick = onClick,
)
}
@Composable
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
private fun ButtonPreview() {
FirefoxTheme(theme = Theme.getTheme(isPrivate = false)) {
Box(Modifier.background(FirefoxTheme.colors.layer1)) {
Column(
modifier = Modifier
.background(FirefoxTheme.colors.layer1)
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
PrimaryButton(
text = stringResource(R.string.recent_tabs_show_all),
text = "Label",
icon = painterResource(R.drawable.ic_tab_collection),
onClick = {},
)
SecondaryButton(
text = "Label",
icon = painterResource(R.drawable.ic_tab_collection),
onClick = {},
)
TertiaryButton(
text = "Label",
icon = painterResource(R.drawable.ic_tab_collection),
onClick = {},
)
DestructiveButton(
text = "Label",
icon = painterResource(R.drawable.ic_tab_collection),
onClick = {},
)

@ -20,17 +20,13 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Card
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@ -40,6 +36,7 @@ import org.mozilla.fenix.R
import org.mozilla.fenix.compose.PrimaryText
import org.mozilla.fenix.compose.SecondaryText
import org.mozilla.fenix.compose.ThumbnailCard
import org.mozilla.fenix.compose.button.Button
import org.mozilla.fenix.home.recentsyncedtabs.RecentSyncedTab
import org.mozilla.fenix.theme.FirefoxTheme
import org.mozilla.fenix.theme.Theme
@ -134,30 +131,20 @@ fun RecentSyncedTab(
Spacer(modifier = Modifier.height(32.dp))
Button(
text = if (tab != null) {
stringResource(R.string.recent_tabs_see_all_synced_tabs_button_text)
} else {
""
},
textColor = FirefoxTheme.colors.textActionSecondary,
backgroundColor = if (tab == null) {
FirefoxTheme.colors.layer3
} else {
FirefoxTheme.colors.actionSecondary
},
tint = FirefoxTheme.colors.iconActionSecondary,
onClick = onSeeAllSyncedTabsButtonClick,
colors = ButtonDefaults.outlinedButtonColors(
backgroundColor = if (tab == null) {
FirefoxTheme.colors.layer3
} else {
FirefoxTheme.colors.actionSecondary
}
),
elevation = ButtonDefaults.elevation(
defaultElevation = 0.dp,
pressedElevation = 0.dp
),
modifier = Modifier
.height(36.dp)
.fillMaxWidth()
) {
if (tab != null) {
Text(
text = stringResource(R.string.recent_tabs_see_all_synced_tabs_button_text),
textAlign = TextAlign.Center,
color = FirefoxTheme.colors.textActionSecondary
)
}
}
)
}
}
}

@ -7,28 +7,17 @@ package org.mozilla.fenix.home.sessioncontrol.viewholders
import android.view.View
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Button
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.ButtonDefaults.outlinedButtonColors
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.lifecycle.LifecycleOwner
import org.mozilla.fenix.R
import org.mozilla.fenix.compose.ComposeViewHolder
import org.mozilla.fenix.compose.button.TertiaryButton
import org.mozilla.fenix.home.sessioncontrol.CustomizeHomeIteractor
import org.mozilla.fenix.theme.FirefoxTheme
import org.mozilla.fenix.theme.Theme
class CustomizeHomeButtonViewHolder(
composeView: ComposeView,
@ -40,56 +29,21 @@ class CustomizeHomeButtonViewHolder(
val LAYOUT_ID = View.generateViewId()
}
init {
val horizontalPadding =
composeView.resources.getDimensionPixelSize(R.dimen.home_item_horizontal_margin)
composeView.setPadding(horizontalPadding, 0, horizontalPadding, 0)
}
@Composable
override fun Content() {
Column {
Spacer(modifier = Modifier.height(68.dp))
CustomizeHomeButton(
onButtonClick = { interactor.openCustomizeHomePage() }
TertiaryButton(
text = stringResource(R.string.browser_menu_customize_home_1),
onClick = interactor::openCustomizeHomePage,
)
}
}
}
/**
* A "Customize homepage" button.
*
* @param onButtonClick Invoked when the user clicks on the button.
*/
@Composable
fun CustomizeHomeButton(
onButtonClick: () -> Unit
) {
Button(
onClick = { onButtonClick() },
modifier = Modifier
.padding(horizontal = 16.dp)
.fillMaxWidth()
.height(36.dp),
elevation = ButtonDefaults.elevation(defaultElevation = 0.dp, pressedElevation = 0.dp),
colors = outlinedButtonColors(
backgroundColor = FirefoxTheme.colors.actionTertiary,
contentColor = FirefoxTheme.colors.textActionTertiary
)
) {
Text(
text = stringResource(R.string.browser_menu_customize_home_1),
fontSize = 14.sp,
fontFamily = FontFamily(Font(R.font.metropolis_semibold)),
letterSpacing = 0.5.sp,
lineHeight = 16.sp,
maxLines = 1
)
}
}
@Composable
@Preview
fun CustomizeHomeButtonPreview() {
FirefoxTheme(theme = Theme.getTheme(isPrivate = false)) {
CustomizeHomeButton(
onButtonClick = {}
)
}
}

@ -132,6 +132,7 @@ private val privateColorPalette = FirefoxColors(
iconAccentYellow = PhotonColors.Yellow20,
iconActionPrimary = PhotonColors.LightGrey05,
iconActionSecondary = PhotonColors.DarkGrey90,
iconActionTertiary = PhotonColors.LightGrey05,
iconGradientStart = PhotonColors.Violet20,
iconGradientEnd = PhotonColors.Blue20,
borderPrimary = PhotonColors.DarkGrey05,
@ -197,6 +198,7 @@ private val darkColorPalette = FirefoxColors(
iconAccentYellow = PhotonColors.Yellow20,
iconActionPrimary = PhotonColors.LightGrey05,
iconActionSecondary = PhotonColors.DarkGrey90,
iconActionTertiary = PhotonColors.LightGrey05,
iconGradientStart = PhotonColors.Violet20,
iconGradientEnd = PhotonColors.Blue20,
borderPrimary = PhotonColors.DarkGrey05,
@ -262,6 +264,7 @@ private val lightColorPalette = FirefoxColors(
iconAccentYellow = PhotonColors.Yellow60,
iconActionPrimary = PhotonColors.LightGrey05,
iconActionSecondary = PhotonColors.DarkGrey90,
iconActionTertiary = PhotonColors.DarkGrey90,
iconGradientStart = PhotonColors.Violet50,
iconGradientEnd = PhotonColors.Blue60,
borderPrimary = PhotonColors.LightGrey30,
@ -332,6 +335,7 @@ class FirefoxColors(
iconAccentYellow: Color,
iconActionPrimary: Color,
iconActionSecondary: Color,
iconActionTertiary: Color,
iconGradientStart: Color,
iconGradientEnd: Color,
borderPrimary: Color,
@ -507,6 +511,9 @@ class FirefoxColors(
// Action secondary icon
var iconActionSecondary by mutableStateOf(iconActionSecondary)
private set
// Action tertiary icon
var iconActionTertiary by mutableStateOf(iconActionTertiary)
private set
// Reader, ETP Shield
var iconGradientStart by mutableStateOf(iconGradientStart)
private set
@ -590,6 +597,7 @@ class FirefoxColors(
iconAccentYellow = other.iconAccentYellow
iconActionPrimary = other.iconActionPrimary
iconActionSecondary = other.iconActionSecondary
iconActionTertiary = other.iconActionTertiary
iconGradientStart = other.iconGradientStart
iconGradientEnd = other.iconGradientEnd
borderPrimary = other.borderPrimary
@ -655,6 +663,7 @@ class FirefoxColors(
iconAccentYellow = iconAccentYellow,
iconActionPrimary = iconActionPrimary,
iconActionSecondary = iconActionSecondary,
iconActionTertiary = iconActionTertiary,
iconGradientStart = iconGradientStart,
iconGradientEnd = iconGradientEnd,
borderPrimary = borderPrimary,

@ -107,6 +107,8 @@
<color name="fx_mobile_icon_color_action_primary" tools:ignore="UnusedResources">@color/photonLightGrey05</color>
<!-- Action Secondary Icon -->
<color name="fx_mobile_icon_color_action_secondary">@color/photonDarkGrey90</color>
<!-- Action Tertiary Icon -->
<color name="fx_mobile_icon_color_action_tertiary" tools:ignore="UnusedResources">@color/photonLightGrey05</color>
<!-- Reader, ETP Shield -->
<color name="fx_mobile_icon_color_gradient_start">@color/photonViolet20</color>
<!-- Reader, ETP Shield -->

@ -107,6 +107,8 @@
<color name="fx_mobile_icon_color_action_primary" tools:ignore="UnusedResources">@color/photonLightGrey05</color>
<!-- Action Secondary Icon -->
<color name="fx_mobile_icon_color_action_secondary">@color/photonDarkGrey90</color>
<!-- Action Tertiary Icon -->
<color name="fx_mobile_icon_color_action_tertiary" tools:ignore="UnusedResources">@color/photonDarkGrey90</color>
<!-- Reader, ETP Shield -->
<color name="fx_mobile_icon_color_gradient_start">@color/photonViolet50</color>
<!-- Reader, ETP Shield -->
@ -232,6 +234,12 @@
<color name="fx_mobile_private_icon_color_accent_pink" tools:ignore="UnusedResources">@color/photonPink20</color>
<color name="fx_mobile_private_icon_color_accent_green" tools:ignore="UnusedResources">@color/photonGreen20</color>
<color name="fx_mobile_private_icon_color_accent_yellow" tools:ignore="UnusedResources">@color/photonYellow20</color>
<!-- Action Primary Icon -->
<color name="fx_mobile_private_icon_color_action_primary" tools:ignore="UnusedResources">@color/photonLightGrey05</color>
<!-- Action Secondary Icon -->
<color name="fx_mobile_private_icon_color_action_secondary" tools:ignore="UnusedResources">@color/photonDarkGrey90</color>
<!-- Action Tertiary Icon -->
<color name="fx_mobile_private_icon_color_action_tertiary" tools:ignore="UnusedResources">@color/photonLightGrey05</color>
<!-- Reader, ETP Shield -->
<color name="fx_mobile_private_icon_color_gradient_start" tools:ignore="UnusedResources">@color/photonViolet20</color>
<!-- Reader, ETP Shield -->

Loading…
Cancel
Save