Skip to content

Commit

Permalink
restore basic onHover behavior for ListComboBox
Browse files Browse the repository at this point in the history
Signed-off-by: Ivan Morgillo <[email protected]>
  • Loading branch information
hamen committed Oct 16, 2024
1 parent 2534d29 commit 2327a72
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,6 @@ internal class SwingComparisonTabPanel : BorderLayoutPanel() {
text = item,
isSelected = isSelected,
isHovered = isItemHovered,
isListHovered = isListHovered,
style = JewelTheme.comboBoxStyle.itemStyle,
contentDescription = item,
)
Expand All @@ -283,7 +282,6 @@ internal class SwingComparisonTabPanel : BorderLayoutPanel() {
text = item,
isSelected = isSelected,
isHovered = isItemHovered,
isListHovered = isListHovered,
style = JewelTheme.comboBoxStyle.itemStyle,
contentDescription = item,
)
Expand All @@ -304,7 +302,6 @@ internal class SwingComparisonTabPanel : BorderLayoutPanel() {
text = item,
isSelected = isSelected,
isHovered = isItemHovered,
isListHovered = isListHovered,
style = JewelTheme.comboBoxStyle.itemStyle,
contentDescription = item,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import org.jetbrains.jewel.foundation.theme.JewelTheme
import org.jetbrains.jewel.ui.Outline
import org.jetbrains.jewel.ui.component.Dropdown
import org.jetbrains.jewel.ui.component.ListComboBox
import org.jetbrains.jewel.ui.component.ListItemState
import org.jetbrains.jewel.ui.component.SimpleListItem
import org.jetbrains.jewel.ui.component.Text
import org.jetbrains.jewel.ui.component.Typography
Expand Down Expand Up @@ -180,8 +181,6 @@ fun Dropdowns() {
var selectedComboBox2: String? by remember { mutableStateOf(comboBoxItems.first()) }
var selectedComboBox3: String? by remember { mutableStateOf(comboBoxItems.first()) }

var isListHovered1 by remember { mutableStateOf(false) }

Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
Text(text = "ComboBoxes", style = Typography.h1TextStyle())
Text(text = "Selected item: $selectedComboBox1")
Expand All @@ -195,15 +194,12 @@ fun Dropdowns() {
modifier = Modifier.width(200.dp),
maxPopupHeight = 150.dp,
onSelectedItemChange = { selectedComboBox1 = it },
onListHoverChange = { isListHovered1 = it },
listItemContent = { item, isSelected, isFocused, isItemHovered, isListHovered ->
SimpleListItem(
text = item,
isSelected = isSelected && !isListHovered1,
isHovered = isItemHovered,
isListHovered = isListHovered,
style = JewelTheme.comboBoxStyle.itemStyle,
modifier = Modifier,
state = ListItemState(isSelected, isListHovered, isItemHovered),
style = JewelTheme.comboBoxStyle.itemStyle,
contentDescription = item,
)
},
Expand All @@ -223,9 +219,7 @@ fun Dropdowns() {
listItemContent = { item, isSelected, isFocused, isItemHovered, isListHovered ->
SimpleListItem(
text = item,
isSelected = isSelected,
isHovered = isItemHovered,
isListHovered = isListHovered,
state = ListItemState(isSelected, isListHovered, isItemHovered),
style = JewelTheme.comboBoxStyle.itemStyle,
contentDescription = item,
)
Expand All @@ -244,9 +238,7 @@ fun Dropdowns() {
listItemContent = { item, isSelected, isFocused, isItemHovered, isListHovered ->
SimpleListItem(
text = item,
isSelected = isSelected,
isHovered = isItemHovered,
isListHovered = isListHovered,
state = ListItemState(isSelected, isListHovered, isItemHovered),
style = JewelTheme.comboBoxStyle.itemStyle,
contentDescription = item,
)
Expand Down
3 changes: 1 addition & 2 deletions ui-tests/src/test/kotlin/ListComboBoxUiTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -469,11 +469,10 @@ class ListComboBoxUiTest {
listItemContent = { item, isSelected, isFocused, isItemHovered, isListHovered ->
SimpleListItem(
text = item,
modifier = Modifier.testTag(item),
isSelected = isSelected,
isHovered = isItemHovered,
isListHovered = isListHovered,
style = JewelTheme.comboBoxStyle.itemStyle,
modifier = Modifier.testTag(item),
contentDescription = item,
)
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ public fun ListComboBox(
val scrollState = rememberSelectableLazyListState()
var selectedItem by remember { mutableIntStateOf(0) }
var isListHovered by remember { mutableStateOf(false) }
var hoverItemIndex by remember { mutableStateOf(-1) }
var softSelection by remember { mutableStateOf(isListHovered) }
val scope = rememberCoroutineScope()

LaunchedEffect(selectedItem) { scrollState.selectedKeys = setOf(items[selectedItem]) }
Expand All @@ -56,10 +58,18 @@ public fun ListComboBox(
}

val onArrowDownPress: () -> Unit = {
if (hoverItemIndex != -1) {
selectedItem = hoverItemIndex
hoverItemIndex = -1
}
selectedItem = selectedItem.plus(1).coerceAtMost(items.lastIndex)
scope.launch { scrollState.lazyListState.scrollToIndex(selectedItem) }
}
val onArrowUpPress: () -> Unit = {
if (hoverItemIndex != -1) {
selectedItem = hoverItemIndex
hoverItemIndex = -1
}
selectedItem = selectedItem.minus(1).coerceAtLeast(0)
scope.launch { scrollState.lazyListState.scrollToIndex(selectedItem) }
}
Expand Down Expand Up @@ -88,6 +98,7 @@ public fun ListComboBox(
modifier =
Modifier.heightIn(max = popupMaxHeight).onHover {
isListHovered = it
if (!isListHovered) hoverItemIndex = -1
onListHoverChange(it)
},
) {
Expand All @@ -113,11 +124,18 @@ public fun ListComboBox(
Modifier.onHover {
isItemHovered = it
if (isItemHovered) {
hoverItemIndex = items.indexOf(item)
onHoverItemChange(item)
}
}
) {
listItemContent(item, isSelected, isActive, isItemHovered, isListHovered)
listItemContent(
item,
isSelected,
isActive,
isItemHovered && hoverItemIndex != -1,
isListHovered,
)
}
},
)
Expand All @@ -143,6 +161,7 @@ public fun ListComboBox(
modifier =
Modifier.heightIn(max = popupMaxHeight).onHover {
isListHovered = it
if (!isListHovered) hoverItemIndex = -1
onListHoverChange(it)
},
) {
Expand All @@ -168,6 +187,7 @@ public fun ListComboBox(
Modifier.onHover {
isHovered = it
if (isHovered) {
hoverItemIndex = items.indexOf(item)
onHoverItemChange(item)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,39 +16,29 @@ import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import org.jetbrains.jewel.foundation.GenerateDataFunctions
import org.jetbrains.jewel.foundation.theme.JewelTheme
import org.jetbrains.jewel.foundation.util.JewelLogger
import org.jetbrains.jewel.ui.component.styling.SimpleListItemStyle
import org.jetbrains.jewel.ui.icon.IconKey
import org.jetbrains.jewel.ui.theme.comboBoxStyle

@Composable
public fun SimpleListItem(
text: String,
isSelected: Boolean,
isHovered: Boolean,
isListHovered: Boolean,
style: SimpleListItemStyle,
modifier: Modifier = Modifier,
state: ListItemState,
style: SimpleListItemStyle = JewelTheme.comboBoxStyle.itemStyle,
height: Dp = JewelTheme.globalMetrics.rowHeight,
icon: IconKey? = null,
contentDescription: String? = null,
) {

JewelLogger.getInstance("Jewel.SimpleListItem")
.debug("$text isSelected: $isSelected, isHovered: $isHovered, islistHovered: $isListHovered")

val color =
when {
isSelected -> style.colors.backgroundSelectedFocused
isHovered -> style.colors.backgroundSelectedFocused
else -> Color.Transparent
}
val color = if (state.isHovered) style.colors.backgroundSelectedFocused else Color.Transparent

Row(
verticalAlignment = Alignment.CenterVertically,
modifier =
modifier
.semantics { selected = isSelected }
.semantics { selected = state.isSelected }
.fillMaxWidth()
.height(height)
.padding(style.metrics.outerPadding)
Expand All @@ -61,3 +51,10 @@ public fun SimpleListItem(
Text(text = text, maxLines = 1, overflow = TextOverflow.Ellipsis, style = JewelTheme.defaultTextStyle)
}
}

@GenerateDataFunctions
public class ListItemState(
public val isSelected: Boolean,
public val isSoftSelected: Boolean,
public val isHovered: Boolean,
)

0 comments on commit 2327a72

Please sign in to comment.