Skip to content

Commit

Permalink
Merge pull request #47 from mori-atsushi/state
Browse files Browse the repository at this point in the history
Add enabled / pressed / focused styles for Button
  • Loading branch information
mori-atsushi authored Nov 24, 2023
2 parents 3d004d1 + e4834db commit 73cdaa9
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package com.moriatsushi.compose.stylesheet.button

import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.collectIsFocusedAsState
import androidx.compose.foundation.interaction.collectIsHoveredAsState
import androidx.compose.foundation.interaction.collectIsPressedAsState
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
Expand All @@ -28,6 +30,7 @@ import com.moriatsushi.compose.stylesheet.tag.TagModifier
fun Button(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
tags: TagModifier<ButtonStyle> = TagModifier(),
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
buttonStyle: ButtonStyle = ButtonStyle.Default,
Expand All @@ -39,7 +42,14 @@ fun Button(
this += buttonStyle
}
val isPressed by interactionSource.collectIsPressedAsState()
val stateStyle = mergedStyle.getStyleForState(isPressed = isPressed)
val isHovered by interactionSource.collectIsHoveredAsState()
val isFocused by interactionSource.collectIsFocusedAsState()
val stateStyle = mergedStyle.getStyleForState(
isEnabled = enabled,
isPressed = isPressed,
isHovered = isHovered,
isFocused = isFocused,
)

Row(
modifier = modifier
Expand All @@ -49,6 +59,7 @@ fun Button(
interactionSource = interactionSource,
indication = mergedStyle.indication?.value,
onClick = onClick,
enabled = enabled,
)
.componentPadding(stateStyle.commonStyle.padding),
horizontalArrangement = Arrangement.Center,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ sealed interface ButtonStyle : ComponentStyle {
val indication: IndicationStyle?
val contentStyle: ContentStyle
val pressedStyle: ButtonStateStyle
val hoveredStyle: ButtonStateStyle
val focusedStyle: ButtonStateStyle
val disabledStyle: ButtonStateStyle

companion object {
/**
Expand All @@ -34,24 +37,45 @@ internal fun ButtonStyle(
commonStyle: ComponentCommonStyle = ComponentCommonStyle.Default,
contentStyle: ContentStyle = ContentStyle.Default,
pressedStyle: ButtonStateStyle = ButtonStateStyle.Default,
hoveredStyle: ButtonStateStyle = ButtonStateStyle.Default,
focusedStyle: ButtonStateStyle = ButtonStateStyle.Default,
disabledStyle: ButtonStateStyle = ButtonStateStyle.Default,
): ButtonStyle = ButtonStyleImpl(
indication = indication,
commonStyle = commonStyle,
contentStyle = contentStyle,
pressedStyle = pressedStyle,
hoveredStyle = hoveredStyle,
focusedStyle = focusedStyle,
disabledStyle = disabledStyle,
)

internal fun ButtonStyle.getStyleForState(
isEnabled: Boolean,
isPressed: Boolean,
isHovered: Boolean,
isFocused: Boolean,
): ButtonStateStyle {
val buttonStyle = this
return ButtonStateStyle {
this += buttonStyle.commonStyle
content += buttonStyle.contentStyle

if (isFocused) {
this += buttonStyle.focusedStyle
}

if (isHovered) {
this += buttonStyle.hoveredStyle
}

if (isPressed) {
this += buttonStyle.pressedStyle
}

if (!isEnabled) {
this += buttonStyle.disabledStyle
}
}
}

Expand All @@ -61,4 +85,7 @@ private data class ButtonStyleImpl(
override val commonStyle: ComponentCommonStyle,
override val contentStyle: ContentStyle,
override val pressedStyle: ButtonStateStyle,
override val hoveredStyle: ButtonStateStyle,
override val focusedStyle: ButtonStateStyle,
override val disabledStyle: ButtonStateStyle,
) : ButtonStyle
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import com.moriatsushi.compose.stylesheet.indication.IndicationSetter
@StyleSheetBuilderMarker
class ButtonStyleBuilder internal constructor() : ComponentStyleBuilder<ButtonStyle>() {
private val pressedStyleBuilder = ButtonStateStyleBuilder()
private val hoveredStyleBuilder = ButtonStateStyleBuilder()
private val focusedStyleBuilder = ButtonStateStyleBuilder()
private val disabledStyleBuilder = ButtonStateStyleBuilder()

/**
* An indication representing visual effects that occur when certain interactions happen, such
Expand Down Expand Up @@ -43,17 +46,44 @@ class ButtonStyleBuilder internal constructor() : ComponentStyleBuilder<ButtonSt
pressedStyleBuilder.builder()
}

/**
* Defines hovered styles.
*/
fun hovered(builder: ButtonStateStyleBuilder.() -> Unit) {
hoveredStyleBuilder.builder()
}

/**
* Defines focused styles.
*/
fun focused(builder: ButtonStateStyleBuilder.() -> Unit) {
focusedStyleBuilder.builder()
}

/**
* Defines disabled styles.
*/
fun disabled(builder: ButtonStateStyleBuilder.() -> Unit) {
disabledStyleBuilder.builder()
}

override fun plusAssign(other: ButtonStyle) {
indication += other.indication
this += other.commonStyle
content += other.contentStyle
pressedStyleBuilder += other.pressedStyle
hoveredStyleBuilder += other.hoveredStyle
focusedStyleBuilder += other.focusedStyle
disabledStyleBuilder += other.disabledStyle
}

override fun build(): ButtonStyle = ButtonStyle(
indication = indication.value,
commonStyle = buildCommonStyle(),
contentStyle = content.build(),
pressedStyle = pressedStyleBuilder.build(),
hoveredStyle = hoveredStyleBuilder.build(),
focusedStyle = focusedStyleBuilder.build(),
disabledStyle = disabledStyleBuilder.build(),
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ fun themeStyleSheet(
Colors.semantic.inverseSurfacePressed += if (useDarkMode) Colors.gray300 else Colors.gray600
Colors.semantic.onInverseSurface += if (useDarkMode) Colors.gray900 else Colors.white

Colors.semantic.disabledSurface += if (useDarkMode) Colors.gray700 else Colors.gray100
Colors.semantic.onDisabledSurface += if (useDarkMode) Colors.gray500 else Colors.gray300

content {
color += Colors.semantic.onBackground
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,10 @@ internal val buttonStyleSheet = StyleSheet {
pressed {
background += Colors.semantic.inverseSurfacePressed
}

disabled {
background += Colors.semantic.disabledSurface
content.color += Colors.semantic.onDisabledSurface
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,7 @@ class SemanticColors internal constructor() {
val inverseSurface = Token("color.semantic.inverseSurface", Colors.gray900)
val inverseSurfacePressed = Token("color.semantic.inverseSurfacePressed", Colors.gray700)
val onInverseSurface = Token("color.semantic.onInverseSurface", Colors.gray50)

val disabledSurface = Token("color.semantic.inverseSurfacePressed", Colors.gray100)
val onDisabledSurface = Token("color.semantic.onInverseSurface", Colors.gray300)
}

0 comments on commit 73cdaa9

Please sign in to comment.