Skip to content

Commit f367482

Browse files
CopilotYuKongA
andcommitted
library: Optimize some components
--------- Co-Authored-By: copilot-swe-agent[bot] <[email protected]> Co-Authored-By: YuKongA <[email protected]>
1 parent eca9410 commit f367482

File tree

16 files changed

+174
-154
lines changed

16 files changed

+174
-154
lines changed

example/src/commonMain/kotlin/UITest.kt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ import top.yukonga.miuix.kmp.icon.icons.useful.NavigatorSwitch
8787
import top.yukonga.miuix.kmp.icon.icons.useful.Order
8888
import top.yukonga.miuix.kmp.icon.icons.useful.Settings
8989
import top.yukonga.miuix.kmp.theme.MiuixTheme
90+
import top.yukonga.miuix.kmp.utils.WindowSize
9091
import top.yukonga.miuix.kmp.utils.getWindowSize
9192
import top.yukonga.miuix.kmp.utils.overScrollVertical
9293
import top.yukonga.miuix.kmp.utils.scrollEndHaptic
@@ -229,7 +230,7 @@ private fun WideScreenLayout(
229230
pagerState: PagerState,
230231
topAppBarScrollBehaviorList: List<ScrollBehavior>,
231232
currentScrollBehavior: ScrollBehavior,
232-
windowSize: Any,
233+
windowSize: WindowSize,
233234
colorMode: MutableState<Int>
234235
) {
235236
val layoutDirection = LocalLayoutDirection.current
@@ -274,7 +275,7 @@ private fun WideScreenPanel(
274275
onPageSelected: (Int) -> Unit,
275276
barScrollBehavior: ScrollBehavior,
276277
uiState: UIState,
277-
windowSize: Any,
278+
windowSize: WindowSize,
278279
layoutDirection: LayoutDirection
279280
) {
280281
Scaffold(

iosApp/iosApp/Info.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<key>CFBundleShortVersionString</key>
1818
<string>1.0.4</string>
1919
<key>CFBundleVersion</key>
20-
<string>500</string>
20+
<string>501</string>
2121
<key>LSRequiresIPhoneOS</key>
2222
<true/>
2323
<key>CADisableMinimumFrameDurationOnPhone</key>

miuix/src/commonMain/kotlin/top/yukonga/miuix/kmp/basic/Button.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ fun Button(
5151
content: @Composable RowScope.() -> Unit
5252
) {
5353
val shape = remember(cornerRadius) { SmoothRoundedCornerShape(cornerRadius) }
54-
val color by rememberUpdatedState(if (enabled) colors.color else colors.disabledColor)
54+
val color = if (enabled) colors.color else colors.disabledColor
5555
Surface(
5656
onClick = onClick,
5757
enabled = enabled,
@@ -96,8 +96,8 @@ fun TextButton(
9696
insideMargin: PaddingValues = ButtonDefaults.InsideMargin
9797
) {
9898
val shape = remember(cornerRadius) { SmoothRoundedCornerShape(cornerRadius) }
99-
val color by rememberUpdatedState(if (enabled) colors.color else colors.disabledColor)
100-
val textColor by rememberUpdatedState(if (enabled) colors.textColor else colors.disabledTextColor)
99+
val color = if (enabled) colors.color else colors.disabledColor
100+
val textColor = if (enabled) colors.textColor else colors.disabledTextColor
101101
Surface(
102102
onClick = onClick,
103103
enabled = enabled,

miuix/src/commonMain/kotlin/top/yukonga/miuix/kmp/basic/Card.kt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -102,21 +102,21 @@ fun Card(
102102
content: @Composable ColumnScope.() -> Unit,
103103
) {
104104
val interactionSource = remember { MutableInteractionSource() }
105-
val currentOnClick by rememberUpdatedState(onClick)
106-
val currentOnLongPress by rememberUpdatedState(onLongPress)
107105

108-
val pressFeedbackModifier = when (pressFeedbackType) {
109-
PressFeedbackType.None -> Modifier
110-
PressFeedbackType.Sink -> Modifier.pressSink(interactionSource)
111-
PressFeedbackType.Tilt -> Modifier.pressTilt(interactionSource)
106+
val pressFeedbackModifier = remember(pressFeedbackType, interactionSource) {
107+
when (pressFeedbackType) {
108+
PressFeedbackType.None -> Modifier
109+
PressFeedbackType.Sink -> Modifier.pressSink(interactionSource)
110+
PressFeedbackType.Tilt -> Modifier.pressTilt(interactionSource)
111+
}
112112
}
113113

114114
BasicCard(
115115
modifier = modifier
116-
.pointerInput(Unit) {
116+
.pointerInput(onClick, onLongPress) {
117117
detectTapGestures(
118-
onTap = { currentOnClick?.invoke() },
119-
onLongPress = { currentOnLongPress?.invoke() }
118+
onTap = { onClick?.invoke() },
119+
onLongPress = { onLongPress?.invoke() }
120120
)
121121
}
122122
.pointerInput(interactionSource) {

miuix/src/commonMain/kotlin/top/yukonga/miuix/kmp/basic/Checkbox.kt

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import androidx.compose.runtime.LaunchedEffect
2828
import androidx.compose.runtime.Stable
2929
import androidx.compose.runtime.getValue
3030
import androidx.compose.runtime.remember
31-
import androidx.compose.runtime.rememberUpdatedState
3231
import androidx.compose.ui.Alignment
3332
import androidx.compose.ui.Modifier
3433
import androidx.compose.ui.draw.clip
@@ -65,46 +64,44 @@ fun Checkbox(
6564
colors: CheckboxColors = CheckboxDefaults.checkboxColors(),
6665
enabled: Boolean = true,
6766
) {
68-
val isChecked by rememberUpdatedState(checked)
69-
val currentOnCheckedChange by rememberUpdatedState(onCheckedChange)
70-
7167
val hapticFeedback = LocalHapticFeedback.current
7268

7369
val interactionSource = remember { MutableInteractionSource() }
7470
val isPressed by interactionSource.collectIsPressedAsState()
7571
val isDragged by interactionSource.collectIsDraggedAsState()
7672
val isHovered by interactionSource.collectIsHoveredAsState()
7773

78-
val springSpec = spring<Float>(
79-
dampingRatio = Spring.DampingRatioLowBouncy,
80-
stiffness = Spring.StiffnessMedium
81-
)
74+
val springSpec = remember {
75+
spring<Float>(
76+
dampingRatio = Spring.DampingRatioLowBouncy,
77+
stiffness = Spring.StiffnessMedium
78+
)
79+
}
8280

8381
val size by animateFloatAsState(
8482
targetValue = if (!enabled) 1f else if (isPressed || isDragged || isHovered) 0.95f else 1f,
8583
animationSpec = springSpec
8684
)
8785

8886
val backgroundColor by animateColorAsState(
89-
targetValue = if (isChecked) colors.checkedBackgroundColor(enabled) else colors.uncheckedBackgroundColor(enabled),
87+
targetValue = if (checked) colors.checkedBackgroundColor(enabled) else colors.uncheckedBackgroundColor(enabled),
9088
animationSpec = tween(durationMillis = 300, easing = FastOutSlowInEasing)
9189
)
9290

9391
val foregroundColor by animateColorAsState(
94-
targetValue = if (isChecked) colors.checkedForegroundColor(enabled) else colors.uncheckedForegroundColor(enabled),
92+
targetValue = if (checked) colors.checkedForegroundColor(enabled) else colors.uncheckedForegroundColor(enabled),
9593
animationSpec = tween(durationMillis = 300, easing = FastOutSlowInEasing)
9694
)
9795

98-
val checkmarkAnim = rememberCheckmarkAnimationState(isChecked)
96+
val checkmarkAnim = rememberCheckmarkAnimationState(checked)
9997

10098
val finalModifier = if (onCheckedChange != null) {
10199
Modifier.toggleable(
102-
value = isChecked,
100+
value = checked,
103101
onValueChange = {
104-
if (currentOnCheckedChange == null) return@toggleable
105-
currentOnCheckedChange?.invoke(!isChecked)
102+
onCheckedChange.invoke(!checked)
106103
hapticFeedback.performHapticFeedback(
107-
if (isChecked) HapticFeedbackType.ToggleOn else HapticFeedbackType.ToggleOff
104+
if (checked) HapticFeedbackType.ToggleOn else HapticFeedbackType.ToggleOff
108105
)
109106
},
110107
enabled = enabled,

miuix/src/commonMain/kotlin/top/yukonga/miuix/kmp/basic/Component.kt

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ fun BasicComponent(
6161
) {
6262
@Suppress("NAME_SHADOWING")
6363
val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
64+
val indication = LocalIndication.current
6465

6566
val holdDown = remember { mutableStateOf<HoldDownInteraction.HoldDown?>(null) }
6667
LaunchedEffect(holdDownState) {
@@ -76,19 +77,21 @@ fun BasicComponent(
7677
}
7778
}
7879

80+
val clickableModifier = remember(onClick, enabled, interactionSource) {
81+
if (onClick != null && enabled) {
82+
Modifier.clickable(
83+
indication = indication,
84+
interactionSource = interactionSource,
85+
onClick = onClick
86+
)
87+
} else Modifier
88+
}
89+
7990
SubcomposeLayout(
8091
modifier = modifier
8192
.heightIn(min = 56.dp)
8293
.fillMaxWidth()
83-
.then(
84-
if (onClick != null && enabled) {
85-
Modifier.clickable(
86-
indication = LocalIndication.current,
87-
interactionSource = interactionSource,
88-
onClick = { onClick.invoke() }
89-
)
90-
} else Modifier
91-
)
94+
.then(clickableModifier)
9295
.padding(insideMargin)
9396
) { constraints ->
9497
val looseConstraints = constraints.copy(minWidth = 0, minHeight = 0)

miuix/src/commonMain/kotlin/top/yukonga/miuix/kmp/basic/IconButton.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ fun IconButton(
5353
minWidth: Dp = IconButtonDefaults.MinWidth,
5454
content: @Composable () -> Unit
5555
) {
56-
val currentOnClick by rememberUpdatedState(onClick)
5756
val shape = remember(cornerRadius) { SmoothRoundedCornerShape(cornerRadius) }
5857
val interactionSource = remember { MutableInteractionSource() }
5958
val holdDown = remember { mutableStateOf<HoldDownInteraction.HoldDown?>(null) }
@@ -81,7 +80,7 @@ fun IconButton(
8180
role = Role.Button,
8281
indication = LocalIndication.current,
8382
interactionSource = interactionSource,
84-
onClick = currentOnClick
83+
onClick = onClick
8584
),
8685
contentAlignment = Alignment.Center
8786
) {

miuix/src/commonMain/kotlin/top/yukonga/miuix/kmp/basic/ListPopup.kt

Lines changed: 69 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ import top.yukonga.miuix.kmp.theme.MiuixTheme
4343
import top.yukonga.miuix.kmp.utils.BackHandler
4444
import top.yukonga.miuix.kmp.utils.MiuixPopupUtils.Companion.PopupLayout
4545
import top.yukonga.miuix.kmp.utils.SmoothRoundedCornerShape
46-
import top.yukonga.miuix.kmp.utils.WindowSize
4746
import top.yukonga.miuix.kmp.utils.getWindowSize
4847
import kotlin.math.min
4948

@@ -76,9 +75,6 @@ fun ListPopup(
7675
) {
7776
if (!show.value) return
7877

79-
val density = LocalDensity.current
80-
val layoutDirection = LocalLayoutDirection.current
81-
8278
val windowSize by rememberUpdatedState(getWindowSize())
8379
var parentBounds by remember { mutableStateOf(IntRect.Zero) }
8480

@@ -96,8 +92,16 @@ fun ListPopup(
9692
}
9793
}
9894
) { _, _ -> layout(0, 0) {} }
95+
if (parentBounds == IntRect.Zero) return
9996

100-
val popupMargin = remember {
97+
val density = LocalDensity.current
98+
val layoutDirection = LocalLayoutDirection.current
99+
val displayCutout = WindowInsets.displayCutout.asPaddingValues()
100+
val statusBars = WindowInsets.statusBars.asPaddingValues()
101+
val navigationBars = WindowInsets.navigationBars.asPaddingValues()
102+
val captionBar = WindowInsets.captionBar.asPaddingValues()
103+
104+
val popupMargin = remember(windowSize, density) {
101105
with(density) {
102106
IntRect(
103107
left = popupPositionProvider.getMargins().calculateLeftPadding(layoutDirection).roundToPx(),
@@ -108,17 +112,19 @@ fun ListPopup(
108112
}
109113
}
110114

111-
val windowBounds = with(density) {
112-
IntRect(
113-
left = WindowInsets.displayCutout.asPaddingValues().calculateLeftPadding(layoutDirection).roundToPx(),
114-
top = WindowInsets.statusBars.asPaddingValues().calculateTopPadding().roundToPx(),
115-
right = windowSize.width - WindowInsets.displayCutout.asPaddingValues().calculateRightPadding(layoutDirection).roundToPx(),
116-
bottom = windowSize.height - WindowInsets.navigationBars.asPaddingValues().calculateBottomPadding()
117-
.roundToPx() - WindowInsets.captionBar.asPaddingValues().calculateBottomPadding().roundToPx()
118-
)
115+
val windowBounds = remember(windowSize, density) {
116+
with(density) {
117+
IntRect(
118+
left = displayCutout.calculateLeftPadding(layoutDirection).roundToPx(),
119+
top = statusBars.calculateTopPadding().roundToPx(),
120+
right = windowSize.width - displayCutout.calculateRightPadding(layoutDirection).roundToPx(),
121+
bottom = windowSize.height - navigationBars.calculateBottomPadding()
122+
.roundToPx() - captionBar.calculateBottomPadding().roundToPx()
123+
)
124+
}
119125
}
120126

121-
val transformOrigin = remember(parentBounds, popupMargin, windowSize, alignment, density) {
127+
val transformOrigin = remember(windowSize, alignment, density) {
122128
val xInWindow = when (alignment) {
123129
PopupPositionProvider.Align.Right,
124130
PopupPositionProvider.Align.TopRight,
@@ -133,63 +139,61 @@ fun ListPopup(
133139
)
134140
}
135141

136-
if (parentBounds != IntRect.Zero && windowSize != WindowSize(0, 0)) {
137-
PopupLayout(
138-
visible = show,
139-
enableWindowDim = enableWindowDim,
140-
transformOrigin = { transformOrigin },
141-
) {
142-
val shape = remember { SmoothRoundedCornerShape(16.dp) }
143-
val elevationPx = with(density) { shadowElevation.toPx() }
142+
PopupLayout(
143+
visible = show,
144+
enableWindowDim = enableWindowDim,
145+
transformOrigin = { transformOrigin },
146+
) {
147+
val shape = remember { SmoothRoundedCornerShape(16.dp) }
148+
val elevationPx = with(density) { shadowElevation.toPx() }
144149

145-
Box(
146-
modifier = popupModifier
147-
.pointerInput(onDismissRequest) {
148-
detectTapGestures(
149-
onTap = { onDismissRequest?.invoke() }
150-
)
151-
}
152-
.layout { measurable, constraints ->
153-
val placeable = measurable.measure(
154-
constraints.copy(
155-
minWidth = if (minWidth.roundToPx() <= windowSize.width) minWidth.roundToPx() else windowSize.width,
156-
minHeight = if (50.dp.roundToPx() <= windowSize.height) 50.dp.roundToPx() else windowSize.height,
157-
maxHeight = maxHeight?.roundToPx()?.coerceAtLeast(50.dp.roundToPx())
158-
?: (windowBounds.height - popupMargin.top - popupMargin.bottom).coerceAtLeast(
159-
50.dp.roundToPx()
160-
),
161-
maxWidth = if (minWidth.roundToPx() <= windowSize.width) windowSize.width else minWidth.roundToPx()
162-
)
150+
Box(
151+
modifier = popupModifier
152+
.pointerInput(onDismissRequest) {
153+
detectTapGestures(
154+
onTap = { onDismissRequest?.invoke() }
155+
)
156+
}
157+
.layout { measurable, constraints ->
158+
val placeable = measurable.measure(
159+
constraints.copy(
160+
minWidth = if (minWidth.roundToPx() <= windowSize.width) minWidth.roundToPx() else windowSize.width,
161+
minHeight = if (50.dp.roundToPx() <= windowSize.height) 50.dp.roundToPx() else windowSize.height,
162+
maxHeight = maxHeight?.roundToPx()?.coerceAtLeast(50.dp.roundToPx())
163+
?: (windowBounds.height - popupMargin.top - popupMargin.bottom).coerceAtLeast(
164+
50.dp.roundToPx()
165+
),
166+
maxWidth = if (minWidth.roundToPx() <= windowSize.width) windowSize.width else minWidth.roundToPx()
163167
)
164-
val measuredSize = IntSize(placeable.width, placeable.height)
168+
)
169+
val measuredSize = IntSize(placeable.width, placeable.height)
165170

166-
val calculatedOffset = popupPositionProvider.calculatePosition(
167-
parentBounds,
168-
windowBounds,
169-
layoutDirection,
170-
measuredSize,
171-
popupMargin,
172-
alignment
173-
)
171+
val calculatedOffset = popupPositionProvider.calculatePosition(
172+
parentBounds,
173+
windowBounds,
174+
layoutDirection,
175+
measuredSize,
176+
popupMargin,
177+
alignment
178+
)
174179

175-
layout(constraints.maxWidth, constraints.maxHeight) {
176-
placeable.place(calculatedOffset)
177-
}
180+
layout(constraints.maxWidth, constraints.maxHeight) {
181+
placeable.place(calculatedOffset)
178182
}
179-
) {
180-
Box(
181-
modifier = Modifier
182-
.graphicsLayer(
183-
clip = true,
184-
shape = shape,
185-
shadowElevation = elevationPx,
186-
ambientShadowColor = MiuixTheme.colorScheme.windowDimming,
187-
spotShadowColor = MiuixTheme.colorScheme.windowDimming
188-
)
189-
.background(MiuixTheme.colorScheme.surface)
190-
) {
191-
content()
192183
}
184+
) {
185+
Box(
186+
modifier = Modifier
187+
.graphicsLayer(
188+
clip = true,
189+
shape = shape,
190+
shadowElevation = elevationPx,
191+
ambientShadowColor = MiuixTheme.colorScheme.windowDimming,
192+
spotShadowColor = MiuixTheme.colorScheme.windowDimming
193+
)
194+
.background(MiuixTheme.colorScheme.surface)
195+
) {
196+
content()
193197
}
194198
}
195199
}

0 commit comments

Comments
 (0)