From 8547f276050ec038afa9f83a59aa4657ea5762e2 Mon Sep 17 00:00:00 2001 From: "Joker.X" Date: Sat, 29 Nov 2025 18:32:31 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E5=AE=9E=E7=8E=B0=E4=B8=BB?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/joker/kit/MainActivity.kt | 6 +- .../kit/core/designsystem/component/Box.kt | 400 ++++++++++++++++ .../kit/core/designsystem/component/Column.kt | 444 ++++++++++++++++++ .../core/designsystem/component/LazyList.kt | 306 ++++++++++++ .../kit/core/designsystem/component/Row.kt | 347 ++++++++++++++ .../kit/core/designsystem/component/Scroll.kt | 235 +++++++++ .../kit/core/designsystem/component/Spacer.kt | 141 ++++++ .../kit/core/designsystem/theme/Color.kt | 306 ++++++++++++ .../kit/core/designsystem/theme/Shape.kt | 83 ++++ .../joker/kit/core/designsystem/theme/Size.kt | 117 +++++ .../kit/core/designsystem/theme/Theme.kt | 155 ++++++ .../joker/kit/core/designsystem/theme/Type.kt | 194 ++++++++ .../main/java/com/joker/kit/ui/theme/Color.kt | 11 - .../main/java/com/joker/kit/ui/theme/Theme.kt | 58 --- .../main/java/com/joker/kit/ui/theme/Type.kt | 34 -- 15 files changed, 2731 insertions(+), 106 deletions(-) create mode 100644 app/src/main/java/com/joker/kit/core/designsystem/component/Box.kt create mode 100644 app/src/main/java/com/joker/kit/core/designsystem/component/Column.kt create mode 100644 app/src/main/java/com/joker/kit/core/designsystem/component/LazyList.kt create mode 100644 app/src/main/java/com/joker/kit/core/designsystem/component/Row.kt create mode 100644 app/src/main/java/com/joker/kit/core/designsystem/component/Scroll.kt create mode 100644 app/src/main/java/com/joker/kit/core/designsystem/component/Spacer.kt create mode 100644 app/src/main/java/com/joker/kit/core/designsystem/theme/Color.kt create mode 100644 app/src/main/java/com/joker/kit/core/designsystem/theme/Shape.kt create mode 100644 app/src/main/java/com/joker/kit/core/designsystem/theme/Size.kt create mode 100644 app/src/main/java/com/joker/kit/core/designsystem/theme/Theme.kt create mode 100644 app/src/main/java/com/joker/kit/core/designsystem/theme/Type.kt delete mode 100644 app/src/main/java/com/joker/kit/ui/theme/Color.kt delete mode 100644 app/src/main/java/com/joker/kit/ui/theme/Theme.kt delete mode 100644 app/src/main/java/com/joker/kit/ui/theme/Type.kt diff --git a/app/src/main/java/com/joker/kit/MainActivity.kt b/app/src/main/java/com/joker/kit/MainActivity.kt index 6848dc2..6445793 100644 --- a/app/src/main/java/com/joker/kit/MainActivity.kt +++ b/app/src/main/java/com/joker/kit/MainActivity.kt @@ -11,14 +11,14 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview -import com.joker.kit.ui.theme.AndroidProjectComposeTheme +import com.joker.kit.core.designsystem.theme.AppTheme class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { - AndroidProjectComposeTheme { + AppTheme { Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding -> Greeting( name = "Android", @@ -41,7 +41,7 @@ fun Greeting(name: String, modifier: Modifier = Modifier) { @Preview(showBackground = true) @Composable fun GreetingPreview() { - AndroidProjectComposeTheme { + AppTheme { Greeting("Android") } } \ No newline at end of file diff --git a/app/src/main/java/com/joker/kit/core/designsystem/component/Box.kt b/app/src/main/java/com/joker/kit/core/designsystem/component/Box.kt new file mode 100644 index 0000000..0671acb --- /dev/null +++ b/app/src/main/java/com/joker/kit/core/designsystem/component/Box.kt @@ -0,0 +1,400 @@ +package com.joker.kit.core.designsystem.component + +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.BoxScope +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +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.Shape +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import com.joker.kit.core.designsystem.theme.SpacePaddingLarge +import com.joker.kit.core.designsystem.theme.SpacePaddingMedium +import com.joker.kit.core.designsystem.theme.SpacePaddingSmall + +/** + * 封装的Box组件,预设了常用的修饰符 + * + * @param modifier 额外的修饰符 + * @param contentAlignment 内容对齐方式 + * @param fillMaxSize 是否填充最大尺寸 + * @param fillMaxWidth 是否填充最大宽度(当fillMaxSize为false时生效) + * @param padding 内边距 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun AppBox( + modifier: Modifier = Modifier, + contentAlignment: Alignment = Alignment.TopStart, + fillMaxSize: Boolean = false, + fillMaxWidth: Boolean = true, + padding: Dp = 0.dp, + content: @Composable BoxScope.() -> Unit +) { + val finalModifier = modifier + .let { if (fillMaxSize) it.fillMaxSize() else if (fillMaxWidth) it.fillMaxWidth() else it } + .let { if (padding > 0.dp) it.padding(padding) else it } + + Box( + modifier = finalModifier, + contentAlignment = contentAlignment, + content = content + ) +} + +/** + * 填充整个屏幕的Box,便于创建全屏布局 + * + * @param modifier 额外的修饰符 + * @param contentAlignment 内容对齐方式 + * @param padding 内边距 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun FullScreenBox( + modifier: Modifier = Modifier, + contentAlignment: Alignment = Alignment.TopStart, + padding: PaddingValues = PaddingValues(0.dp), + content: @Composable BoxScope.() -> Unit +) { + Box( + modifier = modifier + .fillMaxSize() + .padding(padding), + contentAlignment = contentAlignment, + content = content + ) +} + +/** + * 居中Box组件,内容居中对齐 + * + * @param modifier 额外的修饰符 + * @param fillMaxSize 是否填充最大尺寸 + * @param padding 内边距 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun CenterBox( + modifier: Modifier = Modifier, + fillMaxSize: Boolean = true, + padding: Dp = 0.dp, + content: @Composable BoxScope.() -> Unit +) { + AppBox( + modifier = modifier, + contentAlignment = Alignment.Center, + fillMaxSize = fillMaxSize, + padding = padding, + content = content + ) +} + +/** + * 顶部居中对齐的Box组件 + * + * @param modifier 额外的修饰符 + * @param fillMaxSize 是否填充最大尺寸 + * @param fillMaxWidth 是否填充最大宽度 + * @param padding 内边距 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun TopCenterBox( + modifier: Modifier = Modifier, + fillMaxSize: Boolean = false, + fillMaxWidth: Boolean = true, + padding: Dp = 0.dp, + content: @Composable BoxScope.() -> Unit +) { + AppBox( + modifier = modifier, + contentAlignment = Alignment.TopCenter, + fillMaxSize = fillMaxSize, + fillMaxWidth = fillMaxWidth, + padding = padding, + content = content + ) +} + +/** + * 底部居中对齐的Box组件 + * + * @param modifier 额外的修饰符 + * @param fillMaxSize 是否填充最大尺寸 + * @param fillMaxWidth 是否填充最大宽度 + * @param padding 内边距 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun BottomCenterBox( + modifier: Modifier = Modifier, + fillMaxSize: Boolean = false, + fillMaxWidth: Boolean = true, + padding: Dp = 0.dp, + content: @Composable BoxScope.() -> Unit +) { + AppBox( + modifier = modifier, + contentAlignment = Alignment.BottomCenter, + fillMaxSize = fillMaxSize, + fillMaxWidth = fillMaxWidth, + padding = padding, + content = content + ) +} + +/** + * 左侧居中对齐的Box组件 + * + * @param modifier 额外的修饰符 + * @param fillMaxSize 是否填充最大尺寸 + * @param fillMaxWidth 是否填充最大宽度 + * @param padding 内边距 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun CenterStartBox( + modifier: Modifier = Modifier, + fillMaxSize: Boolean = false, + fillMaxWidth: Boolean = true, + padding: Dp = 0.dp, + content: @Composable BoxScope.() -> Unit +) { + AppBox( + modifier = modifier, + contentAlignment = Alignment.CenterStart, + fillMaxSize = fillMaxSize, + fillMaxWidth = fillMaxWidth, + padding = padding, + content = content + ) +} + +/** + * 右侧居中对齐的Box组件 + * + * @param modifier 额外的修饰符 + * @param fillMaxSize 是否填充最大尺寸 + * @param fillMaxWidth 是否填充最大宽度 + * @param padding 内边距 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun CenterEndBox( + modifier: Modifier = Modifier, + fillMaxSize: Boolean = false, + fillMaxWidth: Boolean = true, + padding: Dp = 0.dp, + content: @Composable BoxScope.() -> Unit +) { + AppBox( + modifier = modifier, + contentAlignment = Alignment.CenterEnd, + fillMaxSize = fillMaxSize, + fillMaxWidth = fillMaxWidth, + padding = padding, + content = content + ) +} + +/** + * 固定尺寸的Box组件 + * + * @param modifier 额外的修饰符 + * @param width 宽度 + * @param height 高度 + * @param contentAlignment 内容对齐方式 + * @param padding 内边距 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun FixedSizeBox( + modifier: Modifier = Modifier, + width: Dp, + height: Dp, + contentAlignment: Alignment = Alignment.Center, + padding: Dp = 0.dp, + content: @Composable BoxScope.() -> Unit +) { + Box( + modifier = modifier + .width(width) + .height(height) + .let { if (padding > 0.dp) it.padding(padding) else it }, + contentAlignment = contentAlignment, + content = content + ) +} + +/** + * 圆角Box组件,常用于卡片或容器 + * + * @param modifier 额外的修饰符 + * @param contentAlignment 内容对齐方式 + * @param fillMaxWidth 是否填充最大宽度 + * @param cornerRadius 圆角半径 + * @param padding 内边距 + * @param backgroundColor 背景颜色 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun RoundedBox( + modifier: Modifier = Modifier, + contentAlignment: Alignment = Alignment.TopStart, + fillMaxWidth: Boolean = true, + cornerRadius: Dp = 8.dp, + padding: Dp = SpacePaddingMedium, + backgroundColor: Color = MaterialTheme.colorScheme.surface, + content: @Composable BoxScope.() -> Unit +) { + Box( + modifier = modifier + .let { if (fillMaxWidth) it.fillMaxWidth() else it } + .clip(RoundedCornerShape(cornerRadius)) + .padding(padding), + contentAlignment = contentAlignment, + content = content + ) +} + +/** + * 带边框的Box组件,常用于强调区域 + * + * @param modifier 额外的修饰符 + * @param contentAlignment 内容对齐方式 + * @param fillMaxWidth 是否填充最大宽度 + * @param cornerRadius 圆角半径 + * @param padding 内边距 + * @param borderWidth 边框宽度 + * @param borderColor 边框颜色 + * @param shape 形状 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun BorderBox( + modifier: Modifier = Modifier, + contentAlignment: Alignment = Alignment.TopStart, + fillMaxWidth: Boolean = true, + cornerRadius: Dp = 8.dp, + padding: Dp = SpacePaddingMedium, + borderWidth: Dp = 1.dp, + borderColor: Color = MaterialTheme.colorScheme.outline, + shape: Shape = RoundedCornerShape(cornerRadius), + content: @Composable BoxScope.() -> Unit +) { + Box( + modifier = modifier + .let { if (fillMaxWidth) it.fillMaxWidth() else it } + .clip(shape) + .border(borderWidth, borderColor, shape) + .padding(padding), + contentAlignment = contentAlignment, + content = content + ) +} + +/** + * 带小内边距的Box,常用于紧凑型布局 + * + * @param modifier 额外的修饰符 + * @param contentAlignment 内容对齐方式 + * @param fillMaxSize 是否填充最大尺寸 + * @param fillMaxWidth 是否填充最大宽度 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun SmallPaddingBox( + modifier: Modifier = Modifier, + contentAlignment: Alignment = Alignment.TopStart, + fillMaxSize: Boolean = false, + fillMaxWidth: Boolean = true, + content: @Composable BoxScope.() -> Unit +) { + AppBox( + modifier = modifier, + contentAlignment = contentAlignment, + fillMaxSize = fillMaxSize, + fillMaxWidth = fillMaxWidth, + padding = SpacePaddingSmall, + content = content + ) +} + +/** + * 带中等内边距的Box,常用于普通布局 + * + * @param modifier 额外的修饰符 + * @param contentAlignment 内容对齐方式 + * @param fillMaxSize 是否填充最大尺寸 + * @param fillMaxWidth 是否填充最大宽度 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun MediumPaddingBox( + modifier: Modifier = Modifier, + contentAlignment: Alignment = Alignment.TopStart, + fillMaxSize: Boolean = false, + fillMaxWidth: Boolean = true, + content: @Composable BoxScope.() -> Unit +) { + AppBox( + modifier = modifier, + contentAlignment = contentAlignment, + fillMaxSize = fillMaxSize, + fillMaxWidth = fillMaxWidth, + padding = SpacePaddingMedium, + content = content + ) +} + +/** + * 带大内边距的Box,常用于强调布局 + * + * @param modifier 额外的修饰符 + * @param contentAlignment 内容对齐方式 + * @param fillMaxSize 是否填充最大尺寸 + * @param fillMaxWidth 是否填充最大宽度 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun LargePaddingBox( + modifier: Modifier = Modifier, + contentAlignment: Alignment = Alignment.TopStart, + fillMaxSize: Boolean = false, + fillMaxWidth: Boolean = true, + content: @Composable BoxScope.() -> Unit +) { + AppBox( + modifier = modifier, + contentAlignment = contentAlignment, + fillMaxSize = fillMaxSize, + fillMaxWidth = fillMaxWidth, + padding = SpacePaddingLarge, + content = content + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/joker/kit/core/designsystem/component/Column.kt b/app/src/main/java/com/joker/kit/core/designsystem/component/Column.kt new file mode 100644 index 0000000..a20e057 --- /dev/null +++ b/app/src/main/java/com/joker/kit/core/designsystem/component/Column.kt @@ -0,0 +1,444 @@ +package com.joker.kit.core.designsystem.component + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.foundation.layout.wrapContentWidth +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import com.joker.kit.core.designsystem.theme.SpacePaddingLarge +import com.joker.kit.core.designsystem.theme.SpacePaddingMedium +import com.joker.kit.core.designsystem.theme.SpacePaddingSmall +import com.joker.kit.core.designsystem.theme.SpaceVerticalMedium + +/** + * 封装的Column组件,预设了常用的修饰符 + * + * @param modifier 额外的修饰符 + * @param verticalArrangement 垂直排列方式 + * @param horizontalAlignment 水平对齐方式 + * @param fillMaxWidth 是否填充最大宽度 + * @param padding 内边距 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun AppColumn( + modifier: Modifier = Modifier, + verticalArrangement: Arrangement.Vertical = Arrangement.Top, + horizontalAlignment: Alignment.Horizontal = Alignment.Start, + fillMaxWidth: Boolean = true, + padding: Dp = 0.dp, + content: @Composable ColumnScope.() -> Unit +) { + val finalModifier = modifier + .let { if (fillMaxWidth) it.fillMaxWidth() else it } + .let { if (padding > 0.dp) it.padding(padding) else it } + + Column( + modifier = finalModifier, + verticalArrangement = verticalArrangement, + horizontalAlignment = horizontalAlignment, + content = content + ) +} + +/** + * 填充整个屏幕的Column,便于创建全屏页面布局 + * + * @param modifier 额外的修饰符 + * @param verticalArrangement 垂直排列方式 + * @param horizontalAlignment 水平对齐方式 + * @param padding 内边距 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun FullScreenColumn( + modifier: Modifier = Modifier, + verticalArrangement: Arrangement.Vertical = Arrangement.Top, + horizontalAlignment: Alignment.Horizontal = Alignment.Start, + padding: Dp = 0.dp, + content: @Composable ColumnScope.() -> Unit +) { + Column( + modifier = modifier + .fillMaxSize() + .let { if (padding > 0.dp) it.padding(padding) else it }, + verticalArrangement = verticalArrangement, + horizontalAlignment = horizontalAlignment, + content = content + ) +} + +/** + * 垂直居中的Column组件 + * + * @param modifier 额外的修饰符 + * @param fillMaxWidth 是否填充最大宽度 + * @param padding 内边距 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun CenterColumn( + modifier: Modifier = Modifier, + fillMaxWidth: Boolean = true, + padding: Dp = 0.dp, + content: @Composable ColumnScope.() -> Unit +) { + AppColumn( + modifier = modifier, + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally, + fillMaxWidth = fillMaxWidth, + padding = padding, + content = content + ) +} + +/** + * 顶部对齐的Column组件 + * + * @param modifier 额外的修饰符 + * @param horizontalAlignment 水平对齐方式 + * @param fillMaxWidth 是否填充最大宽度 + * @param padding 内边距 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun TopColumn( + modifier: Modifier = Modifier, + horizontalAlignment: Alignment.Horizontal = Alignment.Start, + fillMaxWidth: Boolean = true, + padding: Dp = 0.dp, + content: @Composable ColumnScope.() -> Unit +) { + AppColumn( + modifier = modifier, + verticalArrangement = Arrangement.Top, + horizontalAlignment = horizontalAlignment, + fillMaxWidth = fillMaxWidth, + padding = padding, + content = content + ) +} + +/** + * 底部对齐的Column组件 + * + * @param modifier 额外的修饰符 + * @param horizontalAlignment 水平对齐方式 + * @param fillMaxWidth 是否填充最大宽度 + * @param padding 内边距 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun BottomColumn( + modifier: Modifier = Modifier, + horizontalAlignment: Alignment.Horizontal = Alignment.Start, + fillMaxWidth: Boolean = true, + padding: Dp = 0.dp, + content: @Composable ColumnScope.() -> Unit +) { + AppColumn( + modifier = modifier, + verticalArrangement = Arrangement.Bottom, + horizontalAlignment = horizontalAlignment, + fillMaxWidth = fillMaxWidth, + padding = padding, + content = content + ) +} + +/** + * 两端对齐的Column组件 + * + * @param modifier 额外的修饰符 + * @param horizontalAlignment 水平对齐方式 + * @param fillMaxWidth 是否填充最大宽度 + * @param padding 内边距 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun SpaceBetweenColumn( + modifier: Modifier = Modifier, + horizontalAlignment: Alignment.Horizontal = Alignment.CenterHorizontally, + fillMaxWidth: Boolean = true, + padding: Dp = 0.dp, + content: @Composable ColumnScope.() -> Unit +) { + AppColumn( + modifier = modifier, + verticalArrangement = Arrangement.SpaceBetween, + horizontalAlignment = horizontalAlignment, + fillMaxWidth = fillMaxWidth, + padding = padding, + content = content + ) +} + +/** + * 均匀分布的Column组件 + * + * @param modifier 额外的修饰符 + * @param horizontalAlignment 水平对齐方式 + * @param fillMaxWidth 是否填充最大宽度 + * @param padding 内边距 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun SpaceEvenlyColumn( + modifier: Modifier = Modifier, + horizontalAlignment: Alignment.Horizontal = Alignment.Start, + fillMaxWidth: Boolean = true, + padding: Dp = 0.dp, + content: @Composable ColumnScope.() -> Unit +) { + AppColumn( + modifier = modifier, + verticalArrangement = Arrangement.SpaceEvenly, + horizontalAlignment = horizontalAlignment, + fillMaxWidth = fillMaxWidth, + padding = padding, + content = content + ) +} + +/** + * 居左对齐的Column组件 + * + * @param modifier 额外的修饰符 + * @param verticalArrangement 垂直排列方式 + * @param fillMaxWidth 是否填充最大宽度 + * @param padding 内边距 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun StartAlignColumn( + modifier: Modifier = Modifier, + verticalArrangement: Arrangement.Vertical = Arrangement.Top, + fillMaxWidth: Boolean = true, + padding: Dp = 0.dp, + content: @Composable ColumnScope.() -> Unit +) { + AppColumn( + modifier = modifier, + verticalArrangement = verticalArrangement, + horizontalAlignment = Alignment.Start, + fillMaxWidth = fillMaxWidth, + padding = padding, + content = content + ) +} + +/** + * 居右对齐的Column组件 + * + * @param modifier 额外的修饰符 + * @param verticalArrangement 垂直排列方式 + * @param fillMaxWidth 是否填充最大宽度 + * @param padding 内边距 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun EndAlignColumn( + modifier: Modifier = Modifier, + verticalArrangement: Arrangement.Vertical = Arrangement.Top, + fillMaxWidth: Boolean = true, + padding: Dp = 0.dp, + content: @Composable ColumnScope.() -> Unit +) { + AppColumn( + modifier = modifier, + verticalArrangement = verticalArrangement, + horizontalAlignment = Alignment.End, + fillMaxWidth = fillMaxWidth, + padding = padding, + content = content + ) +} + +/** + * 内容包裹的Column,不会填充最大宽度 + * + * @param modifier 额外的修饰符 + * @param verticalArrangement 垂直排列方式 + * @param horizontalAlignment 水平对齐方式 + * @param padding 内边距 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun WrapColumn( + modifier: Modifier = Modifier, + verticalArrangement: Arrangement.Vertical = Arrangement.Top, + horizontalAlignment: Alignment.Horizontal = Alignment.Start, + padding: Dp = 0.dp, + content: @Composable ColumnScope.() -> Unit +) { + Column( + modifier = modifier + .wrapContentWidth() + .wrapContentHeight() + .let { if (padding > 0.dp) it.padding(padding) else it }, + verticalArrangement = verticalArrangement, + horizontalAlignment = horizontalAlignment, + content = content + ) +} + +/** + * 垂直列表组件,带有预设的垂直间距 + * + * @param modifier 额外的修饰符 + * @param verticalArrangement 垂直排列方式 + * @param horizontalAlignment 水平对齐方式 + * @param fillMaxWidth 是否填充最大宽度 + * @param padding 内边距 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun VerticalList( + modifier: Modifier = Modifier, + verticalArrangement: Arrangement.Vertical = Arrangement.spacedBy(SpaceVerticalMedium), + horizontalAlignment: Alignment.Horizontal = Alignment.Start, + fillMaxWidth: Boolean = true, + padding: Dp = SpacePaddingMedium, + content: @Composable ColumnScope.() -> Unit +) { + AppColumn( + modifier = modifier, + verticalArrangement = verticalArrangement, + horizontalAlignment = horizontalAlignment, + fillMaxWidth = fillMaxWidth, + padding = padding, + content = content + ) +} + +/** + * 卡片内容列表,适用于卡片内部的内容排列 + * + * @param modifier 额外的修饰符 + * @param verticalArrangement 垂直排列方式 + * @param horizontalAlignment 水平对齐方式 + * @param padding 内边距 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun CardContentList( + modifier: Modifier = Modifier, + verticalArrangement: Arrangement.Vertical = Arrangement.spacedBy(SpaceVerticalMedium), + horizontalAlignment: Alignment.Horizontal = Alignment.Start, + padding: Dp = SpacePaddingMedium, + content: @Composable ColumnScope.() -> Unit +) { + Column( + modifier = modifier + .fillMaxWidth() + .padding(padding), + verticalArrangement = verticalArrangement, + horizontalAlignment = horizontalAlignment, + content = content + ) +} + +/** + * 带小内边距的Column,常用于紧凑型布局 + * + * @param modifier 额外的修饰符 + * @param verticalArrangement 垂直排列方式 + * @param horizontalAlignment 水平对齐方式 + * @param fillMaxWidth 是否填充最大宽度 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun SmallPaddingColumn( + modifier: Modifier = Modifier, + verticalArrangement: Arrangement.Vertical = Arrangement.Top, + horizontalAlignment: Alignment.Horizontal = Alignment.Start, + fillMaxWidth: Boolean = true, + content: @Composable ColumnScope.() -> Unit +) { + AppColumn( + modifier = modifier, + verticalArrangement = verticalArrangement, + horizontalAlignment = horizontalAlignment, + fillMaxWidth = fillMaxWidth, + padding = SpacePaddingSmall, + content = content + ) +} + +/** + * 带中等内边距的Column,常用于普通布局 + * + * @param modifier 额外的修饰符 + * @param verticalArrangement 垂直排列方式 + * @param horizontalAlignment 水平对齐方式 + * @param fillMaxWidth 是否填充最大宽度 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun MediumPaddingColumn( + modifier: Modifier = Modifier, + verticalArrangement: Arrangement.Vertical = Arrangement.Top, + horizontalAlignment: Alignment.Horizontal = Alignment.Start, + fillMaxWidth: Boolean = true, + content: @Composable ColumnScope.() -> Unit +) { + AppColumn( + modifier = modifier, + verticalArrangement = verticalArrangement, + horizontalAlignment = horizontalAlignment, + fillMaxWidth = fillMaxWidth, + padding = SpacePaddingMedium, + content = content + ) +} + +/** + * 带大内边距的Column,常用于强调布局 + * + * @param modifier 额外的修饰符 + * @param verticalArrangement 垂直排列方式 + * @param horizontalAlignment 水平对齐方式 + * @param fillMaxWidth 是否填充最大宽度 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun LargePaddingColumn( + modifier: Modifier = Modifier, + verticalArrangement: Arrangement.Vertical = Arrangement.Top, + horizontalAlignment: Alignment.Horizontal = Alignment.Start, + fillMaxWidth: Boolean = true, + content: @Composable ColumnScope.() -> Unit +) { + AppColumn( + modifier = modifier, + verticalArrangement = verticalArrangement, + horizontalAlignment = horizontalAlignment, + fillMaxWidth = fillMaxWidth, + padding = SpacePaddingLarge, + content = content + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/joker/kit/core/designsystem/component/LazyList.kt b/app/src/main/java/com/joker/kit/core/designsystem/component/LazyList.kt new file mode 100644 index 0000000..96995a2 --- /dev/null +++ b/app/src/main/java/com/joker/kit/core/designsystem/component/LazyList.kt @@ -0,0 +1,306 @@ +package com.joker.kit.core.designsystem.component + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.LazyListScope +import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import com.joker.kit.core.designsystem.theme.SpacePaddingLarge +import com.joker.kit.core.designsystem.theme.SpacePaddingMedium +import com.joker.kit.core.designsystem.theme.SpacePaddingSmall +import com.joker.kit.core.designsystem.theme.SpaceVerticalSmall + +/** + * 垂直懒加载列表组件,预设的常用属性 + * + * @param modifier 额外的修饰符 + * @param listState 列表状态 + * @param contentPadding 内容内边距 + * @param verticalArrangement 垂直排列方式 + * @param horizontalAlignment 水平对齐方式 + * @param reverseLayout 是否反向布局 + * @param fillMaxSize 是否填充最大尺寸 + * @param fillMaxWidth 是否填充最大宽度(当fillMaxSize为false时生效) + * @param content 列表内容构建器 + * @author Joker.X + */ +@Composable +fun AppLazyColumn( + modifier: Modifier = Modifier, + listState: LazyListState = rememberLazyListState(), + contentPadding: PaddingValues = PaddingValues(0.dp), + verticalArrangement: Arrangement.Vertical = Arrangement.Top, + horizontalAlignment: Alignment.Horizontal = Alignment.Start, + reverseLayout: Boolean = false, + fillMaxSize: Boolean = false, + fillMaxWidth: Boolean = true, + content: LazyListScope.() -> Unit +) { + LazyColumn( + modifier = modifier.let { + if (fillMaxSize) it.fillMaxSize() + else if (fillMaxWidth) it.fillMaxWidth() + else it + }, + state = listState, + contentPadding = contentPadding, + verticalArrangement = verticalArrangement, + horizontalAlignment = horizontalAlignment, + reverseLayout = reverseLayout, + content = content + ) +} + +/** + * 带小内边距的垂直懒加载列表 + * + * @param modifier 额外的修饰符 + * @param listState 列表状态 + * @param verticalArrangement 垂直排列方式 + * @param horizontalAlignment 水平对齐方式 + * @param reverseLayout 是否反向布局 + * @param fillMaxSize 是否填充最大尺寸 + * @param fillMaxWidth 是否填充最大宽度 + * @param content 列表内容构建器 + * @author Joker.X + */ +@Composable +fun SmallPaddingLazyColumn( + modifier: Modifier = Modifier, + listState: LazyListState = rememberLazyListState(), + verticalArrangement: Arrangement.Vertical = Arrangement.Top, + horizontalAlignment: Alignment.Horizontal = Alignment.Start, + reverseLayout: Boolean = false, + fillMaxSize: Boolean = false, + fillMaxWidth: Boolean = true, + content: LazyListScope.() -> Unit +) { + AppLazyColumn( + modifier = modifier, + listState = listState, + contentPadding = PaddingValues(SpacePaddingSmall), + verticalArrangement = verticalArrangement, + horizontalAlignment = horizontalAlignment, + reverseLayout = reverseLayout, + fillMaxSize = fillMaxSize, + fillMaxWidth = fillMaxWidth, + content = content + ) +} + +/** + * 带中等内边距的垂直懒加载列表 + * + * @param modifier 额外的修饰符 + * @param listState 列表状态 + * @param verticalArrangement 垂直排列方式 + * @param horizontalAlignment 水平对齐方式 + * @param reverseLayout 是否反向布局 + * @param fillMaxSize 是否填充最大尺寸 + * @param fillMaxWidth 是否填充最大宽度 + * @param content 列表内容构建器 + * @author Joker.X + */ +@Composable +fun MediumPaddingLazyColumn( + modifier: Modifier = Modifier, + listState: LazyListState = rememberLazyListState(), + verticalArrangement: Arrangement.Vertical = Arrangement.Top, + horizontalAlignment: Alignment.Horizontal = Alignment.Start, + reverseLayout: Boolean = false, + fillMaxSize: Boolean = false, + fillMaxWidth: Boolean = true, + content: LazyListScope.() -> Unit +) { + AppLazyColumn( + modifier = modifier, + listState = listState, + contentPadding = PaddingValues(SpacePaddingMedium), + verticalArrangement = verticalArrangement, + horizontalAlignment = horizontalAlignment, + reverseLayout = reverseLayout, + fillMaxSize = fillMaxSize, + fillMaxWidth = fillMaxWidth, + content = content + ) +} + +/** + * 带大内边距的垂直懒加载列表 + * + * @param modifier 额外的修饰符 + * @param listState 列表状态 + * @param verticalArrangement 垂直排列方式 + * @param horizontalAlignment 水平对齐方式 + * @param reverseLayout 是否反向布局 + * @param fillMaxSize 是否填充最大尺寸 + * @param fillMaxWidth 是否填充最大宽度 + * @param content 列表内容构建器 + * @author Joker.X + */ +@Composable +fun LargePaddingLazyColumn( + modifier: Modifier = Modifier, + listState: LazyListState = rememberLazyListState(), + verticalArrangement: Arrangement.Vertical = Arrangement.Top, + horizontalAlignment: Alignment.Horizontal = Alignment.Start, + reverseLayout: Boolean = false, + fillMaxSize: Boolean = false, + fillMaxWidth: Boolean = true, + content: LazyListScope.() -> Unit +) { + AppLazyColumn( + modifier = modifier, + listState = listState, + contentPadding = PaddingValues(SpacePaddingLarge), + verticalArrangement = verticalArrangement, + horizontalAlignment = horizontalAlignment, + reverseLayout = reverseLayout, + fillMaxSize = fillMaxSize, + fillMaxWidth = fillMaxWidth, + content = content + ) +} + +/** + * 垂直列表项目,预设了间距 + * + * @param modifier 额外的修饰符 + * @param listState 列表状态 + * @param contentPadding 内容内边距 + * @param itemSpacing 列表项间距 + * @param horizontalAlignment 水平对齐方式 + * @param reverseLayout 是否反向布局 + * @param fillMaxSize 是否填充最大尺寸 + * @param fillMaxWidth 是否填充最大宽度 + * @param content 列表内容构建器 + * @author Joker.X + */ +@Composable +fun VerticalListItems( + modifier: Modifier = Modifier, + listState: LazyListState = rememberLazyListState(), + contentPadding: PaddingValues = PaddingValues(SpacePaddingMedium), + itemSpacing: Dp = SpaceVerticalSmall, + horizontalAlignment: Alignment.Horizontal = Alignment.Start, + reverseLayout: Boolean = false, + fillMaxSize: Boolean = false, + fillMaxWidth: Boolean = true, + content: LazyListScope.() -> Unit +) { + AppLazyColumn( + modifier = modifier, + listState = listState, + contentPadding = contentPadding, + verticalArrangement = Arrangement.spacedBy(itemSpacing), + horizontalAlignment = horizontalAlignment, + reverseLayout = reverseLayout, + fillMaxSize = fillMaxSize, + fillMaxWidth = fillMaxWidth, + content = content + ) +} + +/** + * 水平懒加载列表组件,预设的常用属性 + * + * @param modifier 额外的修饰符 + * @param listState 列表状态 + * @param contentPadding 内容内边距 + * @param horizontalArrangement 水平排列方式 + * @param verticalAlignment 垂直对齐方式 + * @param reverseLayout 是否反向布局 + * @param content 列表内容构建器 + * @author Joker.X + */ +@Composable +fun AppLazyRow( + modifier: Modifier = Modifier, + listState: LazyListState = rememberLazyListState(), + contentPadding: PaddingValues = PaddingValues(0.dp), + horizontalArrangement: Arrangement.Horizontal = Arrangement.Start, + verticalAlignment: Alignment.Vertical = Alignment.CenterVertically, + reverseLayout: Boolean = false, + content: LazyListScope.() -> Unit +) { + LazyRow( + modifier = modifier, + state = listState, + contentPadding = contentPadding, + horizontalArrangement = horizontalArrangement, + verticalAlignment = verticalAlignment, + reverseLayout = reverseLayout, + content = content + ) +} + +/** + * 带小内边距的水平懒加载列表 + * + * @param modifier 额外的修饰符 + * @param listState 列表状态 + * @param horizontalArrangement 水平排列方式 + * @param verticalAlignment 垂直对齐方式 + * @param reverseLayout 是否反向布局 + * @param content 列表内容构建器 + * @author Joker.X + */ +@Composable +fun SmallPaddingLazyRow( + modifier: Modifier = Modifier, + listState: LazyListState = rememberLazyListState(), + horizontalArrangement: Arrangement.Horizontal = Arrangement.Start, + verticalAlignment: Alignment.Vertical = Alignment.CenterVertically, + reverseLayout: Boolean = false, + content: LazyListScope.() -> Unit +) { + AppLazyRow( + modifier = modifier, + listState = listState, + contentPadding = PaddingValues(SpacePaddingSmall), + horizontalArrangement = horizontalArrangement, + verticalAlignment = verticalAlignment, + reverseLayout = reverseLayout, + content = content + ) +} + +/** + * 带中等内边距的水平懒加载列表 + * + * @param modifier 额外的修饰符 + * @param listState 列表状态 + * @param horizontalArrangement 水平排列方式 + * @param verticalAlignment 垂直对齐方式 + * @param reverseLayout 是否反向布局 + * @param content 列表内容构建器 + * @author Joker.X + */ +@Composable +fun MediumPaddingLazyRow( + modifier: Modifier = Modifier, + listState: LazyListState = rememberLazyListState(), + horizontalArrangement: Arrangement.Horizontal = Arrangement.Start, + verticalAlignment: Alignment.Vertical = Alignment.CenterVertically, + reverseLayout: Boolean = false, + content: LazyListScope.() -> Unit +) { + AppLazyRow( + modifier = modifier, + listState = listState, + contentPadding = PaddingValues(SpacePaddingMedium), + horizontalArrangement = horizontalArrangement, + verticalAlignment = verticalAlignment, + reverseLayout = reverseLayout, + content = content + ) +} diff --git a/app/src/main/java/com/joker/kit/core/designsystem/component/Row.kt b/app/src/main/java/com/joker/kit/core/designsystem/component/Row.kt new file mode 100644 index 0000000..44a4d9a --- /dev/null +++ b/app/src/main/java/com/joker/kit/core/designsystem/component/Row.kt @@ -0,0 +1,347 @@ +package com.joker.kit.core.designsystem.component + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentWidth +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import com.joker.kit.core.designsystem.theme.SpaceHorizontalSmall +import com.joker.kit.core.designsystem.theme.SpacePaddingLarge +import com.joker.kit.core.designsystem.theme.SpacePaddingMedium +import com.joker.kit.core.designsystem.theme.SpacePaddingSmall + +/** + * 封装的Row组件,预设了常用的修饰符 + * + * @param modifier 额外的修饰符 + * @param horizontalArrangement 水平排列方式 + * @param verticalAlignment 垂直对齐方式 + * @param fillMaxWidth 是否填充最大宽度 + * @param padding 内边距 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun AppRow( + modifier: Modifier = Modifier, + horizontalArrangement: Arrangement.Horizontal = Arrangement.Start, + verticalAlignment: Alignment.Vertical = Alignment.CenterVertically, + fillMaxWidth: Boolean = true, + padding: Dp = 0.dp, + content: @Composable RowScope.() -> Unit +) { + val finalModifier = modifier + .let { if (fillMaxWidth) it.fillMaxWidth() else it } + .let { if (padding > 0.dp) it.padding(padding) else it } + + Row( + modifier = finalModifier, + horizontalArrangement = horizontalArrangement, + verticalAlignment = verticalAlignment, + content = content + ) +} + +/** + * 水平居中的Row组件 + * + * @param modifier 额外的修饰符 + * @param fillMaxWidth 是否填充最大宽度 + * @param padding 内边距 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun CenterRow( + modifier: Modifier = Modifier, + fillMaxWidth: Boolean = true, + padding: Dp = 0.dp, + content: @Composable RowScope.() -> Unit +) { + AppRow( + modifier = modifier, + horizontalArrangement = Arrangement.Center, + verticalAlignment = Alignment.CenterVertically, + fillMaxWidth = fillMaxWidth, + padding = padding, + content = content + ) +} + +/** + * 两端对齐的Row组件 + * + * @param modifier 额外的修饰符 + * @param fillMaxWidth 是否填充最大宽度 + * @param padding 内边距 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun SpaceBetweenRow( + modifier: Modifier = Modifier, + fillMaxWidth: Boolean = true, + padding: Dp = 0.dp, + content: @Composable RowScope.() -> Unit +) { + AppRow( + modifier = modifier, + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + fillMaxWidth = fillMaxWidth, + padding = padding, + content = content + ) +} + +/** + * 均匀分布的Row组件 + * + * @param modifier 额外的修饰符 + * @param fillMaxWidth 是否填充最大宽度 + * @param padding 内边距 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun SpaceEvenlyRow( + modifier: Modifier = Modifier, + fillMaxWidth: Boolean = true, + padding: Dp = 0.dp, + content: @Composable RowScope.() -> Unit +) { + AppRow( + modifier = modifier, + horizontalArrangement = Arrangement.SpaceEvenly, + verticalAlignment = Alignment.CenterVertically, + fillMaxWidth = fillMaxWidth, + padding = padding, + content = content + ) +} + +/** + * 平均分布的Row组件(间距均匀) + * + * @param modifier 额外的修饰符 + * @param fillMaxWidth 是否填充最大宽度 + * @param padding 内边距 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun SpaceAroundRow( + modifier: Modifier = Modifier, + fillMaxWidth: Boolean = true, + padding: Dp = 0.dp, + content: @Composable RowScope.() -> Unit +) { + AppRow( + modifier = modifier, + horizontalArrangement = Arrangement.SpaceAround, + verticalAlignment = Alignment.CenterVertically, + fillMaxWidth = fillMaxWidth, + padding = padding, + content = content + ) +} + +/** + * 左对齐的Row组件 + * + * @param modifier 额外的修饰符 + * @param fillMaxWidth 是否填充最大宽度 + * @param padding 内边距 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun StartRow( + modifier: Modifier = Modifier, + fillMaxWidth: Boolean = true, + padding: Dp = 0.dp, + content: @Composable RowScope.() -> Unit +) { + AppRow( + modifier = modifier, + horizontalArrangement = Arrangement.Start, + verticalAlignment = Alignment.CenterVertically, + fillMaxWidth = fillMaxWidth, + padding = padding, + content = content + ) +} + +/** + * 右对齐的Row组件 + * + * @param modifier 额外的修饰符 + * @param fillMaxWidth 是否填充最大宽度 + * @param padding 内边距 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun EndRow( + modifier: Modifier = Modifier, + fillMaxWidth: Boolean = true, + padding: Dp = 0.dp, + content: @Composable RowScope.() -> Unit +) { + AppRow( + modifier = modifier, + horizontalArrangement = Arrangement.End, + verticalAlignment = Alignment.CenterVertically, + fillMaxWidth = fillMaxWidth, + padding = padding, + content = content + ) +} + +/** + * 内容包裹的Row,不会填充最大宽度 + * + * @param modifier 额外的修饰符 + * @param horizontalArrangement 水平排列方式 + * @param verticalAlignment 垂直对齐方式 + * @param padding 内边距 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun WrapRow( + modifier: Modifier = Modifier, + horizontalArrangement: Arrangement.Horizontal = Arrangement.Start, + verticalAlignment: Alignment.Vertical = Alignment.CenterVertically, + padding: Dp = 0.dp, + content: @Composable RowScope.() -> Unit +) { + Row( + modifier = modifier + .wrapContentWidth() + .let { if (padding > 0.dp) it.padding(padding) else it }, + horizontalArrangement = horizontalArrangement, + verticalAlignment = verticalAlignment, + content = content + ) +} + +/** + * 水平列表组件,带有预设的水平间距 + * + * @param modifier 额外的修饰符 + * @param horizontalArrangement 水平排列方式 + * @param verticalAlignment 垂直对齐方式 + * @param fillMaxWidth 是否填充最大宽度 + * @param padding 内边距 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun HorizontalList( + modifier: Modifier = Modifier, + horizontalArrangement: Arrangement.Horizontal = Arrangement.spacedBy(SpaceHorizontalSmall), + verticalAlignment: Alignment.Vertical = Alignment.CenterVertically, + fillMaxWidth: Boolean = true, + padding: Dp = SpacePaddingMedium, + content: @Composable RowScope.() -> Unit +) { + AppRow( + modifier = modifier, + horizontalArrangement = horizontalArrangement, + verticalAlignment = verticalAlignment, + fillMaxWidth = fillMaxWidth, + padding = padding, + content = content + ) +} + +/** + * 带小内边距的Row,常用于紧凑型布局 + * + * @param modifier 额外的修饰符 + * @param horizontalArrangement 水平排列方式 + * @param verticalAlignment 垂直对齐方式 + * @param fillMaxWidth 是否填充最大宽度 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun SmallPaddingRow( + modifier: Modifier = Modifier, + horizontalArrangement: Arrangement.Horizontal = Arrangement.Start, + verticalAlignment: Alignment.Vertical = Alignment.CenterVertically, + fillMaxWidth: Boolean = true, + content: @Composable RowScope.() -> Unit +) { + AppRow( + modifier = modifier, + horizontalArrangement = horizontalArrangement, + verticalAlignment = verticalAlignment, + fillMaxWidth = fillMaxWidth, + padding = SpacePaddingSmall, + content = content + ) +} + +/** + * 带中等内边距的Row,常用于普通布局 + * + * @param modifier 额外的修饰符 + * @param horizontalArrangement 水平排列方式 + * @param verticalAlignment 垂直对齐方式 + * @param fillMaxWidth 是否填充最大宽度 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun MediumPaddingRow( + modifier: Modifier = Modifier, + horizontalArrangement: Arrangement.Horizontal = Arrangement.Start, + verticalAlignment: Alignment.Vertical = Alignment.CenterVertically, + fillMaxWidth: Boolean = true, + content: @Composable RowScope.() -> Unit +) { + AppRow( + modifier = modifier, + horizontalArrangement = horizontalArrangement, + verticalAlignment = verticalAlignment, + fillMaxWidth = fillMaxWidth, + padding = SpacePaddingMedium, + content = content + ) +} + +/** + * 带大内边距的Row,常用于强调布局 + * + * @param modifier 额外的修饰符 + * @param horizontalArrangement 水平排列方式 + * @param verticalAlignment 垂直对齐方式 + * @param fillMaxWidth 是否填充最大宽度 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun LargePaddingRow( + modifier: Modifier = Modifier, + horizontalArrangement: Arrangement.Horizontal = Arrangement.Start, + verticalAlignment: Alignment.Vertical = Alignment.CenterVertically, + fillMaxWidth: Boolean = true, + content: @Composable RowScope.() -> Unit +) { + AppRow( + modifier = modifier, + horizontalArrangement = horizontalArrangement, + verticalAlignment = verticalAlignment, + fillMaxWidth = fillMaxWidth, + padding = SpacePaddingLarge, + content = content + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/joker/kit/core/designsystem/component/Scroll.kt b/app/src/main/java/com/joker/kit/core/designsystem/component/Scroll.kt new file mode 100644 index 0000000..be84123 --- /dev/null +++ b/app/src/main/java/com/joker/kit/core/designsystem/component/Scroll.kt @@ -0,0 +1,235 @@ +package com.joker.kit.core.designsystem.component + +import androidx.compose.foundation.gestures.FlingBehavior +import androidx.compose.foundation.gestures.ScrollableDefaults +import androidx.compose.foundation.horizontalScroll +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import com.joker.kit.core.designsystem.theme.SpacePaddingLarge +import com.joker.kit.core.designsystem.theme.SpacePaddingMedium +import com.joker.kit.core.designsystem.theme.SpacePaddingSmall + +/** + * 垂直滚动组件,包含预设的修饰符和属性 + * + * @param modifier 额外的修饰符 + * @param padding 内边距 + * @param horizontalAlignment 水平对齐方式 + * @param verticalArrangement 垂直排列方式 + * @param fillMaxSize 是否填充最大尺寸 + * @param fillMaxWidth 是否填充最大宽度 (仅当fillMaxSize为false时生效) + * @param flingBehavior 滑动行为 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun VerticalScroll( + modifier: Modifier = Modifier, + padding: Dp = 0.dp, + horizontalAlignment: Alignment.Horizontal = Alignment.Start, + verticalArrangement: Arrangement.Vertical = Arrangement.Top, + fillMaxSize: Boolean = false, + fillMaxWidth: Boolean = true, + flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(), + content: @Composable ColumnScope.() -> Unit +) { + val scrollState = rememberScrollState() + + Column( + modifier = modifier + .let { if (fillMaxSize) it.fillMaxSize() else if (fillMaxWidth) it.fillMaxWidth() else it } + .verticalScroll(scrollState, flingBehavior = flingBehavior) + .let { if (padding > 0.dp) it.padding(padding) else it }, + horizontalAlignment = horizontalAlignment, + verticalArrangement = verticalArrangement, + content = content + ) +} + +/** + * 带小内边距的垂直滚动组件 + * + * @param modifier 额外的修饰符 + * @param horizontalAlignment 水平对齐方式 + * @param verticalArrangement 垂直排列方式 + * @param fillMaxSize 是否填充最大尺寸 + * @param fillMaxWidth 是否填充最大宽度 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun SmallPaddingVerticalScroll( + modifier: Modifier = Modifier, + horizontalAlignment: Alignment.Horizontal = Alignment.Start, + verticalArrangement: Arrangement.Vertical = Arrangement.Top, + fillMaxSize: Boolean = false, + fillMaxWidth: Boolean = true, + content: @Composable ColumnScope.() -> Unit +) { + VerticalScroll( + modifier = modifier, + padding = SpacePaddingSmall, + horizontalAlignment = horizontalAlignment, + verticalArrangement = verticalArrangement, + fillMaxSize = fillMaxSize, + fillMaxWidth = fillMaxWidth, + content = content + ) +} + +/** + * 带中等内边距的垂直滚动组件 + * + * @param modifier 额外的修饰符 + * @param horizontalAlignment 水平对齐方式 + * @param verticalArrangement 垂直排列方式 + * @param fillMaxSize 是否填充最大尺寸 + * @param fillMaxWidth 是否填充最大宽度 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun MediumPaddingVerticalScroll( + modifier: Modifier = Modifier, + horizontalAlignment: Alignment.Horizontal = Alignment.Start, + verticalArrangement: Arrangement.Vertical = Arrangement.Top, + fillMaxSize: Boolean = false, + fillMaxWidth: Boolean = true, + content: @Composable ColumnScope.() -> Unit +) { + VerticalScroll( + modifier = modifier, + padding = SpacePaddingMedium, + horizontalAlignment = horizontalAlignment, + verticalArrangement = verticalArrangement, + fillMaxSize = fillMaxSize, + fillMaxWidth = fillMaxWidth, + content = content + ) +} + +/** + * 带大内边距的垂直滚动组件 + * + * @param modifier 额外的修饰符 + * @param horizontalAlignment 水平对齐方式 + * @param verticalArrangement 垂直排列方式 + * @param fillMaxSize 是否填充最大尺寸 + * @param fillMaxWidth 是否填充最大宽度 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun LargePaddingVerticalScroll( + modifier: Modifier = Modifier, + horizontalAlignment: Alignment.Horizontal = Alignment.Start, + verticalArrangement: Arrangement.Vertical = Arrangement.Top, + fillMaxSize: Boolean = false, + fillMaxWidth: Boolean = true, + content: @Composable ColumnScope.() -> Unit +) { + VerticalScroll( + modifier = modifier, + padding = SpacePaddingLarge, + horizontalAlignment = horizontalAlignment, + verticalArrangement = verticalArrangement, + fillMaxSize = fillMaxSize, + fillMaxWidth = fillMaxWidth, + content = content + ) +} + +/** + * 水平滚动组件,包含预设的修饰符和属性 + * + * @param modifier 额外的修饰符 + * @param padding 内边距 + * @param horizontalArrangement 水平排列方式 + * @param verticalAlignment 垂直对齐方式 + * @param flingBehavior 滑动行为 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun HorizontalScroll( + modifier: Modifier = Modifier, + padding: Dp = 0.dp, + horizontalArrangement: Arrangement.Horizontal = Arrangement.Start, + verticalAlignment: Alignment.Vertical = Alignment.CenterVertically, + flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(), + content: @Composable RowScope.() -> Unit +) { + val scrollState = rememberScrollState() + + Row( + modifier = modifier + .horizontalScroll(scrollState, flingBehavior = flingBehavior) + .let { if (padding > 0.dp) it.padding(padding) else it }, + horizontalArrangement = horizontalArrangement, + verticalAlignment = verticalAlignment, + content = content + ) +} + +/** + * 带小内边距的水平滚动组件 + * + * @param modifier 额外的修饰符 + * @param horizontalArrangement 水平排列方式 + * @param verticalAlignment 垂直对齐方式 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun SmallPaddingHorizontalScroll( + modifier: Modifier = Modifier, + horizontalArrangement: Arrangement.Horizontal = Arrangement.Start, + verticalAlignment: Alignment.Vertical = Alignment.CenterVertically, + content: @Composable RowScope.() -> Unit +) { + HorizontalScroll( + modifier = modifier, + padding = SpacePaddingSmall, + horizontalArrangement = horizontalArrangement, + verticalAlignment = verticalAlignment, + content = content + ) +} + +/** + * 带中等内边距的水平滚动组件 + * + * @param modifier 额外的修饰符 + * @param horizontalArrangement 水平排列方式 + * @param verticalAlignment 垂直对齐方式 + * @param content 内容 + * @author Joker.X + */ +@Composable +fun MediumPaddingHorizontalScroll( + modifier: Modifier = Modifier, + horizontalArrangement: Arrangement.Horizontal = Arrangement.Start, + verticalAlignment: Alignment.Vertical = Alignment.CenterVertically, + content: @Composable RowScope.() -> Unit +) { + HorizontalScroll( + modifier = modifier, + padding = SpacePaddingMedium, + horizontalArrangement = horizontalArrangement, + verticalAlignment = verticalAlignment, + content = content + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/joker/kit/core/designsystem/component/Spacer.kt b/app/src/main/java/com/joker/kit/core/designsystem/component/Spacer.kt new file mode 100644 index 0000000..2d2292f --- /dev/null +++ b/app/src/main/java/com/joker/kit/core/designsystem/component/Spacer.kt @@ -0,0 +1,141 @@ +package com.joker.kit.core.designsystem.component + +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.width +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.joker.kit.core.designsystem.theme.SpaceHorizontalMedium +import com.joker.kit.core.designsystem.theme.SpaceHorizontalSmall +import com.joker.kit.core.designsystem.theme.SpaceHorizontalXLarge +import com.joker.kit.core.designsystem.theme.SpaceHorizontalXSmall +import com.joker.kit.core.designsystem.theme.SpaceHorizontalXXLarge +import com.joker.kit.core.designsystem.theme.SpaceVerticalLarge +import com.joker.kit.core.designsystem.theme.SpaceVerticalMedium +import com.joker.kit.core.designsystem.theme.SpaceVerticalSmall +import com.joker.kit.core.designsystem.theme.SpaceVerticalXLarge +import com.joker.kit.core.designsystem.theme.SpaceVerticalXSmall +import com.joker.kit.core.designsystem.theme.SpaceVerticalXXLarge + + +/** + * 创建一个超大垂直间距(32dp)的Spacer组件 + * 使用方式:SpaceVerticalXXLarge() + * @author Joker.X + */ +@Composable +fun SpaceVerticalXXLarge() { + Spacer(modifier = Modifier.height(SpaceVerticalXXLarge)) +} + +/** + * 创建一个特大垂直间距(24dp)的Spacer组件 + * 使用方式:SpaceVerticalXLarge() + * @author Joker.X + */ +@Composable +fun SpaceVerticalXLarge() { + Spacer(modifier = Modifier.height(SpaceVerticalXLarge)) +} + +/** + * 创建一个大垂直间距(16dp)的Spacer组件 + * 使用方式:SpaceVerticalLarge() + * @author Joker.X + */ +@Composable +fun SpaceVerticalLarge() { + Spacer(modifier = Modifier.height(SpaceVerticalLarge)) +} + +/** + * 创建一个中等垂直间距(12dp)的Spacer组件 + * 使用方式:SpaceVerticalMedium() + * @author Joker.X + */ +@Composable +fun SpaceVerticalMedium() { + Spacer(modifier = Modifier.height(SpaceVerticalMedium)) +} + +/** + * 创建一个小垂直间距(8dp)的Spacer组件 + * 使用方式:SpaceVerticalSmall() + * @author Joker.X + */ +@Composable +fun SpaceVerticalSmall() { + Spacer(modifier = Modifier.height(SpaceVerticalSmall)) +} + +/** + * 创建一个超小垂直间距(4dp)的Spacer组件 + * 使用方式:SpaceVerticalXSmall() + * @author Joker.X + */ +@Composable +fun SpaceVerticalXSmall() { + Spacer(modifier = Modifier.height(SpaceVerticalXSmall)) +} +//endregion + +//region 水平间距组件 +/** + * 创建一个超大水平间距(32dp)的Spacer组件 + * 使用方式:SpaceHorizontalXXLarge() + * @author Joker.X + */ +@Composable +fun SpaceHorizontalXXLarge() { + Spacer(modifier = Modifier.width(SpaceHorizontalXXLarge)) +} + +/** + * 创建一个特大水平间距(24dp)的Spacer组件 + * 使用方式:SpaceHorizontalXLarge() + * @author Joker.X + */ +@Composable +fun SpaceHorizontalXLarge() { + Spacer(modifier = Modifier.width(SpaceHorizontalXLarge)) +} + +/** + * 创建一个大水平间距(16dp)的Spacer组件 + * 使用方式:SpaceHorizontalLarge() + * @author Joker.X + */ +@Composable +fun SpaceHorizontalLarge() { + Spacer(modifier = Modifier.width(SpaceHorizontalXLarge)) +} + +/** + * 创建一个中等水平间距(12dp)的Spacer组件 + * 使用方式:SpaceHorizontalMedium() + * @author Joker.X + */ +@Composable +fun SpaceHorizontalMedium() { + Spacer(modifier = Modifier.width(SpaceHorizontalMedium)) +} + +/** + * 创建一个小水平间距(8dp)的Spacer组件 + * 使用方式:SpaceHorizontalSmall() + * @author Joker.X + */ +@Composable +fun SpaceHorizontalSmall() { + Spacer(modifier = Modifier.width(SpaceHorizontalSmall)) +} + +/** + * 创建一个超小水平间距(4dp)的Spacer组件 + * 使用方式:SpaceHorizontalXSmall() + * @author Joker.X + */ +@Composable +fun SpaceHorizontalXSmall() { + Spacer(modifier = Modifier.width(SpaceHorizontalXSmall)) +} \ No newline at end of file diff --git a/app/src/main/java/com/joker/kit/core/designsystem/theme/Color.kt b/app/src/main/java/com/joker/kit/core/designsystem/theme/Color.kt new file mode 100644 index 0000000..7e4927f --- /dev/null +++ b/app/src/main/java/com/joker/kit/core/designsystem/theme/Color.kt @@ -0,0 +1,306 @@ +package com.joker.kit.core.designsystem.theme + +import androidx.compose.ui.graphics.Color + + +/** + * 颜色规范 + * 定义应用程序中使用的所有颜色,包括浅色和深色主题 + */ + +/** + * 品牌主色(普通模式):#465CFF + * 场景:菜单栏、主要按钮、突出文字 + */ +val PrimaryLight = Color(0xFF465CFF) + +/** + * 品牌主色(暗黑模式):#466CFF + * 场景:暗黑主题下的菜单栏、主要按钮、突出文字 + */ +val PrimaryDark = Color(0xFF466CFF) + +/** + * 品牌主色 + * 暂时和亮色模式一致可自行修改 + */ +val Primary = PrimaryLight + +// 辅助色 +/** + * 危险色/红色:#FF2B2B + * 适用场景:错误提示、删除操作、警告信息等 + */ +val ColorDanger = Color(0xFFFF2B2B) // 危险色/红色 + +/** + * 深色模式危险色/红色:#FF2B3B + */ +val ColorDangerDark = Color(0xFFFF2B3B) + +/** + * 警告色/黄色:#FFB703 + * 适用场景:警告提示、需要注意的信息等 + */ +val ColorWarning = Color(0xFFFFB703) // 警告色/黄色 + +/** + * 深色模式警告色/黄色:#FFB704 + */ +val ColorWarningDark = Color(0xFFFFB704) + +/** + * 紫色:#6831FF + * 适用场景:特殊强调、次要品牌色等 + */ +val ColorPurple = Color(0xFF6831FF) // 紫色 + +/** + * 深色模式紫色:#6832FF + */ +val ColorPurpleDark = Color(0xFF6832FF) + +/** + * 成功色/绿色:#09BE4F + * 适用场景:成功提示、完成状态等 + */ +val ColorSuccess = Color(0xFF09BE4F) // 成功色/绿色 + +/** + * 深色模式成功色/绿色:#09BE5F + */ +val ColorSuccessDark = Color(0xFF09BE5F) + +// 字体颜色 - 浅色模式 +/** + * 浅色模式下主要文字颜色:#181818 + * 适用场景:标题、重要文本内容 + */ +val TextPrimaryLight = Color(0xFF181818) // 用于重要标题内容 + +/** + * 浅色模式下次要文字颜色:#333333 + * 适用场景:正文内容、次要标题 + */ +val TextSecondaryLight = Color(0xFF333333) // 用于普通内容 + +/** + * 浅色模式下次要标题颜色:#7F7F7F + * 适用场景:表单标题、提示标签等 + */ +val TextSubtitleLight = Color(0xFF7F7F7F) + +/** + * 浅色模式下三级文字颜色:#B2B2B2 + * 适用场景:辅助说明、标签文字 + */ +val TextTertiaryLight = Color(0xFFB2B2B2) // 用于底部标签描述 + +/** + * 浅色模式下四级文字颜色:#CCCCCC + * 适用场景:次要辅助信息、禁用状态文字 + */ +val TextQuaternaryLight = Color(0xFFCCCCCC) // 用于辅助次要信息 + +/** + * 按钮文字:#FFFFFF(两种模式一致) + */ +val TextWhite = Color(0xFFFFFFFF) + +// 字体颜色 - 深色模式 +/** + * 深色模式下主要文字颜色:#D1D1D1 + * 适用场景:深色模式下的标题、重要文本内容 + */ +val TextPrimaryDark = Color(0xFFD1D1D1) // 深色模式下的主要文字 + +/** + * 深色模式下次要文字颜色:#A3A3A3 + * 适用场景:深色模式下的正文内容、次要标题 + */ +val TextSecondaryDark = Color(0xFFA3A3A3) // 深色模式下的次要文字 + +/** + * 深色模式下次要标题颜色:#8C8C8C + * 适用场景:深色模式下的表单标题、提示标签等 + */ +val TextSubtitleDark = Color(0xFF8C8C8C) + +/** + * 深色模式下三级文字颜色:#8D8D8D + * 适用场景:深色模式下的辅助说明、标签文字 + */ +val TextTertiaryDark = Color(0xFF8D8D8D) // 深色模式下的三级文字 + +/** + * 深色模式下四级文字颜色:#5E5E5E + * 适用场景:深色模式下的次要辅助信息、禁用状态文字 + */ +val TextQuaternaryDark = Color(0xFF5E5E5E) // 深色模式下的四级文字 + +// 背景色 - 浅色模式 +/** + * 浅色模式下页面背景色:#F1F4FA + * 适用场景:应用整体背景、页面底色 + */ +val BgGreyLight = Color(0xFFF1F4FA) // 页面背景底色 + +/** + * 浅色模式下白色背景:#FFFFFF + * 适用场景:卡片、弹窗等内容区域背景 + */ +val BgWhiteLight = Color(0xFFFFFFFF) // 白色背景 + +/** + * 浅色模式下内容模块背景色:#F8F8F8 + * 适用场景:次级内容区域、列表项底色 + */ +val BgContentLight = Color(0xFFF8F8F8) // 内容模块底色 + +/** + * 浅色模式下红色背景:#FF2B2B(5%透明度) + * 适用场景:红色主题的轻量化背景、提示区域 + */ +val BgRedLight = Color(0x0DFF2B2B) // 红色背景 5% 透明度 + +/** + * 浅色模式下黄色背景:#FFB703(10%透明度) + * 适用场景:黄色主题的轻量化背景、警告区域 + */ +val BgYellowLight = Color(0x1AFFB703) // 黄色背景 10% 透明度 + +/** + * 浅色模式下紫色背景:#6831FF(10%透明度) + * 适用场景:紫色主题的轻量化背景、特殊区域 + */ +val BgPurpleLight = Color(0x1A6831FF) // 紫色背景 10% 透明度 + +/** + * 浅色模式下绿色背景:#09BE4F(5%透明度) + * 适用场景:绿色主题的轻量化背景、成功提示区域 + */ +val BgGreenLight = Color(0x0D09BE4F) // 绿色背景 5% 透明度 + +// 背景色 - 深色模式 +/** + * 深色模式下页面背景色:#111111 + * 适用场景:深色模式下的应用整体背景、页面底色 + */ +val BgGreyDark = Color(0xFF111111) // 深色模式下的页面背景底色 + +/** + * 深色模式下白色背景:#1B1B1B + * 适用场景:深色模式下的卡片、弹窗等内容区域背景 + */ +val BgWhiteDark = Color(0xFF1B1B1B) // 深色模式下的白色背景 + +/** + * 深色模式下内容模块背景色:#222222 + * 适用场景:深色模式下的次级内容区域、列表项底色 + */ +val BgContentDark = Color(0xFF222222) // 深色模式下的内容模块底色 + +/** + * 深色模式下红色背景:#222222 + */ +val BgRedDark = Color(0xFF222222) + +/** + * 深色模式下黄色背景:#222222 + */ +val BgYellowDark = Color(0xFF222222) + +/** + * 深色模式下紫色背景:#222222 + */ +val BgPurpleDark = Color(0xFF222222) + +/** + * 深色模式下绿色背景:#222222 + */ +val BgGreenDark = Color(0xFF222222) + +// 遮罩颜色 +/** + * 浅色模式下遮罩颜色:60%透明度黑色 + * 适用场景:弹窗背景、加载状态遮罩 + */ +val MaskLight = Color(0x99000000) // rgba(0, 0, 0, 0.6) - 浅色模式 + +/** + * 深色模式下遮罩颜色:60%透明度黑色 + * 适用场景:深色模式下的弹窗背景、加载状态遮罩 + */ +val MaskDark = Color(0x99000000) // rgba(0, 0, 0, 0.6) - 深色模式 + +/** + * 浅色模式下按压状态颜色:20%透明度黑色 + * 适用场景:浅色模式下的按钮、卡片等组件的点击反馈 + */ +val PressLight = Color(0x33000000) // rgba(0, 0, 0, 0.2) - 浅色模式点击 + +/** + * 深色模式下按压状态颜色:20%透明度白色 + * 适用场景:深色模式下的按钮、卡片等组件的点击反馈 + */ +val PressDark = Color(0x33FFFFFF) // rgba(255, 255, 255, .2) - 深色模式点击 + +/** + * 浅色模式下轻量按压状态颜色:5%透明度黑色 + * 适用场景:弱态组件、背景较浅的点击反馈 + */ +val PressLightSoft = Color(0x0D000000) // rgba(0, 0, 0, 0.05) + +/** + * 深色模式下轻量按压状态颜色:10%透明度白色 + * 适用场景:弱态组件、背景较暗的点击反馈 + */ +val PressDarkSoft = Color(0x1AFFFFFF) // rgba(255, 255, 255, 0.1) + +/** + * 浅色模式下阴影颜色:#020426(5%透明度) + */ +val ShadowLight = Color(0x0D020426) + +/** + * 深色模式下阴影颜色:#111111(50%透明度) + */ +val ShadowDark = Color(0x80111111) + +// 边框颜色 +/** + * 浅色模式下边框颜色:#EEEEEE + * 适用场景:分割线、边框、描边等 + */ +val BorderLight = Color(0xFFEEEEEE) // 浅色模式边框 + +/** + * 深色模式下边框颜色:#242424 + * 适用场景:深色模式下的分割线、边框、描边等 + */ +val BorderDark = Color(0xFF242424) // 深色模式边框 + +// 渐变色起点和终点颜色 +/** + * 主色渐变起点:#465CFF + * 适用场景:与主色渐变终点配合使用,用于渐变按钮、背景等 + */ +val GradientPrimaryStart = Color(0xFF465CFF) // 主色渐变起点 + +/** + * 主色渐变终点:#6831FF + * 适用场景:与主色渐变起点配合使用,用于渐变按钮、背景等 + */ +val GradientPrimaryEnd = Color(0xFF6831FF) // 主色渐变终点 + +/** + * 红色渐变起点:#FD8C8C + * 适用场景:与红色渐变终点配合使用,用于警告类渐变效果 + */ +val GradientRedStart = Color(0xFFFD8C8C) // 红色渐变起点 + +/** + * 红色渐变终点:#FF2B2B + * 适用场景:与红色渐变起点配合使用,用于警告类渐变效果 + */ +val GradientRedEnd = Color(0xFFFF2B2B) // 红色渐变终点 \ No newline at end of file diff --git a/app/src/main/java/com/joker/kit/core/designsystem/theme/Shape.kt b/app/src/main/java/com/joker/kit/core/designsystem/theme/Shape.kt new file mode 100644 index 0000000..8fd363a --- /dev/null +++ b/app/src/main/java/com/joker/kit/core/designsystem/theme/Shape.kt @@ -0,0 +1,83 @@ +package com.joker.kit.core.designsystem.theme + +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Shapes +import androidx.compose.ui.unit.dp + +/** + * 圆角规范 + */ + +// 标准圆角数值定义 + +/** + * 超小圆角数值:4dp + */ +val RadiusXSmall = 4.dp + +/** + * 小圆角数值:8dp + */ +val RadiusSmall = 8.dp + +/** + * 中圆角数值:12dp + */ +val RadiusMedium = 12.dp + +/** + * 大圆角数值:16dp + */ +val RadiusLarge = 16.dp + +/** + * 超大圆角数值:24dp + */ +val RadiusExtraLarge = 24.dp + +/** + * 超小圆角:4dp + * 适用场景:极小的UI元素,如图标按钮 + */ +val ShapeXSmall = RoundedCornerShape(RadiusXSmall) // 超小圆角 8px + +/** + * 小圆角:8dp + * 适用场景:常规卡片、按钮等小型UI元素的圆角 + */ +val ShapeSmall = RoundedCornerShape(RadiusSmall) // 小圆角 16px + +/** + * 中圆角:12dp + * 适用场景:中型容器、对话框等组件的圆角 + */ +val ShapeMedium = RoundedCornerShape(RadiusMedium) // 中圆角 24px + +/** + * 大圆角:16dp + * 适用场景:分类列表等组件 + */ +val ShapeLarge = RoundedCornerShape(RadiusLarge) // 大圆角 32px + +/** + * 超大圆角:24dp + * 适用场景:大型卡片、底部弹窗等较大UI元素的圆角 + */ +val ShapeExtraLarge = RoundedCornerShape(RadiusExtraLarge) // 超大圆角 48px + +/** + * 圆形 + * 适用场景:头像、图标按钮等需要完全圆形的组件 + */ +val ShapeCircle = RoundedCornerShape(percent = 50) + +/** + * Material3 Shapes配置 + * 将自定义圆角规范应用于Material3设计系统 + */ +val AppShapes = Shapes( + small = ShapeSmall, + medium = ShapeMedium, + large = ShapeExtraLarge, + extraLarge = ShapeExtraLarge +) diff --git a/app/src/main/java/com/joker/kit/core/designsystem/theme/Size.kt b/app/src/main/java/com/joker/kit/core/designsystem/theme/Size.kt new file mode 100644 index 0000000..e1a4dbb --- /dev/null +++ b/app/src/main/java/com/joker/kit/core/designsystem/theme/Size.kt @@ -0,0 +1,117 @@ +package com.joker.kit.core.designsystem.theme + +import androidx.compose.ui.unit.dp + +/** + * 布局间距规范 + */ + +/** + * 超大垂直间距:32dp + * 适用场景:页面块与块之间的大间距,如不同功能模块之间的分隔 + */ +val SpaceVerticalXXLarge = 32.dp + +/** + * 特大垂直间距:24dp + * 适用场景:大模块内部的分隔,如卡片组之间的间距 + */ +val SpaceVerticalXLarge = 24.dp + +/** + * 大垂直间距:16dp + * 适用场景:卡片内部主要内容块之间的间距 + */ +val SpaceVerticalLarge = 16.dp + +/** + * 中等垂直间距:12dp + * 适用场景:内容区域的常规间距,如列表项之间的间距 + */ +val SpaceVerticalMedium = 12.dp + +/** + * 小垂直间距:8dp + * 适用场景:紧凑布局中的间距,如图标与文字之间 + */ +val SpaceVerticalSmall = 8.dp + +/** + * 超小垂直间距:4dp + * 适用场景:最小的垂直间隔,如紧凑排列的元素间距 + */ +val SpaceVerticalXSmall = 4.dp + +/** + * 超大水平间距:32dp + * 适用场景:页面左右边距,大型容器的内边距 + */ +val SpaceHorizontalXXLarge = 32.dp + +/** + * 特大水平间距:24dp + * 适用场景:大型容器内部的水平分隔 + */ +val SpaceHorizontalXLarge = 24.dp + +/** + * 大水平间距:16dp + * 适用场景:常规容器的左右边距,如卡片的内边距 + */ +val SpaceHorizontalLarge = 16.dp + +/** + * 中等水平间距:12dp + * 适用场景:中等容器的水平间距,如列表项的左右间距 + */ +val SpaceHorizontalMedium = 12.dp + +/** + * 小水平间距:8dp + * 适用场景:紧凑布局的水平间距,如图标与文字之间 + */ +val SpaceHorizontalSmall = 8.dp + +/** + * 超小平间间距:4dp + * 适用场景:最小的平间间隔,如紧凑排列的元素间距 + */ +val SpaceHorizontalXSmall = 4.dp + +/** + * 常用于内边距的值 + * 大内边距:16dp + * 适用场景:卡片、对话框等容器的内边距 + */ +val SpacePaddingLarge = 16.dp + +/** + * 中等内边距:12dp + * 适用场景:按钮、输入框等中型组件的内边距 + */ +val SpacePaddingMedium = 12.dp + +/** + * 小内边距:8dp + * 适用场景:紧凑型组件的内边距,如小型按钮 + */ +val SpacePaddingSmall = 8.dp + +/** + * 超小内边距:4dp + * 适用场景:最小的内边距,如标签、徽章等小组件 + */ +val SpacePaddingXSmall = 4.dp + +/** + * 其他常用尺寸 + * 分割线高度:0.5dp + * 适用场景:列表项之间的分割线、边框线等 + */ +val SpaceDivider = 0.5.dp // 分割线高度 + +/** + * 指示器高度:2dp + * 适用场景:选中指示器、进度条等 + */ +val SpaceIndicator = 2.dp // 指示器高度 diff --git a/app/src/main/java/com/joker/kit/core/designsystem/theme/Theme.kt b/app/src/main/java/com/joker/kit/core/designsystem/theme/Theme.kt new file mode 100644 index 0000000..c6c57bb --- /dev/null +++ b/app/src/main/java/com/joker/kit/core/designsystem/theme/Theme.kt @@ -0,0 +1,155 @@ +package com.joker.kit.core.designsystem.theme + +import android.os.Build +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.dynamicDarkColorScheme +import androidx.compose.material3.dynamicLightColorScheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.platform.LocalContext + +/** + * 深色主题配色方案 + * 定义MaterialTheme中深色模式下的各种颜色 + */ +private val DarkColorScheme = darkColorScheme( + primary = PrimaryDark, + onPrimary = TextWhite, + primaryContainer = PrimaryDark, + onPrimaryContainer = TextWhite, + inversePrimary = PrimaryLight, + secondary = ColorPurpleDark, + onSecondary = TextWhite, + secondaryContainer = ColorPurpleDark, + onSecondaryContainer = TextWhite, + tertiary = ColorSuccessDark, + onTertiary = TextWhite, + tertiaryContainer = ColorSuccessDark, + onTertiaryContainer = TextWhite, + background = BgGreyDark, + onBackground = TextPrimaryDark, + surface = BgWhiteDark, + onSurface = TextPrimaryDark, + surfaceVariant = BgContentDark, + onSurfaceVariant = TextSecondaryDark, + surfaceTint = PrimaryDark, + inverseSurface = BgGreyLight, + inverseOnSurface = TextPrimaryLight, + error = ColorDangerDark, + onError = TextWhite, + errorContainer = BgRedDark, + onErrorContainer = ColorDangerDark, + outline = BorderDark, + outlineVariant = BorderDark, + scrim = MaskDark, + surfaceBright = BgWhiteDark, + surfaceContainer = BgWhiteDark, + surfaceContainerHigh = BgWhiteDark, + surfaceContainerHighest = BgWhiteDark, + surfaceContainerLow = BgContentDark, + surfaceContainerLowest = BgGreyDark, + surfaceDim = BgGreyDark, + primaryFixed = PrimaryDark, + primaryFixedDim = PrimaryDark, + onPrimaryFixed = TextWhite, + onPrimaryFixedVariant = TextWhite, + secondaryFixed = ColorPurpleDark, + secondaryFixedDim = ColorPurpleDark, + onSecondaryFixed = TextWhite, + onSecondaryFixedVariant = TextWhite, + tertiaryFixed = ColorSuccessDark, + tertiaryFixedDim = ColorSuccessDark, + onTertiaryFixed = TextWhite, + onTertiaryFixedVariant = TextWhite +) + +/** + * 浅色主题配色方案 + * 定义MaterialTheme中浅色模式下的各种颜色 + */ +private val LightColorScheme = lightColorScheme( + primary = PrimaryLight, + onPrimary = TextWhite, + primaryContainer = PrimaryLight, + onPrimaryContainer = TextWhite, + inversePrimary = PrimaryDark, + secondary = ColorPurple, + onSecondary = TextWhite, + secondaryContainer = ColorPurple, + onSecondaryContainer = TextWhite, + tertiary = ColorSuccess, + onTertiary = TextWhite, + tertiaryContainer = ColorSuccess, + onTertiaryContainer = TextWhite, + background = BgGreyLight, + onBackground = TextPrimaryLight, + surface = BgWhiteLight, + onSurface = TextPrimaryLight, + surfaceVariant = BgContentLight, + onSurfaceVariant = TextSecondaryLight, + surfaceTint = PrimaryLight, + inverseSurface = BgGreyDark, + inverseOnSurface = TextPrimaryDark, + error = ColorDanger, + onError = TextWhite, + errorContainer = BgRedLight, + onErrorContainer = ColorDanger, + outline = BorderLight, + outlineVariant = BorderLight, + scrim = MaskLight, + surfaceBright = BgWhiteLight, + surfaceContainer = BgWhiteLight, + surfaceContainerHigh = BgWhiteLight, + surfaceContainerHighest = BgWhiteLight, + surfaceContainerLow = BgContentLight, + surfaceContainerLowest = BgGreyLight, + surfaceDim = BgGreyLight, + primaryFixed = PrimaryLight, + primaryFixedDim = PrimaryLight, + onPrimaryFixed = TextWhite, + onPrimaryFixedVariant = TextWhite, + secondaryFixed = ColorPurple, + secondaryFixedDim = ColorPurple, + onSecondaryFixed = TextWhite, + onSecondaryFixedVariant = TextWhite, + tertiaryFixed = ColorSuccess, + tertiaryFixedDim = ColorSuccess, + onTertiaryFixed = TextWhite, + onTertiaryFixedVariant = TextWhite +) + +/** + * 应用主题 Composable 函数 + * 根据系统设置决定使用深色或浅色主题,并应用所有设计系统元素 + * + * @param darkTheme 是否使用深色主题,默认跟随系统设置 + * @param dynamicColor 是否使用动态颜色(Android 12+特性),默认关闭 + * @param content 需要应用主题的内容 + * @author Joker.X + */ +@Composable +fun AppTheme( + darkTheme: Boolean = isSystemInDarkTheme(), + // Dynamic color is available on Android 12+ + dynamicColor: Boolean = false, + content: @Composable () -> Unit +) { + val colorScheme = when { + dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { + val context = LocalContext.current + if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) + } + + darkTheme -> DarkColorScheme + else -> LightColorScheme + } + + MaterialTheme( + colorScheme = colorScheme, + typography = Typography, + shapes = AppShapes, + content = content + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/joker/kit/core/designsystem/theme/Type.kt b/app/src/main/java/com/joker/kit/core/designsystem/theme/Type.kt new file mode 100644 index 0000000..dcb0595 --- /dev/null +++ b/app/src/main/java/com/joker/kit/core/designsystem/theme/Type.kt @@ -0,0 +1,194 @@ +package com.joker.kit.core.designsystem.theme + +import androidx.compose.material3.Typography +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.sp + +/** + * 字体规范 + * 1px = 0.5sp 转换结果,未提供的尺寸按层级递减补齐 + */ +val Typography = Typography( + + /** + * 中粗体 · 22sp / 31sp + * 使用场景:超大标题,文章标题 + */ + displayLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.SemiBold, // 中粗体 + fontSize = 22.sp, + lineHeight = 31.sp, + letterSpacing = 0.sp + ), + + /** + * 中粗体 · 18sp / 27sp + * 使用场景:大标题 + */ + displayMedium = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.SemiBold, // 中粗体 + fontSize = 18.sp, + lineHeight = 27.sp, + letterSpacing = 0.sp + ), + + /** + * 中粗体 · 16sp / 24sp + * 使用场景:展示级文案(中等长度) + */ + displaySmall = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.SemiBold, + fontSize = 16.sp, + lineHeight = 24.sp, + letterSpacing = 0.sp + ), + + /** + * 中黑体 · 16sp / 24sp + * 使用场景:二级标题、导航栏、列表、段落标题、按钮文字 + */ + headlineLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Medium, // 中黑体 + fontSize = 16.sp, + lineHeight = 24.sp, + letterSpacing = 0.sp + ), + + /** + * 中黑体 · 13sp / 20sp + * 使用场景:信息分组小标题 + */ + headlineSmall = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Medium, + fontSize = 13.sp, + lineHeight = 20.sp, + letterSpacing = 0.sp + ), + + /** + * 中黑体 · 14sp / 22sp + * 使用场景:类别名称 + */ + headlineMedium = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Medium, // 中黑体 + fontSize = 14.sp, + lineHeight = 22.sp, + letterSpacing = 0.sp + ), + + /** + * 中黑体 · 16sp / 20sp + * 使用场景:模块标题、弹窗标题 + */ + titleLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Medium, + fontSize = 16.sp, + lineHeight = 20.sp, + letterSpacing = 0.sp + ), + + /** + * 中黑体 · 14sp / 20sp + * 使用场景:列表项标题、辅助性标题 + */ + titleMedium = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Medium, + fontSize = 14.sp, + lineHeight = 20.sp, + letterSpacing = 0.sp + ), + + /** + * 中黑体 · 12sp / 18sp + * 使用场景:段落内小标题、二级描述 + */ + titleSmall = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Medium, + fontSize = 12.sp, + lineHeight = 18.sp, + letterSpacing = 0.sp + ), + + /** + * 常规体 · 14sp / 22sp + * 使用场景:正文内容、段落文字 + */ + bodyLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, // 常规体 + fontSize = 14.sp, + lineHeight = 22.sp, + letterSpacing = 0.sp + ), + + /** + * 常规体 · 12sp / 18sp + * 使用场景:底部导航栏文字、辅助性文字、标签文字 + */ + bodyMedium = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, // 常规体 + fontSize = 12.sp, + lineHeight = 18.sp, + letterSpacing = 0.sp + ), + + /** + * 常规体 · 11sp / 16sp + * 使用场景:次级正文、辅助段落 + */ + bodySmall = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 11.sp, + lineHeight = 16.sp, + letterSpacing = 0.sp + ), + + /** + * 中黑体 · 12sp / 16sp + * 使用场景:按钮、标签等操作文字 + */ + labelLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Medium, + fontSize = 12.sp, + lineHeight = 16.sp, + letterSpacing = 0.1.sp + ), + + /** + * 中黑体 · 11sp / 16sp + * 使用场景:辅助标签、徽标说明 + */ + labelMedium = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Medium, + fontSize = 11.sp, + lineHeight = 16.sp, + letterSpacing = 0.1.sp + ), + + /** + * 中黑体 · 10sp / 14sp + * 使用场景:最小标签、角标 + */ + labelSmall = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Medium, + fontSize = 10.sp, + lineHeight = 14.sp, + letterSpacing = 0.1.sp + ) +) diff --git a/app/src/main/java/com/joker/kit/ui/theme/Color.kt b/app/src/main/java/com/joker/kit/ui/theme/Color.kt deleted file mode 100644 index cfc9fc8..0000000 --- a/app/src/main/java/com/joker/kit/ui/theme/Color.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.joker.kit.ui.theme - -import androidx.compose.ui.graphics.Color - -val Purple80 = Color(0xFFD0BCFF) -val PurpleGrey80 = Color(0xFFCCC2DC) -val Pink80 = Color(0xFFEFB8C8) - -val Purple40 = Color(0xFF6650a4) -val PurpleGrey40 = Color(0xFF625b71) -val Pink40 = Color(0xFF7D5260) \ No newline at end of file diff --git a/app/src/main/java/com/joker/kit/ui/theme/Theme.kt b/app/src/main/java/com/joker/kit/ui/theme/Theme.kt deleted file mode 100644 index 4a6adcc..0000000 --- a/app/src/main/java/com/joker/kit/ui/theme/Theme.kt +++ /dev/null @@ -1,58 +0,0 @@ -package com.joker.kit.ui.theme - -import android.app.Activity -import android.os.Build -import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.darkColorScheme -import androidx.compose.material3.dynamicDarkColorScheme -import androidx.compose.material3.dynamicLightColorScheme -import androidx.compose.material3.lightColorScheme -import androidx.compose.runtime.Composable -import androidx.compose.ui.platform.LocalContext - -private val DarkColorScheme = darkColorScheme( - primary = Purple80, - secondary = PurpleGrey80, - tertiary = Pink80 -) - -private val LightColorScheme = lightColorScheme( - primary = Purple40, - secondary = PurpleGrey40, - tertiary = Pink40 - - /* Other default colors to override - background = Color(0xFFFFFBFE), - surface = Color(0xFFFFFBFE), - onPrimary = Color.White, - onSecondary = Color.White, - onTertiary = Color.White, - onBackground = Color(0xFF1C1B1F), - onSurface = Color(0xFF1C1B1F), - */ -) - -@Composable -fun AndroidProjectComposeTheme( - darkTheme: Boolean = isSystemInDarkTheme(), - // Dynamic color is available on Android 12+ - dynamicColor: Boolean = true, - content: @Composable () -> Unit -) { - val colorScheme = when { - dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { - val context = LocalContext.current - if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) - } - - darkTheme -> DarkColorScheme - else -> LightColorScheme - } - - MaterialTheme( - colorScheme = colorScheme, - typography = Typography, - content = content - ) -} \ No newline at end of file diff --git a/app/src/main/java/com/joker/kit/ui/theme/Type.kt b/app/src/main/java/com/joker/kit/ui/theme/Type.kt deleted file mode 100644 index c10e3d9..0000000 --- a/app/src/main/java/com/joker/kit/ui/theme/Type.kt +++ /dev/null @@ -1,34 +0,0 @@ -package com.joker.kit.ui.theme - -import androidx.compose.material3.Typography -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.font.FontFamily -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.sp - -// Set of Material typography styles to start with -val Typography = Typography( - bodyLarge = TextStyle( - fontFamily = FontFamily.Default, - fontWeight = FontWeight.Normal, - fontSize = 16.sp, - lineHeight = 24.sp, - letterSpacing = 0.5.sp - ) - /* Other default text styles to override - titleLarge = TextStyle( - fontFamily = FontFamily.Default, - fontWeight = FontWeight.Normal, - fontSize = 22.sp, - lineHeight = 28.sp, - letterSpacing = 0.sp - ), - labelSmall = TextStyle( - fontFamily = FontFamily.Default, - fontWeight = FontWeight.Medium, - fontSize = 11.sp, - lineHeight = 16.sp, - letterSpacing = 0.5.sp - ) - */ -) \ No newline at end of file