mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-10-31 08:15:02 +00:00
Draw the focus indicator around the whole SelectedItem
Previously, only the small remove button could get the keyboard focus, and the focus ring was barely visible. Now the whole item is focusable, the focus ring is drawn around it, and pressing an activation key (Enter, Space, D-pad center) removes the item. Touch behavior is unchanged: only the remove button is clickable. Also add a shared `activationKeys` set in the designsystem module. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+20
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) 2026 Element Creations Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.designsystem.utils
|
||||
|
||||
import androidx.compose.ui.input.key.Key
|
||||
|
||||
/**
|
||||
* Keys which can be used to activate (i.e. click) the component having the keyboard focus.
|
||||
*/
|
||||
val activationKeys = setOf(
|
||||
Key.Enter,
|
||||
Key.NumPadEnter,
|
||||
Key.DirectionCenter,
|
||||
Key.Spacebar,
|
||||
)
|
||||
+32
@@ -9,6 +9,8 @@
|
||||
package io.element.android.libraries.matrix.ui.components
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.focusable
|
||||
import androidx.compose.foundation.indication
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@@ -25,11 +27,16 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.draw.clipToBounds
|
||||
import androidx.compose.ui.draw.drawWithContent
|
||||
import androidx.compose.ui.focus.focusProperties
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.graphics.BlendMode
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.CompositingStrategy
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.input.key.KeyEventType
|
||||
import androidx.compose.ui.input.key.key
|
||||
import androidx.compose.ui.input.key.onKeyEvent
|
||||
import androidx.compose.ui.input.key.type
|
||||
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.semantics.clearAndSetSemantics
|
||||
@@ -48,6 +55,7 @@ import io.element.android.libraries.designsystem.text.toPx
|
||||
import io.element.android.libraries.designsystem.theme.components.Icon
|
||||
import io.element.android.libraries.designsystem.theme.components.Surface
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.designsystem.utils.activationKeys
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
||||
@Composable
|
||||
@@ -62,9 +70,31 @@ fun SelectedItem(
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
val actionRemove = stringResource(id = CommonStrings.action_remove)
|
||||
val interactionSource = remember { MutableInteractionSource() }
|
||||
Box(
|
||||
modifier = modifier
|
||||
.width(avatarData.size.dp)
|
||||
.then(
|
||||
if (canRemove) {
|
||||
// Let the whole item get the keyboard focus, so that the focus indicator is drawn around it.
|
||||
Modifier
|
||||
.onKeyEvent { event ->
|
||||
if (event.type == KeyEventType.KeyUp && event.key in activationKeys) {
|
||||
onRemoveClick()
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
.indication(
|
||||
interactionSource = interactionSource,
|
||||
indication = ripple(),
|
||||
)
|
||||
.focusable(interactionSource = interactionSource)
|
||||
} else {
|
||||
Modifier
|
||||
}
|
||||
)
|
||||
.clearAndSetSemantics {
|
||||
contentDescription = a11yContentDescription
|
||||
if (canRemove) {
|
||||
@@ -130,6 +160,8 @@ fun SelectedItem(
|
||||
.clip(CircleShape)
|
||||
.size(20.dp)
|
||||
.align(Alignment.TopEnd)
|
||||
// The whole item is focusable, not the remove button
|
||||
.focusProperties { canFocus = false }
|
||||
.clickable(
|
||||
indication = ripple(),
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
|
||||
Reference in New Issue
Block a user