Skip to content

Commit 122732c

Browse files
HowieHChenYuKongA
andauthored
library: Optimize SuperDropdown (#23)
* Modify the position of the popup * Add: SuperDropdown will be "selected" when the popup is expanded. * update: [SuperDropdown] Change background instead of focus state when "selected". * example: No need for HorizontalPadding --------- Co-authored-by: YuKongA <[email protected]>
1 parent 0499757 commit 122732c

File tree

2 files changed

+25
-8
lines changed

2 files changed

+25
-8
lines changed

composeApp/src/commonMain/kotlin/SecondPage.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ fun SecondPage(
2828
summary = "Popup near click",
2929
items = dropdownOptions,
3030
selectedIndex = dropdownSelectedOption.value,
31-
onSelectedIndexChange = { newOption -> dropdownSelectedOption.value = newOption },
32-
horizontalPadding = 12.dp
31+
onSelectedIndexChange = { newOption -> dropdownSelectedOption.value = newOption }
3332
)
3433
}
3534
item {

miuix/src/commonMain/kotlin/top/yukonga/miuix/kmp/extra/SuperDropdown.kt

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package top.yukonga.miuix.kmp.extra
22

3+
import androidx.compose.animation.animateColorAsState
4+
import androidx.compose.animation.core.spring
35
import androidx.compose.foundation.Image
46
import androidx.compose.foundation.background
57
import androidx.compose.foundation.clickable
@@ -24,6 +26,7 @@ import androidx.compose.foundation.lazy.LazyColumn
2426
import androidx.compose.runtime.Composable
2527
import androidx.compose.runtime.LaunchedEffect
2628
import androidx.compose.runtime.MutableState
29+
import androidx.compose.runtime.State
2730
import androidx.compose.runtime.getValue
2831
import androidx.compose.runtime.mutableStateListOf
2932
import androidx.compose.runtime.mutableStateOf
@@ -107,6 +110,8 @@ fun SuperDropdown(
107110
val isDropdownExpanded = remember { mutableStateOf(false) }
108111
val hapticFeedback = LocalHapticFeedback.current
109112
val actionColor = if (enabled) MiuixTheme.colorScheme.onSurfaceVariantActions else MiuixTheme.colorScheme.disabledOnSecondaryVariant
113+
val targetColor = if (isDropdownExpanded.value) MiuixTheme.colorScheme.onBackground.copy(alpha = 0.15f) else Color.Transparent
114+
val touchTint by animateColorAsState(targetValue = targetColor, animationSpec = spring(stiffness = 2000f))
110115
var alignLeft by rememberSaveable { mutableStateOf(true) }
111116
var dropdownOffsetXPx by remember { mutableStateOf(0) }
112117
var dropdownOffsetYPx by remember { mutableStateOf(0) }
@@ -134,7 +139,8 @@ fun SuperDropdown(
134139
componentHeightPx = coordinates.size.height
135140
componentWidthPx = coordinates.size.width
136141
}
137-
},
142+
}
143+
.background(touchTint),
138144
insideMargin = insideMargin,
139145
title = title,
140146
titleColor = titleColor,
@@ -190,6 +196,7 @@ fun SuperDropdown(
190196
val captionBarPx by rememberUpdatedState(
191197
with(density) { WindowInsets.captionBar.asPaddingValues().calculateBottomPadding().toPx() }.roundToInt()
192198
)
199+
val insideWidthPx by rememberUpdatedState(with(density) { insideMargin.width.toPx() }.roundToInt())
193200
val insideHeightPx by rememberUpdatedState(with(density) { insideMargin.height.toPx() }.roundToInt())
194201
val displayCutoutLeftSize = rememberUpdatedState(with(density) {
195202
WindowInsets.displayCutout.asPaddingValues(density).calculateLeftPadding(LayoutDirection.Ltr).toPx()
@@ -221,9 +228,9 @@ fun SuperDropdown(
221228
modifier = Modifier
222229
.onGloballyPositioned { layoutCoordinates ->
223230
offsetXPx = if (alwaysRight || !alignLeft) {
224-
dropdownOffsetXPx + componentWidthPx - layoutCoordinates.size.width - paddingPx - if (defaultWindowInsetsPadding) displayCutoutLeftSize.value else 0
231+
dropdownOffsetXPx + componentWidthPx - insideWidthPx - layoutCoordinates.size.width - paddingPx - if (defaultWindowInsetsPadding) displayCutoutLeftSize.value else 0
225232
} else {
226-
dropdownOffsetXPx + paddingPx - if (defaultWindowInsetsPadding) displayCutoutLeftSize.value else 0
233+
dropdownOffsetXPx + paddingPx + insideWidthPx - if (defaultWindowInsetsPadding) displayCutoutLeftSize.value else 0
227234
}
228235
offsetYPx = calculateOffsetYPx(
229236
windowHeightPx,
@@ -238,8 +245,10 @@ fun SuperDropdown(
238245
}
239246
.align(AbsoluteAlignment.TopLeft)
240247
.graphicsLayer(
241-
shadowElevation = 18f,
242-
shape = SmoothRoundedCornerShape(18.dp)
248+
shadowElevation = 40f,
249+
shape = SmoothRoundedCornerShape(18.dp),
250+
ambientShadowColor = MiuixTheme.colorScheme.onBackground.copy(alpha = 0.2f),
251+
spotShadowColor = MiuixTheme.colorScheme.onBackground.copy(alpha = 0.6f)
243252
)
244253
.clip(SmoothRoundedCornerShape(18.dp))
245254
.background(MiuixTheme.colorScheme.surface)
@@ -353,7 +362,16 @@ fun calculateOffsetYPx(
353362
navigationBarPx: Int,
354363
captionBarPx: Int
355364
): Int {
356-
return if (windowHeightPx - dropdownOffsetPx < dropdownHeightPx / 2 + captionBarPx + navigationBarPx + insideHeightPx + componentHeightPx / 2) {
365+
return if (windowHeightPx - captionBarPx - navigationBarPx - dropdownOffsetPx - componentHeightPx > dropdownHeightPx) {
366+
// Show below
367+
dropdownOffsetPx + componentHeightPx - insideHeightPx / 2
368+
} else if (dropdownOffsetPx - statusBarPx > dropdownHeightPx) {
369+
// Show above
370+
dropdownOffsetPx - dropdownHeightPx + insideHeightPx / 2
371+
} else if (windowHeightPx - statusBarPx - captionBarPx - navigationBarPx <= dropdownHeightPx) {
372+
// Special handling when the height of the popup is maxsize (== windowHeightPx)
373+
0
374+
} else if (windowHeightPx - dropdownOffsetPx < dropdownHeightPx / 2 + captionBarPx + navigationBarPx + insideHeightPx + componentHeightPx / 2) {
357375
windowHeightPx - dropdownHeightPx - insideHeightPx - captionBarPx - navigationBarPx
358376
} else {
359377
val offset = dropdownOffsetPx - dropdownHeightPx / 2 + componentHeightPx / 2

0 commit comments

Comments
 (0)