[a11y] Use built-in onClickLabel parameter.

This commit is contained in:
Benoit Marty 2025-07-03 17:47:17 +02:00
parent 635711ebef
commit ef8d57dff8
6 changed files with 28 additions and 60 deletions

View file

@ -39,7 +39,6 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.clearAndSetSemantics
import androidx.compose.ui.semantics.onClick
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.traversalIndex
import androidx.compose.ui.text.style.TextAlign
@ -454,19 +453,11 @@ private fun EmojiButton(
.size(48.dp)
.background(backgroundColor, CircleShape)
.clickable(
enabled = true,
onClickLabel = a11yClickLabel,
onClick = { onClick(emoji) },
indication = ripple(bounded = false, radius = emojiRippleRadius),
interactionSource = remember { MutableInteractionSource() }
)
.semantics {
onClick(
label = a11yClickLabel,
) {
onClick(emoji)
true
}
},
),
contentAlignment = Alignment.Center
) {
Text(

View file

@ -31,7 +31,6 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.clearAndSetSemantics
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.onClick
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@ -85,15 +84,6 @@ fun MessagesReactionButton(
}
}
val a11yClickLabel = if (content is MessagesReactionsButtonContent.Reaction) {
a11yReactionAction(
emoji = content.reaction.key,
userAlreadyReacted = content.isHighlighted
)
} else {
""
}
Surface(
modifier = modifier
.background(Color.Transparent)
@ -107,6 +97,12 @@ fun MessagesReactionButton(
.clip(RoundedCornerShape(corner = CornerSize(12.dp)))
.combinedClickable(
onClick = onClick,
onClickLabel = (content as? MessagesReactionsButtonContent.Reaction)?.let {
a11yReactionAction(
emoji = content.reaction.key,
userAlreadyReacted = content.isHighlighted
)
},
onLongClick = onLongClick
)
// Inner border, to highlight when selected
@ -115,14 +111,6 @@ fun MessagesReactionButton(
.padding(vertical = 4.dp, horizontal = 10.dp)
.clearAndSetSemantics {
contentDescription = a11yText
if (content is MessagesReactionsButtonContent.Reaction) {
onClick(
label = a11yClickLabel
) {
onClick()
true
}
}
},
color = buttonColor
) {

View file

@ -58,7 +58,6 @@ import io.element.android.libraries.designsystem.components.button.MainActionBut
import io.element.android.libraries.designsystem.components.list.ListItemContent
import io.element.android.libraries.designsystem.components.preferences.PreferenceCategory
import io.element.android.libraries.designsystem.components.preferences.PreferenceSwitch
import io.element.android.libraries.designsystem.modifiers.a11yClickLabel
import io.element.android.libraries.designsystem.modifiers.niceClickable
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
@ -401,7 +400,6 @@ private fun RoomHeaderSection(
.padding(horizontal = 16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
val actionView = stringResource(CommonStrings.action_view)
Avatar(
avatarData = AvatarData(roomId.value, roomName, avatarUrl, AvatarSize.RoomHeader),
avatarType = AvatarType.Room(
@ -412,9 +410,13 @@ private fun RoomHeaderSection(
),
contentDescription = avatarUrl?.let { stringResource(CommonStrings.a11y_room_avatar) },
modifier = Modifier
.clickable(enabled = avatarUrl != null) { openAvatarPreview(avatarUrl!!) }
.clickable(
enabled = avatarUrl != null,
onClickLabel = stringResource(CommonStrings.action_view),
) {
openAvatarPreview(avatarUrl!!)
}
.testTag(TestTags.roomDetailAvatar)
.a11yClickLabel(avatarUrl?.let { actionView })
)
TitleAndSubtitle(
title = roomName,

View file

@ -31,7 +31,6 @@ import io.element.android.libraries.designsystem.components.avatar.Avatar
import io.element.android.libraries.designsystem.components.avatar.AvatarData
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.designsystem.components.avatar.AvatarType
import io.element.android.libraries.designsystem.modifiers.a11yClickLabel
import io.element.android.libraries.designsystem.modifiers.niceClickable
import io.element.android.libraries.designsystem.preview.ElementPreview
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
@ -61,16 +60,19 @@ fun UserProfileHeaderSection(
.padding(horizontal = 16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
val actionView = stringResource(CommonStrings.action_view)
Avatar(
avatarData = AvatarData(userId.value, userName, avatarUrl, AvatarSize.UserHeader),
avatarType = AvatarType.User,
contentDescription = avatarUrl?.let { stringResource(CommonStrings.a11y_user_avatar) },
modifier = Modifier
.clip(CircleShape)
.clickable(enabled = avatarUrl != null) { openAvatarPreview(avatarUrl!!) }
.clickable(
enabled = avatarUrl != null,
onClickLabel = stringResource(CommonStrings.action_view),
) {
openAvatarPreview(avatarUrl!!)
}
.testTag(TestTags.memberDetailAvatar)
.a11yClickLabel(avatarUrl?.let { actionView })
)
Spacer(modifier = Modifier.height(24.dp))
if (userName != null) {

View file

@ -26,7 +26,6 @@ import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.LayoutDirection
import io.element.android.libraries.designsystem.modifiers.a11yClickLabel
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
import io.element.android.libraries.designsystem.text.toPx
@ -52,7 +51,6 @@ fun DmAvatars(
val boxSizePx = boxSize.toPx()
val otherAvatarRadius = otherUserAvatarData.size.dp.toPx() / 2
val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl
val actionView = stringResource(CommonStrings.action_view)
Box(
modifier = modifier.size(boxSize),
) {
@ -84,10 +82,12 @@ fun DmAvatars(
)
}
.clip(CircleShape)
.clickable(enabled = userAvatarData.url != null) {
.clickable(
enabled = userAvatarData.url != null,
onClickLabel = stringResource(CommonStrings.action_view),
) {
userAvatarData.url?.let { openAvatarPreview(it) }
}
.a11yClickLabel(userAvatarData.url?.let { actionView })
)
// Draw other user avatar
Avatar(
@ -97,11 +97,13 @@ fun DmAvatars(
modifier = Modifier
.align(Alignment.TopEnd)
.clip(CircleShape)
.clickable(enabled = otherUserAvatarData.url != null) {
.clickable(
enabled = otherUserAvatarData.url != null,
onClickLabel = stringResource(CommonStrings.action_view),
) {
otherUserAvatarData.url?.let { openOtherAvatarPreview(it) }
}
.testTag(TestTags.memberDetailAvatar)
.a11yClickLabel(otherUserAvatarData.url?.let { actionView })
)
}
}

View file

@ -12,8 +12,6 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.semantics.onClick
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
fun Modifier.clickableIfNotNull(onClick: (() -> Unit)? = null): Modifier = this.then(
@ -31,18 +29,3 @@ fun Modifier.niceClickable(
.clickable { onClick() }
.padding(horizontal = 4.dp)
}
fun Modifier.a11yClickLabel(
label: String?,
): Modifier = then(
if (label != null) {
Modifier.semantics {
onClick(
label = label,
action = null,
)
}
} else {
Modifier
}
)