diff --git a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/SelectableLazyColumn.kt b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/SelectableLazyColumn.kt index 1a37f2de13dc..16ec1eb4267b 100644 --- a/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/SelectableLazyColumn.kt +++ b/platform/jewel/foundation/src/main/kotlin/org/jetbrains/jewel/foundation/lazy/SelectableLazyColumn.kt @@ -30,6 +30,7 @@ import androidx.compose.ui.input.key.onPreviewKeyEvent import androidx.compose.ui.input.pointer.PointerEventType import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.semantics.focused +import androidx.compose.ui.semantics.isTraversalGroup import androidx.compose.ui.semantics.selected import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.stateDescription @@ -232,6 +233,7 @@ private fun Modifier.selectable( selected = itemKey in selectableState.selectedKeys focused = selectableState.lastActiveItemIndex == allKeys.indexOfFirst { it.key == itemKey } stateDescription = "" + isTraversalGroup = false } // Handle pointer input but ensure Tab keys aren't intercepted .pointerInput(allKeys, itemKey) { @@ -240,7 +242,6 @@ private fun Modifier.selectable( val event = awaitPointerEvent() when (event.type) { PointerEventType.Press -> { - requester?.requestFocus() actionHandler.handlePointerEventPress( pointerEvent = event, keybindings = keybindings, @@ -249,6 +250,7 @@ private fun Modifier.selectable( allKeys = allKeys, key = itemKey, ) + requester?.requestFocus() } } } diff --git a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/ChipsAndTree.kt b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/ChipsAndTree.kt index 578a6e250faa..ac684420574d 100644 --- a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/ChipsAndTree.kt +++ b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/components/ChipsAndTree.kt @@ -2,7 +2,6 @@ // Apache 2.0 license. package org.jetbrains.jewel.samples.showcase.components -import androidx.compose.foundation.VerticalScrollbar import androidx.compose.foundation.border import androidx.compose.foundation.focusable import androidx.compose.foundation.layout.Arrangement @@ -13,8 +12,6 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width -import androidx.compose.foundation.rememberScrollbarAdapter -import androidx.compose.foundation.selection.selectable import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -48,6 +45,7 @@ import org.jetbrains.jewel.ui.component.RadioButtonChip import org.jetbrains.jewel.ui.component.SimpleListItem import org.jetbrains.jewel.ui.component.Text import org.jetbrains.jewel.ui.component.ToggleableChip +import org.jetbrains.jewel.ui.component.VerticalScrollbar import org.jetbrains.jewel.ui.theme.colorPalette @Composable @@ -177,27 +175,27 @@ public fun SelectableLazyColumnSample(modifier: Modifier = Modifier) { } val state = rememberSelectableLazyListState() - Box(modifier = modifier.size(200.dp, 200.dp)) { + Box(modifier = modifier.size(200.dp)) { if (listOfItems.isEmpty()) { CircularProgressIndicator(Modifier.align(Alignment.Center)) } else { SelectableLazyColumn(modifier = Modifier.focusable(), state = state) { items(listOfItems, key = { item -> item }) { item -> + LaunchedEffect(isSelected) { + if (isSelected) { + JewelLogger.getInstance("ChipsAndTree").info("Item $item got selected") + } + } + SimpleListItem( text = item, selected = isSelected, active = isActive, - modifier = - Modifier.fillMaxWidth().selectable(isSelected) { - JewelLogger.getInstance("ChipsAndTree").info("Click on $item") - }, + modifier = Modifier.fillMaxWidth(), ) } } - VerticalScrollbar( - rememberScrollbarAdapter(state.lazyListState), - modifier = Modifier.align(Alignment.CenterEnd), - ) + VerticalScrollbar(state.lazyListState, modifier = Modifier.align(Alignment.CenterEnd)) } } } diff --git a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/views/ComponentsView.kt b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/views/ComponentsView.kt index 605920e4a678..12a885d54faf 100644 --- a/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/views/ComponentsView.kt +++ b/platform/jewel/samples/showcase/src/main/kotlin/org/jetbrains/jewel/samples/showcase/views/ComponentsView.kt @@ -18,6 +18,8 @@ import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.semantics.isTraversalGroup +import androidx.compose.ui.semantics.semantics import androidx.compose.ui.unit.dp import kotlin.time.Duration.Companion.milliseconds import org.jetbrains.jewel.foundation.modifier.trackActivation @@ -43,7 +45,11 @@ public fun ComponentsView( toolbarButtonMetrics: IconButtonMetrics, modifier: Modifier = Modifier, ) { - Row(modifier.trackActivation().fillMaxSize().background(JewelTheme.globalColors.panelBackground)) { + Row( + modifier.trackActivation().fillMaxSize().background(JewelTheme.globalColors.panelBackground).semantics { + isTraversalGroup = true + } + ) { ComponentsToolBar( buttonMetrics = toolbarButtonMetrics, views = viewModel.getViews(), diff --git a/platform/jewel/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/MarkdownView.kt b/platform/jewel/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/MarkdownView.kt index e51f2e485e4b..7fd900a51876 100644 --- a/platform/jewel/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/MarkdownView.kt +++ b/platform/jewel/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/MarkdownView.kt @@ -7,6 +7,8 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.text.input.rememberTextFieldState import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.semantics.isTraversalGroup +import androidx.compose.ui.semantics.semantics import org.jetbrains.jewel.foundation.modifier.trackActivation import org.jetbrains.jewel.foundation.theme.JewelTheme import org.jetbrains.jewel.markdown.MarkdownMode @@ -19,7 +21,11 @@ import org.jetbrains.jewel.ui.component.Divider @Composable internal fun MarkdownDemo() { - Row(Modifier.trackActivation().fillMaxSize().background(JewelTheme.globalColors.panelBackground)) { + Row( + Modifier.trackActivation().fillMaxSize().background(JewelTheme.globalColors.panelBackground).semantics { + isTraversalGroup = true + } + ) { WithMarkdownMode(MarkdownMode.EditorPreview(scrollingSynchronizer = null)) { val editorState = rememberTextFieldState(JewelReadme) MarkdownEditor(state = editorState, modifier = Modifier.fillMaxHeight().weight(1f)) diff --git a/platform/jewel/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/WelcomeView.kt b/platform/jewel/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/WelcomeView.kt index ebe6d143760b..327d66f760cc 100644 --- a/platform/jewel/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/WelcomeView.kt +++ b/platform/jewel/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/WelcomeView.kt @@ -11,6 +11,8 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.semantics.isTraversalGroup +import androidx.compose.ui.semantics.semantics import androidx.compose.ui.unit.dp import org.jetbrains.jewel.foundation.JewelFlags import org.jetbrains.jewel.foundation.modifier.trackActivation @@ -32,7 +34,11 @@ import org.jetbrains.jewel.ui.typography internal fun WelcomeView() { Column( modifier = - Modifier.trackActivation().fillMaxSize().background(JewelTheme.globalColors.panelBackground).padding(24.dp), + Modifier.trackActivation() + .fillMaxSize() + .background(JewelTheme.globalColors.panelBackground) + .padding(24.dp) + .semantics { isTraversalGroup = true }, verticalArrangement = Arrangement.spacedBy(24.dp), ) { Icon(key = ShowcaseIcons.jewelLogo, contentDescription = null, modifier = Modifier.size(200.dp)) diff --git a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/SimpleListItem.kt b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/SimpleListItem.kt index 9efb5d270f25..5a878e7ed86f 100644 --- a/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/SimpleListItem.kt +++ b/platform/jewel/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/SimpleListItem.kt @@ -13,6 +13,7 @@ import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.semantics.isTraversalGroup import androidx.compose.ui.semantics.selected import androidx.compose.ui.semantics.semantics import androidx.compose.ui.text.style.TextOverflow @@ -210,7 +211,10 @@ public fun SimpleListItem( Row( modifier = modifier - .semantics { selected = state.isSelected } + .semantics(mergeDescendants = true) { + selected = state.isSelected + isTraversalGroup = false + } .fillMaxWidth() .height(height) .padding(style.metrics.outerPadding) @@ -337,7 +341,10 @@ public fun SimpleListItem( Row( modifier = modifier - .semantics { selected = state.isSelected } + .semantics(mergeDescendants = true) { + selected = state.isSelected + isTraversalGroup = false + } .fillMaxWidth() .height(height) .padding(style.metrics.outerPadding)