Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chip 구현 #27

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 121 additions & 0 deletions app/src/main/kotlin/com/yourssu/handy/demo/ChipPreview.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package com.yourssu.handy.demo

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.yourssu.handy.compose.Chip
import com.yourssu.handy.compose.ChipSize
import com.yourssu.handy.compose.ChipState
import com.yourssu.handy.compose.HandyTheme

@Preview
@Composable
fun ChipPreview() {
HandyTheme {
Row(
horizontalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier
.background(Color.White)
.padding(10.dp)
) {
Column(
verticalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier.padding(16.dp)
) {
Chip(
text = "Unselected",
chipState = ChipState.Unselected,
chipSize = ChipSize.Large
)

Chip(
text = "Selected",
chipState = ChipState.Selected,
chipSize = ChipSize.Large
)

Chip(
text = "Disabled",
chipState = ChipState.Disabled,
chipSize = ChipSize.Large
)
}
Column(
verticalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier.padding(16.dp)
) {
Chip(
text = "Unselected",
chipState = ChipState.Unselected,
chipSize = ChipSize.Small
)

Chip(
text = "Selected",
chipState = ChipState.Selected,
chipSize = ChipSize.Small
)

Chip(
text = "Disabled",
chipState = ChipState.Disabled,
chipSize = ChipSize.Small
)
}
}
}
}

@Preview
@Composable
fun HorizontalChipPreview() {
HandyTheme {
val state = rememberLazyListState(initialFirstVisibleItemIndex = 2)
LazyRow(
state = state,
horizontalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier
.background(Color.White)
.padding(10.dp)

) {
item {
Chip(
text = "Chip1",
chipState = ChipState.Unselected,
chipSize = ChipSize.Large
)
}
item {
Chip(
text = "Chip2",
chipState = ChipState.Selected,
chipSize = ChipSize.Large
)
}
item {
Chip(
text = "Chip3",
chipState = ChipState.Disabled,
chipSize = ChipSize.Large
)
}
item {
Chip(
text = "LongNameChip",
chipState = ChipState.Unselected,
chipSize = ChipSize.Large
)
}
}
}
}
116 changes: 116 additions & 0 deletions compose/src/main/kotlin/com/yourssu/handy/compose/Chip.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package com.yourssu.handy.compose

import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.yourssu.handy.compose.foundation.*
import com.yourssu.handy.compose.icons.HandyIcons
import com.yourssu.handy.compose.icons.line.*

enum class ChipSize(
internal val chipHeight: Dp
) {
Large(32.dp),
Small(24.dp)
}

enum class ChipState {
Unselected,
Selected,
Disabled
}

@Composable
fun Chip(
modifier: Modifier = Modifier,
minjun011026 marked this conversation as resolved.
Show resolved Hide resolved
text: String = "",
chipState: ChipState = ChipState.Unselected,
chipSize: ChipSize = ChipSize.Large,
leadingIcon: ImageVector? = null,
trailingIcon: ImageVector? = null,
chipOnClick: (() -> Unit) = {},
leadingIconOnClick: (() -> Unit) = {},
trailingIconOnClick: (() -> Unit) = {}
) {

val backgroundColor = when (chipState) {
ChipState.Unselected -> ColorGray100
ChipState.Selected -> ColorViolet100
ChipState.Disabled -> ColorGray50
}
val textColor = when (chipState) {
ChipState.Unselected -> ColorGray700
ChipState.Selected -> ColorViolet500
ChipState.Disabled -> ColorGray300
}

val textStyle: HandyTextStyle =
if (chipState == ChipState.Selected) HandyTypography.B3Sb14 else HandyTypography.B3Rg14

Box(
modifier = modifier
.wrapContentWidth(unbounded = true)
.height(chipSize.chipHeight)
.background(backgroundColor, shape = RoundedCornerShape(16.dp))
.clickable(
enabled = chipState != ChipState.Disabled,
onClick = { chipOnClick() })
.padding(horizontal = 12.dp),
contentAlignment = Alignment.Center
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(4.dp)
) {
leadingIcon?.let {
Icon(
leadingIcon,
tint = textColor,
iconSize = IconSize.XS,
modifier = Modifier.clickable(
enabled = chipState != ChipState.Disabled,
onClick = { leadingIconOnClick() },
interactionSource = remember { MutableInteractionSource() },
indication = null
)
)
}

Text(
text = if (text.length < 10) text else text.take(9) + "...",
color = textColor,
fontSize = 14.dp,
style = textStyle
)
Comment on lines +94 to +99
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Text(
text = if (text.length < 10) text else text.take(9) + "...",
color = textColor,
fontSize = 14.dp,
style = textStyle
)
Text(
text = text,
color = textColor,
style = textStyle,
maxLines = 1, // 최대 1줄
overflow = TextOverflow.Ellipsis // 길이 초과 시 말줄임표로
)

maxLines , overflow 속성 활용 시 text = if (text.length < 10) text else text.take(9) + "...", 처럼 직접 구현하실 필요없습니다!

이미 textStyle로 typo를 적용하셨어서 fontsize를 굳이 한번 더 적용하실 필요 없어요
HandyTextStyle 들어가보시면 이미 적용되어있습니다!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

overflow는 Modifier나 부모 layout 같은 배치 공간의 크기를 넘어설 때 말 줄임표 처리하는 것으로 알고 있는데
Figma의 Spec에는

Chip 하나당 최대 글자 수 10자 이내(공백 포함)로 제한됩니다. 최대 글자 수를 넘을 시 말줄임표 처리됩니다.

로 작성되어 있습니다.
Typography와 TextOverflow를 찾아봤는데 이 부분을 TextOverflow를 이용해서 처리해주는 부분을 발견하지 못 했습니다!
혹시 글자수에 따른 말줄임표 기능이 TextOverflow에 있는지 알려주시면 감사하겠습니다!


trailingIcon?.let {
Icon(
trailingIcon,
tint = textColor,
iconSize = IconSize.XS,
modifier = Modifier.clickable(
enabled = chipState != ChipState.Disabled,
onClick = { trailingIconOnClick() },
interactionSource = remember { MutableInteractionSource() },
indication = null
)
)
}
}
}
}
26 changes: 26 additions & 0 deletions compose/src/main/kotlin/com/yourssu/handy/compose/SearchBar.kt
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 파일은 잘못 포함된 것 같네요

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

앗 SearchBar를 만들어야 하는 줄 알고 만들었던 건데 같이 올려버렸네요

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.yourssu.handy.compose

import androidx.compose.foundation.layout.Row
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.input.TextFieldValue

enum class SearchBarState {
Inactive,
Focused,
Typing,
Completed
}

@Composable
fun SearchBar(
modifier: Modifier = Modifier,
text : String,
onTextChange : (String) -> Unit
){
var searchText by remember { mutableStateOf(TextFieldValue(text)) }
}