in ui-components/src/commonMain/kotlin/org/jetbrains/kotlinconf/ui/components/Filters.kt [73:176]
fun Filters(
tags: List<FilterItem>,
toggleItem: (FilterItem, Boolean) -> Unit,
modifier: Modifier = Modifier,
) {
var isExpanded by rememberSaveable { mutableStateOf(false) }
Column(
modifier = modifier
.clip(KotlinConfTheme.shapes.roundedCornerMd)
.background(KotlinConfTheme.colors.tileBackground),
) {
val stateDesc = stringResource(
if (isExpanded) UiRes.string.action_state_description_expanded
else UiRes.string.action_state_description_collapsed
)
val filterByTagsText = stringResource(UiRes.string.filter_by_tags)
Row(
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.toggleable(
enabled = true,
value = isExpanded,
onValueChange = { isExpanded = it },
indication = null,
interactionSource = remember { MutableInteractionSource() }
)
.heightIn(min = 46.dp)
.padding(vertical = 11.dp)
.fillMaxWidth()
.semantics {
stateDescription = stateDesc
contentDescription = filterByTagsText
}
) {
val iconRotation by animateFloatAsState(if (isExpanded) 0f else 180f)
Action(
modifier = Modifier.clearAndSetSemantics {},
label = stringResource(UiRes.string.filter_by_tags),
icon = UiRes.drawable.up_24,
size = ActionSize.Medium,
enabled = true,
onClick = { isExpanded = !isExpanded },
iconRotation = iconRotation,
)
val count = remember(tags) { tags.count { it.isSelected } }
AnimatedVisibility(
visible = !isExpanded && count > 0,
enter = fadeIn() + expandHorizontally(clip = false, expandFrom = Alignment.Start),
exit = fadeOut() + shrinkHorizontally(clip = false, shrinkTowards = Alignment.Start),
) {
Row {
Spacer(Modifier.width(8.dp))
Box(
contentAlignment = Alignment.Center,
modifier = Modifier.size(24.dp)
.clip(CircleShape)
.background(KotlinConfTheme.colors.primaryBackground)
) {
val tagCountContentDescription = pluralStringResource(UiRes.plurals.filter_by_tags_tag_count, count, count)
Text(
text = count.toString(),
color = KotlinConfTheme.colors.primaryTextWhiteFixed,
style = KotlinConfTheme.typography.text2,
modifier = Modifier.semantics {
contentDescription = tagCountContentDescription
}
)
}
}
}
}
AnimatedVisibility(
visible = isExpanded,
enter = fadeIn(spring(stiffness = Spring.StiffnessLow)),
exit = fadeOut() + shrinkVertically(clip = false, shrinkTowards = Alignment.Top),
) {
Column(
verticalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier.padding(12.dp),
) {
FilterItemGroup(
title = stringResource(UiRes.string.filter_label_category),
items = remember(tags) { tags.filter { it.type == FilterItemType.Category } },
toggle = toggleItem,
)
FilterItemGroup(
title = stringResource(UiRes.string.filter_label_level),
items = remember(tags) { tags.filter { it.type == FilterItemType.Level } },
toggle = toggleItem,
)
FilterItemGroup(
title = stringResource(UiRes.string.filter_label_session_format),
items = remember(tags) { tags.filter { it.type == FilterItemType.Format } },
toggle = toggleItem,
)
}
}
}
}