diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml
index 2c6ea3d8..b268ef36 100644
--- a/.idea/deploymentTargetSelector.xml
+++ b/.idea/deploymentTargetSelector.xml
@@ -5,9 +5,6 @@
-
-
-
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
index e69de29b..7061a0d6 100644
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml
index 931b96c3..16660f1d 100644
--- a/.idea/runConfigurations.xml
+++ b/.idea/runConfigurations.xml
@@ -5,8 +5,12 @@
+
+
+
+
diff --git a/app/src/main/kotlin/com/yourssu/handy/demo/ListPreview.kt b/app/src/main/kotlin/com/yourssu/handy/demo/ListPreview.kt
new file mode 100644
index 00000000..78bdcd99
--- /dev/null
+++ b/app/src/main/kotlin/com/yourssu/handy/demo/ListPreview.kt
@@ -0,0 +1,51 @@
+package com.yourssu.handy.demo
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import com.yourssu.handy.compose.HandyTheme
+import com.yourssu.handy.compose.icons.HandyIcons
+import com.yourssu.handy.compose.icons.line.ArrowsChevronRight
+import com.yourssu.handy.compose.icons.line.User
+
+@Composable
+@Preview
+fun ListPreview() {
+ HandyTheme {
+ Column(
+ modifier = Modifier.fillMaxWidth(),
+ verticalArrangement = Arrangement.spacedBy(10.dp)
+ ) {
+ com.yourssu.handy.compose.list.List(
+ headline = "Enable List Title",
+ onClick = {},
+ leadingIcon = HandyIcons.Line.User,
+ trailingIcon = HandyIcons.Line.ArrowsChevronRight,
+ )
+
+ com.yourssu.handy.compose.list.List(
+ headline = "Disable List Title",
+ onClick = {},
+ leadingIcon = HandyIcons.Line.User,
+ trailingIcon = HandyIcons.Line.ArrowsChevronRight,
+ enabled = false
+ )
+
+ com.yourssu.handy.compose.list.List(
+ headline = "Loooooooooong Titleeeeeeeeeeeeeeeeeeeeeeeeeee",
+ onClick = {},
+ leadingIcon = HandyIcons.Line.User,
+ trailingIcon = HandyIcons.Line.ArrowsChevronRight,
+ )
+
+ com.yourssu.handy.compose.list.List(
+ headline = "Default Title",
+ onClick = {},
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/compose/src/main/kotlin/com/yourssu/handy/compose/foundation/SemanticColors.kt b/compose/src/main/kotlin/com/yourssu/handy/compose/foundation/SemanticColors.kt
index 5a50a8de..981c275b 100644
--- a/compose/src/main/kotlin/com/yourssu/handy/compose/foundation/SemanticColors.kt
+++ b/compose/src/main/kotlin/com/yourssu/handy/compose/foundation/SemanticColors.kt
@@ -123,6 +123,11 @@ data class ColorScheme(
val switchSelected: Color = ColorViolet500,
val switchDisabled: Color = ColorGray200,
val switchThumb: Color = ColorNeutralWhite,
+
+ // List
+ val listEnabled: Color = ColorNeutralWhite,
+ val listPressed: Color = ColorGray50,
+ val listDisabled: Color = ColorNeutralWhite,
)
val lightColorScheme = ColorScheme()
diff --git a/compose/src/main/kotlin/com/yourssu/handy/compose/list/List.kt b/compose/src/main/kotlin/com/yourssu/handy/compose/list/List.kt
new file mode 100644
index 00000000..494b8176
--- /dev/null
+++ b/compose/src/main/kotlin/com/yourssu/handy/compose/list/List.kt
@@ -0,0 +1,112 @@
+package com.yourssu.handy.compose.list
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.interaction.collectIsPressedAsState
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.vector.ImageVector
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import com.yourssu.handy.compose.HandyTheme
+import com.yourssu.handy.compose.Icon
+import com.yourssu.handy.compose.Text
+import com.yourssu.handy.compose.icons.HandyIcons
+import com.yourssu.handy.compose.icons.line.ArrowsChevronRight
+import com.yourssu.handy.compose.icons.line.User
+
+@Composable
+fun List(
+ headline: String,
+ onClick: () -> Unit,
+ modifier: Modifier = Modifier,
+ enabled: Boolean = true,
+ leadingIcon: ImageVector? = null,
+ trailingIcon: ImageVector? = null,
+ headlineColor: Color = HandyTheme.colors.textBasicPrimary,
+ leadingIconColor: Color = HandyTheme.colors.iconBasicPrimary,
+ tailingIconColor: Color = HandyTheme.colors.iconBasicTertiary,
+ interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
+) {
+ val pressed by interactionSource.collectIsPressedAsState()
+ val backgroundColor = determineContainerColor(enabled, pressed)
+
+ Row(
+ modifier = modifier
+ .fillMaxWidth()
+ .height(64.dp)
+ .clickable(
+ onClick = onClick,
+ enabled = enabled,
+ interactionSource = interactionSource,
+ indication = null
+ )
+ .background(backgroundColor),
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ leadingIcon?.let {
+ Icon(
+ imageVector = leadingIcon,
+ contentDescription = "leadingIcon",
+ tint = determineContentColor(enabled, leadingIconColor),
+ modifier = Modifier.padding(start = 16.dp)
+ )
+ }
+
+ Text(
+ text = headline,
+ color = determineContentColor(enabled, headlineColor),
+ modifier = Modifier
+ .padding(horizontal = 16.dp)
+ .weight(1f),
+ overflow = TextOverflow.Ellipsis,
+ maxLines = 1
+ )
+
+ trailingIcon?.let {
+ Icon(
+ imageVector = trailingIcon,
+ contentDescription = "trailingIcon",
+ tint = determineContentColor(enabled, tailingIconColor),
+ modifier = Modifier
+ .padding(end = 16.dp)
+ .align(Alignment.CenterVertically)
+ )
+ }
+ }
+}
+
+@Composable
+fun determineContainerColor(
+ enabled: Boolean,
+ pressed: Boolean,
+): Color {
+ return when {
+ !enabled -> HandyTheme.colors.listDisabled
+ pressed -> HandyTheme.colors.listPressed
+ else -> HandyTheme.colors.listEnabled
+ }
+}
+
+@Composable
+fun determineContentColor(
+ enabled: Boolean,
+ contentColor: Color
+): Color {
+ return when {
+ !enabled -> HandyTheme.colors.textBasicDisabled
+ else -> contentColor
+ }
+}
\ No newline at end of file