andrew
11/07/2022, 3:38 AMandrew
11/07/2022, 3:38 AMsealed interface Button {
sealed interface Filled : Button {
object Primary : Filled
object Secondary : Filled
// object Success : Filled
// object Warn : Filled
}
sealed interface Outlined : Button {
object Primary : Outlined
object Secondary : Outlined
// object Success : Filled
// object Warn : Filled
}
sealed interface Text : Button {
object Primary : Text
object Secondary : Text
// object Success : Filled
// object Warn : Filled
}
@Composable
operator fun invoke(
onClick: () -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
content: @Composable RowScope.() -> Unit,
) {
val indication = rememberRipple(true, color = LocalContentColor.current)
CompositionLocalProvider(
LocalContentColor provides contentColor,
LocalTextStyle provides Typography.mediumStrong,
LocalIconSize provides 20.dp,
) {
Row(
modifier = Modifier
.clickable(
interactionSource = interactionSource,
indication = indication,
enabled = enabled,
role = Role.Button,
onClick = onClick,
)
.background(backgroundColor)
.height(40.dp)
.padding(16.dp, 0.dp)
.then(modifier),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Center,
) {
content()
}
}
}
private val contentColor
@Composable
@ReadOnlyComposable
get() = when (this) {
is Filled -> Color.White
is Outlined.Primary, is Text.Primary -> Theme.colors.primary
is Outlined.Secondary, is Text.Secondary -> LocalContentColor.current
}
private val backgroundColor
@Composable
@ReadOnlyComposable
get() = when (this) {
is Filled.Primary -> Theme.colors.primary
is Filled.Secondary -> Theme.colors.primary.copy(ContentAlpha.secondary)
else -> Color.Transparent
}
}
andrew
11/07/2022, 3:39 AMandrew
11/07/2022, 3:41 AMephemient
11/07/2022, 3:51 AMsealed
ephemient
11/07/2022, 3:51 AMandrew
11/07/2022, 4:04 AMandrew
11/07/2022, 4:06 AMandrew
11/07/2022, 4:20 AMKevin Del Castillo
11/07/2022, 1:44 PMcontentColor
and backgroundColor
andrew
11/07/2022, 4:34 PMandrew
11/07/2022, 4:34 PMandrew
11/07/2022, 4:35 PMKevin Del Castillo
11/07/2022, 4:42 PMButton
Composable, you've already reducing the amount of parameters needed by defining the styleandrew
11/07/2022, 4:44 PMandrew
11/07/2022, 4:45 PMKevin Del Castillo
11/07/2022, 4:46 PMKevin Del Castillo
11/07/2022, 4:47 PMandrew
11/07/2022, 4:49 PMandrew
11/07/2022, 4:52 PMandrew
11/07/2022, 4:53 PMandrew
11/07/2022, 4:54 PMKevin Del Castillo
11/07/2022, 5:00 PMButtonStyle
that contains the allowed styles, each style returns the properties used in the top composable function called Button
for example:
@Composable
fun Button(
modifier: Modifier = Modifier,
style: ButtonStyle,
// ...
) {
val isPressed = // ...
val foregroundColor = style.foregroundColor(isPressed)
// ....
}
Here for example each style overrides the foregroundColor
composable function that returns a different State<Color>
depending on whether the button is pressed or not, similar to what you did with the accessors, so I'm not saying your approach is wrong at all, what doesn't convince is the override of the invoke
operator, that's allandrew
11/07/2022, 5:02 PMKevin Del Castillo
11/07/2022, 5:05 PMinvoke
operator doesn't convince me is that it's a bit obscure to use as part of a defined interface and its objects, while using a top function is clearer in this contextephemient
11/07/2022, 5:06 PMthis
) that isn't explicitly passed in.ephemient
11/07/2022, 5:07 PMandrew
11/07/2022, 5:08 PMandrew
11/07/2022, 5:08 PMephemient
11/07/2022, 5:09 PMsealed class
instead of a sealed interface
, but it's still not standard practicesandrew
11/07/2022, 5:09 PM@Composable
with @ReadOnlyComposable
andrew
11/07/2022, 5:09 PMephemient
11/07/2022, 5:09 PMandrew
11/07/2022, 5:10 PMephemient
11/07/2022, 5:13 PMKevin Del Castillo
11/07/2022, 5:15 PMSwitch
composable with SwitchColors
: https://cs.android.com/androidx/platform/tools/dokka-devsite-plugin/+/master:testData/compose/source/androidx/compose/material/Switch.kt?q=Switchandrew
11/07/2022, 5:17 PMandrew
11/07/2022, 5:21 PMephemient
11/08/2022, 2:38 AMephemient
11/08/2022, 2:44 AMandrew
11/08/2022, 2:56 AMephemient
11/08/2022, 3:23 AM@Immutable class SwitchColors internal constructor
instead of @Stable interface SwitchColors; @Immutable private class DefaultSwitchColors(...) : SwitchColors
. what you linked looks closer to the m2 implementation (which is still elsewhere in that repo). maybe there were other factors at play but the way m3 works looks clearly better to me for this usageandrew
11/08/2022, 7:05 PMandrew
11/08/2022, 7:06 PMephemient
11/09/2022, 10:57 AMandrew
11/09/2022, 3:42 PMandrew
11/09/2022, 3:43 PM