fix(desktop): hover-state polish + Search width cap + reserve reaction-icon space
NoteCard hover (header+text inner clickable + avatar/name chip): - Clip(RoundedCornerShape(8.dp)) before .clickable on the header+text Column so the ripple rounds instead of cutting a hard rectangle. - Avatar+name chip gets a stadium clip (RoundedCornerShape(100.dp)) before its clickable — matches how Slack / Notion / Linear render user-pill hover states. Chat bubble hover (ChatBubbleLayout): - combinedClickable was applied outside the Surface's shape clipping, so the ripple ignored ChatBubbleShapeMe/Them. Moved the shape into a named val and added Modifier.clip(bubbleShape) ahead of combinedClickable. Hover now rounds with the bubble. Chat reaction icon (ChatPane detailRow): - On hover the "add reaction" icon used to conditionally appear and shift every other element in the detail row, causing the whole list to reflow up or down. Wrapped in a Box with Modifier.alpha that fades in/out — the icon is always laid out so the row stays fixed. Button is disabled when not hovered so it's click-through when invisible. Search text field: - Now padded by LocalReadingSidePadding so it stays inside the 720dp reading column on wide displays (previously the search Row's fillMaxWidth spanned the whole window after the ReadingColumn refactor). - Bumped height from 40dp → 44dp. M3 OutlinedTextField has ~16dp of internal vertical content padding that was clipping the bodyMedium placeholder at 40dp. Same change for the chat input. https://claude.ai/code/session_01NufduPfZvYQVYwLkbCjCUo
This commit is contained in:
+17
-11
@@ -34,6 +34,7 @@ import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.compositeOver
|
||||
import com.vitorpamplona.amethyst.commons.ui.theme.ChatBubbleMaxSizeModifier
|
||||
@@ -128,18 +129,23 @@ fun ChatBubbleLayout(
|
||||
)
|
||||
}
|
||||
|
||||
val bubbleShape = if (isLoggedInUser) ChatBubbleShapeMe else ChatBubbleShapeThem
|
||||
// Clip the hover/ripple to the bubble shape — combinedClickable otherwise
|
||||
// paints a rectangular ripple that ignores the Surface's rounded corners.
|
||||
val clickableModifier =
|
||||
remember {
|
||||
Modifier.combinedClickable(
|
||||
onClick = {
|
||||
if (!onClick()) {
|
||||
if (!isComplete) {
|
||||
showDetails.value = !showDetails.value
|
||||
remember(bubbleShape) {
|
||||
Modifier
|
||||
.clip(bubbleShape)
|
||||
.combinedClickable(
|
||||
onClick = {
|
||||
if (!onClick()) {
|
||||
if (!isComplete) {
|
||||
showDetails.value = !showDetails.value
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
onLongClick = { popupExpanded.value = true },
|
||||
)
|
||||
},
|
||||
onLongClick = { popupExpanded.value = true },
|
||||
)
|
||||
}
|
||||
|
||||
Row(
|
||||
@@ -148,7 +154,7 @@ fun ChatBubbleLayout(
|
||||
) {
|
||||
Surface(
|
||||
color = bgColor.value,
|
||||
shape = if (isLoggedInUser) ChatBubbleShapeMe else ChatBubbleShapeThem,
|
||||
shape = bubbleShape,
|
||||
modifier = clickableModifier,
|
||||
) {
|
||||
Column(modifier = MessageBubbleLimits, verticalArrangement = ChatRowColSpacing5dp) {
|
||||
|
||||
Reference in New Issue
Block a user