Skip to content

Commit 172724d

Browse files
committed
library: Add a basic Icon
1 parent b2d1e0d commit 172724d

File tree

5 files changed

+141
-14
lines changed

5 files changed

+141
-14
lines changed

composeApp/src/commonMain/kotlin/MainPage.kt

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import androidx.compose.ui.unit.dp
2828
import component.OtherComponent
2929
import component.TextComponent
3030
import top.yukonga.miuix.kmp.basic.BasicComponent
31+
import top.yukonga.miuix.kmp.basic.Icon
3132
import top.yukonga.miuix.kmp.basic.InputField
3233
import top.yukonga.miuix.kmp.basic.LazyColumn
3334
import top.yukonga.miuix.kmp.basic.ScrollBehavior
@@ -66,13 +67,10 @@ fun MainPage(
6667
onExpandedChange = { expanded = it },
6768
label = "Search",
6869
leadingIcon = {
69-
Image(
70+
Icon(
7071
modifier = Modifier.padding(horizontal = 16.dp),
7172
imageVector = MiuixIcons.Search,
72-
colorFilter = BlendModeColorFilter(
73-
MiuixTheme.colorScheme.onSurfaceContainer,
74-
BlendMode.SrcIn
75-
),
73+
tint = MiuixTheme.colorScheme.onSurfaceContainer,
7674
contentDescription = "Search"
7775
)
7876
},

composeApp/src/commonMain/kotlin/UITest.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import kotlinx.coroutines.flow.debounce
3939
import kotlinx.coroutines.launch
4040
import top.yukonga.miuix.kmp.basic.FloatingActionButton
4141
import top.yukonga.miuix.kmp.basic.HorizontalPager
42+
import top.yukonga.miuix.kmp.basic.Icon
4243
import top.yukonga.miuix.kmp.basic.IconButton
4344
import top.yukonga.miuix.kmp.basic.MiuixScrollBehavior
4445
import top.yukonga.miuix.kmp.basic.NavigationBar
@@ -49,7 +50,6 @@ import top.yukonga.miuix.kmp.basic.TopAppBar
4950
import top.yukonga.miuix.kmp.basic.rememberTopAppBarState
5051
import top.yukonga.miuix.kmp.icon.MiuixIcons
5152
import top.yukonga.miuix.kmp.icon.icons.GitHub
52-
import top.yukonga.miuix.kmp.theme.MiuixTheme
5353
import utils.FPSMonitor
5454

5555
@OptIn(FlowPreview::class)
@@ -111,9 +111,8 @@ fun UITest(
111111
modifier = Modifier.padding(end = 12.dp),
112112
onClick = { }
113113
) {
114-
Image(
114+
Icon(
115115
imageVector = Icons.Rounded.Menu,
116-
colorFilter = ColorFilter.tint(MiuixTheme.colorScheme.onBackground.copy(0.8f)),
117116
contentDescription = "Menu"
118117
)
119118
}

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

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import androidx.compose.animation.expandVertically
55
import androidx.compose.animation.fadeIn
66
import androidx.compose.animation.fadeOut
77
import androidx.compose.animation.shrinkVertically
8-
import androidx.compose.foundation.Image
98
import androidx.compose.foundation.layout.Arrangement
109
import androidx.compose.foundation.layout.Row
1110
import androidx.compose.foundation.layout.Spacer
@@ -23,13 +22,13 @@ import androidx.compose.runtime.remember
2322
import androidx.compose.runtime.setValue
2423
import androidx.compose.ui.Alignment
2524
import androidx.compose.ui.Modifier
26-
import androidx.compose.ui.graphics.ColorFilter
2725
import androidx.compose.ui.unit.dp
2826
import top.yukonga.miuix.kmp.basic.BasicComponent
2927
import top.yukonga.miuix.kmp.basic.Box
3028
import top.yukonga.miuix.kmp.basic.Button
3129
import top.yukonga.miuix.kmp.basic.Card
3230
import top.yukonga.miuix.kmp.basic.Checkbox
31+
import top.yukonga.miuix.kmp.basic.Icon
3332
import top.yukonga.miuix.kmp.basic.SmallTitle
3433
import top.yukonga.miuix.kmp.basic.Switch
3534
import top.yukonga.miuix.kmp.basic.Text
@@ -117,10 +116,9 @@ fun TextComponent() {
117116
Box(
118117
contentAlignment = Alignment.TopStart,
119118
) {
120-
Image(
121-
colorFilter = ColorFilter.tint(MiuixTheme.colorScheme.onBackground),
119+
Icon(
122120
imageVector = Icons.Rounded.AccountBox,
123-
contentDescription = "Person",
121+
contentDescription = "Account",
124122
)
125123
}
126124
},
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
package top.yukonga.miuix.kmp.basic
2+
3+
import androidx.compose.foundation.layout.Box
4+
import androidx.compose.foundation.layout.size
5+
import androidx.compose.runtime.Composable
6+
import androidx.compose.runtime.remember
7+
import androidx.compose.ui.Modifier
8+
import androidx.compose.ui.draw.paint
9+
import androidx.compose.ui.geometry.Size
10+
import androidx.compose.ui.graphics.Color
11+
import androidx.compose.ui.graphics.ColorFilter
12+
import androidx.compose.ui.graphics.ImageBitmap
13+
import androidx.compose.ui.graphics.painter.BitmapPainter
14+
import androidx.compose.ui.graphics.painter.Painter
15+
import androidx.compose.ui.graphics.toolingGraphicsLayer
16+
import androidx.compose.ui.graphics.vector.ImageVector
17+
import androidx.compose.ui.graphics.vector.rememberVectorPainter
18+
import androidx.compose.ui.layout.ContentScale
19+
import androidx.compose.ui.semantics.Role
20+
import androidx.compose.ui.semantics.contentDescription
21+
import androidx.compose.ui.semantics.role
22+
import androidx.compose.ui.semantics.semantics
23+
import androidx.compose.ui.unit.dp
24+
import top.yukonga.miuix.kmp.theme.MiuixTheme
25+
26+
/**
27+
* A [Icon] component that draws [imageVector] using [tint], with a default value.
28+
*
29+
* @param imageVector [ImageVector] to draw inside this icon
30+
* @param contentDescription text used by accessibility services to describe what this icon
31+
* represents. This should always be provided unless this icon is used for decorative purposes,
32+
* and does not represent a meaningful action that a user can take. This text should be localized,
33+
* such as by using [androidx.compose.ui.res.stringResource] or similar
34+
* @param modifier the [Modifier] to be applied to this icon
35+
* @param tint tint to be applied to [imageVector]. If [Color.Unspecified] is provided, then no tint
36+
* is applied.
37+
*/
38+
@Composable
39+
fun Icon(
40+
imageVector: ImageVector,
41+
contentDescription: String?,
42+
modifier: Modifier = Modifier,
43+
tint: Color = MiuixTheme.colorScheme.onBackground
44+
) {
45+
Icon(
46+
painter = rememberVectorPainter(imageVector),
47+
contentDescription = contentDescription,
48+
modifier = modifier,
49+
tint = tint
50+
)
51+
}
52+
53+
/**
54+
* A [Icon] component that draws [bitmap] using [tint], with a default value.
55+
*
56+
* @param bitmap [ImageBitmap] to draw inside this icon
57+
* @param contentDescription text used by accessibility services to describe what this icon
58+
* represents. This should always be provided unless this icon is used for decorative purposes,
59+
* and does not represent a meaningful action that a user can take. This text should be localized,
60+
* such as by using [androidx.compose.ui.res.stringResource] or similar
61+
* @param modifier the [Modifier] to be applied to this icon
62+
* @param tint tint to be applied to [bitmap]. If [Color.Unspecified] is provided, then no tint is
63+
* applied.
64+
*/
65+
@Composable
66+
fun Icon(
67+
bitmap: ImageBitmap,
68+
contentDescription: String?,
69+
modifier: Modifier = Modifier,
70+
tint: Color = MiuixTheme.colorScheme.onBackground
71+
) {
72+
val painter = remember(bitmap) { BitmapPainter(bitmap) }
73+
Icon(
74+
painter = painter,
75+
contentDescription = contentDescription,
76+
modifier = modifier,
77+
tint = tint
78+
)
79+
}
80+
81+
/**
82+
* A [Icon] component that draws [painter] using [tint], with a default value.
83+
*
84+
* @param painter [Painter] to draw inside this icon
85+
* @param contentDescription text used by accessibility services to describe what this icon
86+
* represents. This should always be provided unless this icon is used for decorative purposes,
87+
* and does not represent a meaningful action that a user can take. This text should be localized,
88+
* such as by using [androidx.compose.ui.res.stringResource] or similar
89+
* @param modifier the [Modifier] to be applied to this icon
90+
* @param tint tint to be applied to [painter]. If [Color.Unspecified] is provided, then no tint is
91+
* applied.
92+
*/
93+
@Composable
94+
fun Icon(
95+
painter: Painter,
96+
contentDescription: String?,
97+
modifier: Modifier = Modifier,
98+
tint: Color = MiuixTheme.colorScheme.onBackground
99+
) {
100+
val colorFilter =
101+
remember(tint) { if (tint == Color.Unspecified) null else ColorFilter.tint(tint) }
102+
val semantics =
103+
if (contentDescription != null) {
104+
Modifier.semantics {
105+
this.contentDescription = contentDescription
106+
this.role = Role.Image
107+
}
108+
} else {
109+
Modifier
110+
}
111+
Box(
112+
modifier
113+
.toolingGraphicsLayer()
114+
.defaultSizeFor(painter)
115+
.paint(painter, colorFilter = colorFilter, contentScale = ContentScale.Fit)
116+
.then(semantics)
117+
)
118+
}
119+
120+
private fun Modifier.defaultSizeFor(painter: Painter) =
121+
this.then(
122+
if (painter.intrinsicSize == Size.Unspecified || painter.intrinsicSize.isInfinite()) {
123+
DefaultIconSizeModifier
124+
} else {
125+
Modifier
126+
}
127+
)
128+
129+
private fun Size.isInfinite() = width.isInfinite() && height.isInfinite()
130+
131+
// Default icon size, for icons with no intrinsic size information
132+
private val DefaultIconSizeModifier = Modifier.size(24.dp)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import top.yukonga.miuix.kmp.utils.SmoothRoundedCornerShape
2626
* @param backgroundColor The background color of of the [IconButton].
2727
* @param minHeight The minimum height of of the [IconButton].
2828
* @param minWidth The minimum width of the [IconButton].
29-
* @param content The content of this icon button, typically an [Image].
29+
* @param content The content of this icon button, typically an [Icon].
3030
*/
3131
@Composable
3232
fun IconButton(

0 commit comments

Comments
 (0)