Skip to content

Instantly share code, notes, and snippets.

@go-cristian
Created November 17, 2021 13:53
Show Gist options
  • Save go-cristian/c3fa893581ed48393077abc3e5ccca25 to your computer and use it in GitHub Desktop.
Save go-cristian/c3fa893581ed48393077abc3e5ccca25 to your computer and use it in GitHub Desktop.
@Composable
fun SelectionPill(
option: ToggleButtonOption,
selected: Boolean,
onClick: (option: ToggleButtonOption) -> Unit = {}
) {
Button(
onClick = { onClick(option) },
colors = ButtonDefaults.buttonColors(
backgroundColor = MaterialTheme.colors.background,
),
shape = RoundedCornerShape(0),
elevation = ButtonDefaults.elevation(0.dp, 0.dp),
contentPadding = PaddingValues(0.dp),
modifier = Modifier.padding(14.dp, 0.dp),
) {
Row(
modifier = Modifier.padding(0.dp),
verticalAlignment = Alignment.Bottom,
) {
Title5(
text = option.text,
color = if (selected) highlighted() else nonHighlighted(),
modifier = Modifier.padding(0.dp),
)
if (option.iconRes != null) {
Icon(
painterResource(id = option.iconRes),
contentDescription = null,
tint = if (selected) highlighted() else nonHighlighted(),
modifier = Modifier.padding(4.dp, 2.dp, 2.dp, 2.dp),
)
}
}
}
}
enum class SelectionType {
NONE,
SINGLE,
MULTIPLE,
}
data class ToggleButtonOption(
val text: String,
val iconRes: Int?,
)
@Composable
fun ToggleButton(
options: Array<ToggleButtonOption>,
modifier: Modifier = Modifier,
type: SelectionType = SelectionType.SINGLE,
onClick: (selectedOptions: Array<ToggleButtonOption>) -> Unit = {},
) {
val state = remember { mutableStateMapOf<String, ToggleButtonOption>() }
OutlinedButton(
onClick = { },
border = BorderStroke(1.dp, nonHighlighted()),
shape = RoundedCornerShape(50),
colors = ButtonDefaults.outlinedButtonColors(contentColor = nonHighlighted()),
contentPadding = PaddingValues(0.dp, 0.dp),
modifier = modifier
.padding(0.dp)
.height(52.dp),
) {
if (options.isEmpty()) {
return@OutlinedButton
}
val onItemClick: (option: ToggleButtonOption) -> Unit = { option ->
if (type == SelectionType.SINGLE) {
options.forEach {
val key = it.text
if (key == option.text) {
state[key] = option
} else {
state.remove(key)
}
}
} else {
val key = option.text
if (!state.contains(key)) {
state[key] = option
} else {
state.remove(key)
}
}
onClick(state.values.toTypedArray())
}
if (options.size == 1) {
val option = options.first()
SelectionPill(
option = option,
selected = state.contains(option.text),
onClick = onItemClick,
)
return@OutlinedButton
}
val first = options.first()
val last = options.last()
val middle = options.slice(1..options.size - 2)
SelectionPill(
option = first,
selected = state.contains(first.text),
onClick = onItemClick,
)
VerticalDivider()
middle.map { option ->
SelectionPill(
option = option,
selected = state.contains(option.text),
onClick = onItemClick,
)
VerticalDivider()
}
SelectionPill(
option = last,
selected = state.contains(last.text),
onClick = onItemClick,
)
}
}
@Composable
fun VerticalDivider() {
Divider(
modifier = Modifier
.fillMaxHeight()
.width(2.dp)
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment