Fix AvatarPickerView touch target and disabled state

- Make edit button clickable for better touch accessibility
- Hide edit button and erase background when disabled
- Extract interactionSource to share between clickable areas
This commit is contained in:
ganfra 2026-01-23 12:11:51 +01:00
parent deb340daba
commit 4a43076fc2

View file

@ -78,18 +78,19 @@ fun AvatarPickerView(
enabled: Boolean = true, enabled: Boolean = true,
) { ) {
val a11yAvatar = stringResource(CommonStrings.a11y_avatar) val a11yAvatar = stringResource(CommonStrings.a11y_avatar)
val interactionSource = remember { MutableInteractionSource() }
val clickableModifier = Modifier.clickable( val clickableModifier = Modifier
enabled = enabled, .clickable(
interactionSource = remember { MutableInteractionSource() }, enabled = enabled,
onClickLabel = onClickLabel, interactionSource = interactionSource,
onClick = onClick, onClickLabel = onClickLabel,
indication = ripple(bounded = false), onClick = onClick,
) indication = ripple(bounded = false),
.testTag(TestTags.editAvatar) )
.clearAndSetSemantics { .testTag(TestTags.editAvatar)
contentDescription = a11yAvatar .clearAndSetSemantics {
} contentDescription = a11yAvatar
}
val layoutDirection = LocalLayoutDirection.current val layoutDirection = LocalLayoutDirection.current
@ -123,18 +124,30 @@ fun AvatarPickerView(
buttonSize = state.buttonSize, buttonSize = state.buttonSize,
iconSize = state.iconSize, iconSize = state.iconSize,
iconId = state.iconId, iconId = state.iconId,
modifier = modifier.padding(state.externalPadding).then(clickableModifier), modifier = modifier
.padding(state.externalPadding)
.then(clickableModifier),
) )
} }
is AvatarPickerState.Selected -> { is AvatarPickerState.Selected -> {
Box(modifier = modifier) { Box(modifier = modifier) {
val backgroundModifier = if (enabled) {
eraseBackgroundModifier(state.avatarData.size.dp, state.avatarData.size.dp * 0.225f)
} else {
Modifier
}
Avatar( Avatar(
avatarData = state.avatarData, avatarData = state.avatarData,
avatarType = state.type, avatarType = state.type,
modifier = clickableModifier.then(eraseBackgroundModifier(state.avatarData.size.dp, state.avatarData.size.dp * 0.225f)), modifier = clickableModifier.then(backgroundModifier),
) )
if (enabled) {
OverlayEditButton(editButtonSize = state.avatarData.size.dp * 0.44f) OverlayEditButton(
editButtonSize = state.avatarData.size.dp * 0.44f,
onClick = onClick,
interactionSource = interactionSource
)
}
} }
} }
} }
@ -165,12 +178,18 @@ private fun PickButton(
} }
@Composable @Composable
private fun BoxScope.OverlayEditButton(editButtonSize: Dp) { private fun BoxScope.OverlayEditButton(
editButtonSize: Dp,
onClick: () -> Unit,
interactionSource: MutableInteractionSource
) {
Box( Box(
modifier = Modifier.align(Alignment.BottomEnd) modifier = Modifier
.align(Alignment.BottomEnd)
.size(editButtonSize) .size(editButtonSize)
.offset(x = editButtonSize * 0.266f) .offset(x = editButtonSize * 0.266f)
.clip(CircleShape) .clip(CircleShape)
.clickable(interactionSource = interactionSource, onClick = onClick, indication = null)
.background(ElementTheme.colors.bgCanvasDefault) .background(ElementTheme.colors.bgCanvasDefault)
.border(BorderStroke(1.dp, ElementTheme.colors.borderInteractiveSecondary), shape = CircleShape), .border(BorderStroke(1.dp, ElementTheme.colors.borderInteractiveSecondary), shape = CircleShape),
contentAlignment = Alignment.Center, contentAlignment = Alignment.Center,