Skip to content

Commit a81392e

Browse files
committed
library: Opt MiuixPopupUtil
1 parent ee58ec8 commit a81392e

File tree

4 files changed

+71
-53
lines changed

4 files changed

+71
-53
lines changed

composeApp/src/commonMain/kotlin/component/TextComponent.kt

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -302,10 +302,7 @@ fun dialog(showDialog: MutableState<Boolean>) {
302302
SuperDialog(
303303
title = "Dialog 1",
304304
summary = "Summary",
305-
show = showDialog,
306-
onDismissRequest = {
307-
showDialog.value = false
308-
},
305+
show = showDialog
309306
) {
310307
TextField(
311308
modifier = Modifier.padding(bottom = 16.dp),
@@ -320,8 +317,7 @@ fun dialog(showDialog: MutableState<Boolean>) {
320317
modifier = Modifier.weight(1f),
321318
text = "Cancel",
322319
onClick = {
323-
dismissDialog()
324-
showDialog.value = false
320+
dismissDialog(showDialog)
325321
}
326322
)
327323
Spacer(Modifier.width(20.dp))
@@ -330,8 +326,7 @@ fun dialog(showDialog: MutableState<Boolean>) {
330326
text = "Confirm",
331327
submit = true,
332328
onClick = {
333-
dismissDialog()
334-
showDialog.value = false
329+
dismissDialog(showDialog)
335330
}
336331
)
337332
}
@@ -350,10 +345,7 @@ fun dialog2(showDialog: MutableState<Boolean>) {
350345
SuperDialog(
351346
title = "Dialog 2",
352347
backgroundColor = MiuixTheme.colorScheme.background,
353-
show = showDialog,
354-
onDismissRequest = {
355-
showDialog.value = false
356-
},
348+
show = showDialog
357349
) {
358350
Card {
359351
SuperDropdown(
@@ -372,8 +364,7 @@ fun dialog2(showDialog: MutableState<Boolean>) {
372364
modifier = Modifier.weight(1f),
373365
text = "Cancel",
374366
onClick = {
375-
dismissDialog()
376-
showDialog.value = false
367+
dismissDialog(showDialog)
377368
}
378369
)
379370
Spacer(Modifier.width(20.dp))
@@ -382,8 +373,7 @@ fun dialog2(showDialog: MutableState<Boolean>) {
382373
text = "Confirm",
383374
submit = true,
384375
onClick = {
385-
dismissDialog()
386-
showDialog.value = false
376+
dismissDialog(showDialog)
387377
}
388378
)
389379
}

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

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import top.yukonga.miuix.kmp.basic.Text
3434
import top.yukonga.miuix.kmp.theme.MiuixTheme
3535
import top.yukonga.miuix.kmp.utils.BackHandler
3636
import top.yukonga.miuix.kmp.utils.MiuixPopupUtil.Companion.dismissDialog
37+
import top.yukonga.miuix.kmp.utils.MiuixPopupUtil.Companion.isDialogShowing
3738
import top.yukonga.miuix.kmp.utils.getRoundedCorner
3839
import top.yukonga.miuix.kmp.utils.getWindowSize
3940
import top.yukonga.miuix.kmp.utils.squircleshape.SquircleShape
@@ -47,7 +48,7 @@ import top.yukonga.miuix.kmp.utils.squircleshape.SquircleShape
4748
* @param summary The summary of the [SuperDialog].
4849
* @param summaryColor The color of the summary.
4950
* @param backgroundColor The background color of the [SuperDialog].
50-
* @param show The state of the [SuperDialog].
51+
* @param show The show state of the [SuperDialog].
5152
* @param onDismissRequest The callback when the [SuperDialog] is dismissed.
5253
* @param outsideMargin The margin outside the [SuperDialog].
5354
* @param insideMargin The margin inside the [SuperDialog].
@@ -63,7 +64,7 @@ fun SuperDialog(
6364
summaryColor: Color = MiuixTheme.colorScheme.onSurfaceVariantDialog,
6465
backgroundColor: Color = MiuixTheme.colorScheme.surfaceVariant,
6566
show: MutableState<Boolean>,
66-
onDismissRequest: () -> Unit,
67+
onDismissRequest: (() -> Unit)? = null,
6768
outsideMargin: DpSize = DpSize(12.dp, 12.dp),
6869
insideMargin: Dp = 24.dp,
6970
defaultWindowInsetsPadding: Boolean = true,
@@ -85,9 +86,9 @@ fun SuperDialog(
8586
}
8687
}
8788

88-
BackHandler(enabled = show.value) {
89-
dismissDialog()
90-
onDismissRequest()
89+
BackHandler(enabled = isDialogShowing()) {
90+
dismissDialog(show)
91+
onDismissRequest?.invoke()
9192
}
9293

9394
Box(
@@ -102,8 +103,8 @@ fun SuperDialog(
102103
.pointerInput(Unit) {
103104
detectTapGestures(
104105
onTap = {
105-
dismissDialog()
106-
onDismissRequest()
106+
dismissDialog(show)
107+
onDismissRequest?.invoke()
107108
}
108109
)
109110
}

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

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import androidx.compose.foundation.Image
44
import androidx.compose.foundation.background
55
import androidx.compose.foundation.clickable
66
import androidx.compose.foundation.gestures.detectTapGestures
7-
import androidx.compose.foundation.interaction.MutableInteractionSource
87
import androidx.compose.foundation.layout.Arrangement
98
import androidx.compose.foundation.layout.Row
109
import androidx.compose.foundation.layout.WindowInsets
@@ -64,6 +63,7 @@ import top.yukonga.miuix.kmp.icon.icons.Check
6463
import top.yukonga.miuix.kmp.theme.MiuixTheme
6564
import top.yukonga.miuix.kmp.utils.BackHandler
6665
import top.yukonga.miuix.kmp.utils.MiuixPopupUtil.Companion.dismissPopup
66+
import top.yukonga.miuix.kmp.utils.MiuixPopupUtil.Companion.isPopupShowing
6767
import top.yukonga.miuix.kmp.utils.MiuixPopupUtil.Companion.showPopup
6868
import top.yukonga.miuix.kmp.utils.getWindowSize
6969
import top.yukonga.miuix.kmp.utils.squircleshape.SquircleShape
@@ -103,12 +103,14 @@ fun SuperDropdown(
103103
enabled: Boolean = true
104104
) {
105105
val isDropdownExpanded = remember { mutableStateOf(false) }
106+
106107
if (!dropdownStates.contains(isDropdownExpanded)) dropdownStates.add(isDropdownExpanded)
107108
LaunchedEffect(isDropdownExpanded.value) {
108109
if (isDropdownExpanded.value) {
109-
dropdownStates.forEach { state -> if (state == isDropdownExpanded) state.value = false }
110+
dropdownStates.forEach { state -> if (state != isDropdownExpanded) state.value = false }
110111
}
111112
}
113+
112114
val hapticFeedback = LocalHapticFeedback.current
113115
val density = LocalDensity.current
114116
var alignLeft by rememberSaveable { mutableStateOf(true) }
@@ -133,8 +135,15 @@ fun SuperDropdown(
133135
)
134136
val insideHeightPx by rememberUpdatedState(with(density) { insideMargin.height.toPx() }.roundToInt())
135137

138+
BackHandler(enabled = isPopupShowing()) {
139+
dismissPopup(isDropdownExpanded)
140+
}
141+
136142
BasicComponent(
137-
onClick = { isDropdownExpanded.value = enabled },
143+
onClick = {
144+
isDropdownExpanded.value = enabled
145+
hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress)
146+
},
138147
modifier = modifier
139148
.pointerInput(Unit) {
140149
awaitPointerEventScope {
@@ -178,15 +187,7 @@ fun SuperDropdown(
178187
},
179188
enabled = enabled
180189
)
181-
BackHandler(
182-
enabled = isDropdownExpanded.value
183-
) {
184-
dismissPopup()
185-
isDropdownExpanded.value = false
186-
}
187-
188190
if (isDropdownExpanded.value) {
189-
hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress)
190191
showPopup(
191192
content = {
192193
Box(
@@ -198,10 +199,11 @@ fun SuperDropdown(
198199
}
199200
.fillMaxSize()
200201
.pointerInput(Unit) {
201-
detectTapGestures(onTap = {
202-
dismissPopup()
203-
isDropdownExpanded.value = false
204-
})
202+
detectTapGestures(
203+
onTap = {
204+
dismissPopup(isDropdownExpanded)
205+
}
206+
)
205207
}
206208
.offset(y = offsetPx.dp / density.density)
207209
) {
@@ -228,22 +230,21 @@ fun SuperDropdown(
228230
.align(if (alignLeft && !alwaysRight) AbsoluteAlignment.TopLeft else AbsoluteAlignment.TopRight)
229231
.graphicsLayer(
230232
shadowElevation = 18f,
231-
shape = SquircleShape(18.dp),
232-
clip = false
233+
shape = SquircleShape(18.dp)
233234
)
234235
.clip(SquircleShape(18.dp))
235236
.background(MiuixTheme.colorScheme.surface)
236237
) {
237238
item {
238239
items.forEachIndexed { index, option ->
239240
DropdownImpl(
240-
options = items,
241+
text = option,
242+
optionSize = items.size,
241243
isSelected = items[selectedIndex] == option,
242244
onSelectedIndexChange = {
243245
hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress)
244246
onSelectedIndexChange(it)
245-
dismissPopup()
246-
isDropdownExpanded.value = false
247+
dismissPopup(isDropdownExpanded)
247248
},
248249
textWidthDp = textWidthDp,
249250
index = index
@@ -260,23 +261,24 @@ fun SuperDropdown(
260261
/**
261262
* The implementation of the dropdown.
262263
*
263-
* @param options The options of the dropdown.
264+
* @param text The text of the current option.
265+
* @param optionSize The size of the options.
264266
* @param isSelected Whether the option is selected.
265267
* @param index The index of the current option in the options.
266268
* @param onSelectedIndexChange The callback when the index is selected.
267269
* @param textWidthDp The maximum width of text in options.
268270
*/
269271
@Composable
270272
fun DropdownImpl(
271-
options: List<String>,
273+
text: String,
274+
optionSize: Int,
272275
isSelected: Boolean,
273276
index: Int,
274277
onSelectedIndexChange: (Int) -> Unit,
275278
textWidthDp: Dp?
276279
) {
277-
val dropdownInteractionSource = remember { MutableInteractionSource() }
278280
val additionalTopPadding = if (index == 0) 24.dp else 14.dp
279-
val additionalBottomPadding = if (index == options.size - 1) 24.dp else 14.dp
281+
val additionalBottomPadding = if (index == optionSize - 1) 24.dp else 14.dp
280282
val textColor = if (isSelected) {
281283
MiuixTheme.colorScheme.onTertiaryContainer
282284
} else {
@@ -305,7 +307,7 @@ fun DropdownImpl(
305307
) {
306308
Text(
307309
modifier = Modifier.width(textWidthDp ?: 50.dp),
308-
text = options[index],
310+
text = text,
309311
fontSize = 15.sp,
310312
fontWeight = FontWeight.Medium,
311313
color = textColor,
@@ -350,8 +352,7 @@ fun calculateOffsetPx(
350352
}
351353
}
352354

353-
354355
/**
355356
* Only one dropdown is allowed to be displayed at a time.
356357
*/
357-
val dropdownStates = mutableStateListOf<MutableState<Boolean>>()
358+
val dropdownStates = mutableStateListOf<MutableState<Boolean>>()

miuix/src/commonMain/kotlin/top/yukonga/miuix/kmp/utils/MiuixPopupUtil.kt

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import androidx.compose.animation.slideOutVertically
1212
import androidx.compose.foundation.background
1313
import androidx.compose.foundation.layout.fillMaxSize
1414
import androidx.compose.runtime.Composable
15+
import androidx.compose.runtime.MutableState
1516
import androidx.compose.runtime.mutableStateOf
1617
import androidx.compose.ui.Modifier
1718
import androidx.compose.ui.zIndex
@@ -39,16 +40,28 @@ class MiuixPopupUtil {
3940
fun showDialog(
4041
content: (@Composable () -> Unit)? = null,
4142
) {
42-
isPopupShowing.value = false
43+
if (isDialogShowing.value) return
4344
isDialogShowing.value = true
4445
dialogContext.value = content
4546
}
4647

48+
/**
49+
* Check if the dialog is showing.
50+
*/
51+
fun isDialogShowing(): Boolean {
52+
return isDialogShowing.value
53+
}
54+
4755
/**
4856
* Dismiss the dialog.
57+
*
58+
* @param show The show state of the dialog.
4959
*/
50-
fun dismissDialog() {
60+
fun dismissDialog(
61+
show: MutableState<Boolean>,
62+
) {
5163
isDialogShowing.value = false
64+
show.value = false
5265
}
5366

5467
/**
@@ -60,15 +73,28 @@ class MiuixPopupUtil {
6073
fun showPopup(
6174
content: (@Composable () -> Unit)? = null,
6275
) {
76+
if (isPopupShowing.value) return
6377
isPopupShowing.value = true
6478
popupContext.value = content
6579
}
6680

81+
/**
82+
* Check if the popup is showing.
83+
*/
84+
fun isPopupShowing(): Boolean {
85+
return isPopupShowing.value
86+
}
87+
6788
/**
6889
* Dismiss the popup.
90+
*
91+
* @param show The show state of the popup.
6992
*/
70-
fun dismissPopup() {
93+
fun dismissPopup(
94+
show: MutableState<Boolean>,
95+
) {
7196
isPopupShowing.value = false
97+
show.value = false
7298
}
7399

74100
/**

0 commit comments

Comments
 (0)