Skip to content
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
package com.team.prezel.core.designsystem.component

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.expandVertically
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkVertically
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Icon
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
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.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.team.prezel.core.designsystem.R
import com.team.prezel.core.designsystem.foundation.typography.PrezelTextStyles
import com.team.prezel.core.designsystem.icon.PrezelIcons
import com.team.prezel.core.designsystem.preview.PreviewScaffold
import com.team.prezel.core.designsystem.preview.ThemePreview
import com.team.prezel.core.designsystem.theme.PrezelTheme

@Composable
fun PrezelAccordion(
modifier: Modifier = Modifier,
expanded: Boolean,
onExpandedChange: (Boolean) -> Unit,
enabled: Boolean = true,
showDivider: Boolean = false,
header: @Composable (expanded: Boolean) -> Unit,
label: @Composable (expanded: Boolean) -> Unit,
content: @Composable () -> Unit,
) {
val rotation by animateFloatAsState(
targetValue = if (expanded) 180f else 0f,
label = "accordionChevronRotation",
)

Surface(
modifier = modifier,
color = Color.Transparent,
) {
Column {
PrezelAccordionHeader(
enabled = enabled,
onClick = { onExpandedChange(!expanded) },
header = { header(expanded) },
label = { label(expanded) },
chevron = { PrezelAccordionChevron(rotation = rotation) },
)

PrezelAccordionDivider(showDivider = showDivider)

PrezelAccordionContent(
expanded = expanded,
content = content,
)
}
}
}

@Composable
private fun PrezelAccordionHeader(
enabled: Boolean,
onClick: () -> Unit,
header: @Composable () -> Unit,
label: @Composable () -> Unit,
chevron: @Composable () -> Unit,
) {
Row(
modifier = Modifier
.fillMaxWidth()
.defaultMinSize(minHeight = 48.dp)
.clickable(
enabled = enabled,
indication = null,
interactionSource = remember { MutableInteractionSource() },
onClick = onClick,
),
verticalAlignment = Alignment.CenterVertically,
) {
Box(
modifier = Modifier
.weight(1f),
) {
header()
}
Spacer(Modifier.width(8.dp))

label()

Spacer(Modifier.width(8.dp))

chevron()
}
}

@Composable
private fun PrezelAccordionChevron(rotation: Float) {
Icon(
painter = painterResource(PrezelIcons.ChevronDown),
contentDescription = stringResource(R.string.core_designsystem_accordion_desc),
modifier = Modifier
.size(24.dp)
.rotate(rotation),
tint = PrezelTheme.colors.iconRegular,
)
}

@Composable
private fun PrezelAccordionDivider(showDivider: Boolean) {
if (!showDivider) return

PrezelHorizontalDivider(
type = PrezelDividerType.THICK,
color = PrezelTheme.colors.borderSmall,
)
}

@Composable
private fun PrezelAccordionContent(
expanded: Boolean,
content: @Composable () -> Unit,
) {
AnimatedVisibility(
visible = expanded,
enter = fadeIn() + expandVertically(),
exit = fadeOut() + shrinkVertically(),
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(12.dp),
) {
content()
}
}
}

@ThemePreview
@Composable
private fun PrezelAccordionPreview_Collapsed() {
PrezelTheme {
PreviewScaffold {
PrezelAccordion(
expanded = false,
onExpandedChange = {},
showDivider = true,
header = {
Text(
text = "Title",
style = PrezelTextStyles.Body2Medium.toTextStyle(),
color = PrezelTheme.colors.textLarge,
)
},
label = {
Text(
text = "Label",
style = PrezelTextStyles.Body2Bold.toTextStyle(),
color = PrezelTheme.colors.interactiveRegular,
)
},
) {
Text(
text = "Content",
style = PrezelTextStyles.Body3Regular.toTextStyle(),
color = PrezelTheme.colors.textRegular,
)
}
}
}
}

@ThemePreview
@Composable
private fun PrezelAccordionPreview_Expanded() {
PrezelTheme {
PreviewScaffold {
PrezelAccordion(
expanded = true,
onExpandedChange = {},
showDivider = true,
header = {
Text(
text = "Title",
modifier = Modifier.padding(start = 12.dp),
style = PrezelTextStyles.Body2Medium.toTextStyle(),
color = PrezelTheme.colors.textLarge,
)
},
label = {
Text(
text = "Label",
style = PrezelTextStyles.Body2Bold.toTextStyle(),
color = PrezelTheme.colors.interactiveRegular,
)
},
) {
Text(
text = "Content 영역입니다.\n여기에 설명이나 리스트가 들어갑니다.",
style = PrezelTextStyles.Caption2Medium.toTextStyle(),
color = PrezelTheme.colors.textLarge,
)
}
}
}
}

@ThemePreview
@Composable
private fun PrezelAccordionPreview_Interactive() {
PrezelTheme {
var expanded by remember { mutableStateOf(false) }

PreviewScaffold {
PrezelAccordion(
expanded = expanded,
onExpandedChange = { expanded = it },
showDivider = true,
header = {
Row(
verticalAlignment = Alignment.CenterVertically,
) {
PrezelCheckbox(
checked = false,
size = CheckboxSize.REGULAR,
onCheckedChange = {},
)

Spacer(Modifier.width(4.dp))

Text(text = "(필수) 이용약관")
}
},
label = {
Text(
text = "자세히 보기",
style = PrezelTextStyles.Caption2Medium.toTextStyle(),
color = PrezelTheme.colors.textMedium,
)
},
) {
Text(
text = "클릭하면 열리고 닫힙니다.",
style = PrezelTextStyles.Caption2Medium.toTextStyle(),
color = PrezelTheme.colors.textLarge,
)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,22 +102,22 @@ private fun PrezelTopAppBarWithAllIconsPreview() {
leadingIcon = {
IconButton(onClick = {}) {
Icon(
painter = painterResource(PrezelIcons.Blank),
painter = painterResource(PrezelIcons.ArrowLeft),
contentDescription = "뒤로가기",
)
}
},
trailingIcons = {
IconButton(onClick = {}) {
Icon(
painter = painterResource(PrezelIcons.Blank),
painter = painterResource(PrezelIcons.Search),
contentDescription = "검색",
)
}
IconButton(onClick = {}) {
Icon(
painter = painterResource(PrezelIcons.Blank),
contentDescription = "더보기",
painter = painterResource(PrezelIcons.Menu),
contentDescription = "메뉴",
)
}
},
Expand All @@ -142,7 +142,7 @@ private fun PrezelTopAppBarScrollTestPreview() {
leadingIcon = {
IconButton(onClick = {}) {
Icon(
painter = painterResource(PrezelIcons.Blank),
painter = painterResource(PrezelIcons.ArrowLeft),
contentDescription = "뒤로가기",
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,30 +19,39 @@ object PrezelIcons {
val ChevronUp = R.drawable.core_designsystem_ic_chevron_up
val College = R.drawable.core_designsystem_ic_college
val Company = R.drawable.core_designsystem_ic_company
val Edit = R.drawable.core_designsystem_ic_edit
val Folder = R.drawable.core_designsystem_ic_folder
val Gallery = R.drawable.core_designsystem_ic_gallery
val Hand = R.drawable.core_designsystem_ic_hand
val Home = R.drawable.core_designsystem_ic_home
val Info = R.drawable.core_designsystem_ic_info
val InfoCircle = R.drawable.core_designsystem_ic_info_circle
val InfoCircleFilled = R.drawable.core_designsystem_ic_info_circle_filled
val InfoCircleOutlined = R.drawable.core_designsystem_ic_info_circle_outlined
val Kakao = R.drawable.core_designsystem_ic_kakao
val Lock = R.drawable.core_designsystem_ic_lock
val Menu = R.drawable.core_designsystem_ic_menu
val Mic = R.drawable.core_designsystem_ic_mic
val Pause = R.drawable.core_designsystem_ic_pause
val Person = R.drawable.core_designsystem_ic_person
val Play = R.drawable.core_designsystem_ic_play
val Plus = R.drawable.core_designsystem_ic_plus
val Profile = R.drawable.core_designsystem_ic_profile
val QuestionCircleFilled = R.drawable.core_designsystem_ic_question_circle_filled
val QuestionCircleOutlined = R.drawable.core_designsystem_ic_question_circle_outlined
val RadioCircleFilled = R.drawable.core_designsystem_ic_radio_circle_filled
val RadioCircleOutlined = R.drawable.core_designsystem_ic_radio_circle_outlined
val Recording = R.drawable.core_designsystem_ic_recording
val Reset = R.drawable.core_designsystem_ic_reset
val Rotate = R.drawable.core_designsystem_ic_rotate
val Search = R.drawable.core_designsystem_ic_search
val Setting = R.drawable.core_designsystem_ic_setting
val Stop = R.drawable.core_designsystem_ic_stop
val Storage = R.drawable.core_designsystem_ic_storage
val Trophy = R.drawable.core_designsystem_ic_trophy
val Upload = R.drawable.core_designsystem_ic_upload
val Video = R.drawable.core_designsystem_ic_video
val Voice = R.drawable.core_designsystem_ic_voice
val Warning = R.drawable.core_designsystem_ic_warning
val WarningCircle = R.drawable.core_designsystem_ic_warning_circle
val WarningCircleFilled = R.drawable.core_designsystem_ic_warning_circle_filled
val WarningCircleOutlined = R.drawable.core_designsystem_ic_warning_circle_outlined
val ZoomIn = R.drawable.core_designsystem_ic_zoom_in
val ZoomOut = R.drawable.core_designsystem_ic_zoom_out
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M12,2.25C15.314,2.25 18,4.69 18,8.501L17.998,8.679C17.905,12.08 15.184,15.376 12.738,15.959C12.688,16.858 12.427,17.537 11.845,18.018C11.546,18.264 11.204,18.422 10.872,18.544C10.544,18.663 10.17,18.766 9.809,18.87C8.406,19.275 8.28,20.273 8.477,20.656C8.667,21.024 8.523,21.477 8.154,21.667C7.786,21.857 7.334,21.712 7.144,21.344C6.378,19.86 7.388,18.008 9.393,17.429C9.789,17.314 10.093,17.231 10.357,17.135C10.616,17.04 10.779,16.952 10.89,16.86C11.033,16.743 11.192,16.537 11.236,15.952C8.797,15.353 6.095,12.068 6.002,8.679L6,8.501C6,4.69 8.686,2.25 12,2.25ZM12,3.75C9.515,3.75 7.5,5.518 7.5,8.501C7.5,9.984 8.166,11.543 9.164,12.747C10.203,14.001 11.322,14.55 12,14.55C12.678,14.55 13.797,14.001 14.836,12.747C15.834,11.543 16.5,9.984 16.5,8.501C16.5,5.518 14.485,3.75 12,3.75ZM11.718,5.595C11.801,5.189 12.197,4.928 12.603,5.011C13.28,5.15 13.888,5.518 14.324,6.054C14.761,6.589 15,7.259 15,7.95C15,8.364 14.664,8.7 14.25,8.7C13.836,8.7 13.5,8.364 13.5,7.95C13.5,7.605 13.381,7.27 13.163,7.002C12.944,6.734 12.64,6.55 12.301,6.48C11.896,6.397 11.634,6.001 11.718,5.595Z"
android:pathData="M12,2C15.866,2 19,4.653 19,8.795C19,12.675 16.368,16.485 12.747,16.952C12.748,16.968 12.75,16.984 12.75,17C12.75,17.906 12.494,18.594 11.854,19.048C11.573,19.247 11.255,19.372 10.952,19.467C10.652,19.561 10.309,19.642 9.977,19.725C9.334,19.884 8.996,20.171 8.852,20.396C8.711,20.614 8.742,20.772 8.794,20.859C9.007,21.214 8.893,21.675 8.538,21.889C8.183,22.102 7.722,21.987 7.509,21.633C7.119,20.984 7.189,20.209 7.59,19.585C7.987,18.966 8.694,18.497 9.616,18.269C9.98,18.178 10.26,18.111 10.504,18.035C10.744,17.96 10.892,17.891 10.987,17.823C11.1,17.743 11.25,17.604 11.25,17C11.25,16.984 11.251,16.968 11.252,16.952C7.632,16.485 5,12.674 5,8.795C5,4.653 8.134,2 12,2ZM14.203,4.071C13.933,4.016 13.669,4.19 13.613,4.461C13.558,4.731 13.732,4.995 14.002,5.051C14.566,5.166 15.073,5.474 15.438,5.92C15.801,6.366 16,6.924 16,7.5C16,7.776 16.224,8 16.5,8C16.776,8 17,7.776 17,7.5C17,6.694 16.721,5.913 16.212,5.288C15.702,4.663 14.993,4.233 14.203,4.071Z"
android:fillColor="#6E737D"/>
</vector>
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M15,3.003C15.414,3.003 15.75,3.339 15.75,3.753V4.999H18.5C19.881,4.999 21,6.118 21,7.499V18.501L20.987,18.756C20.868,19.932 19.932,20.868 18.756,20.987L18.5,21.001H5.5L5.244,20.987C4.068,20.868 3.132,19.932 3.013,18.756L3,18.501V7.499C3,6.118 4.119,4.999 5.5,4.999H8.25V3.753C8.25,3.339 8.586,3.003 9,3.003C9.414,3.003 9.75,3.339 9.75,3.753V4.999H14.25V3.753C14.25,3.339 14.586,3.003 15,3.003ZM4.5,12V18.501C4.501,19.053 4.948,19.501 5.5,19.501H18.5C19.052,19.501 19.5,19.053 19.5,18.501V12H4.5ZM5.5,6.499C4.948,6.499 4.5,6.947 4.5,7.499V10.5H19.5V7.499C19.5,6.947 19.052,6.499 18.5,6.499H5.5Z"
android:pathData="M21,18.5C21,19.881 19.881,21 18.5,21H5.5C4.119,21 3,19.881 3,18.5V10.5H21V18.5ZM15,1.999C15.414,1.999 15.75,2.335 15.75,2.749V4H18.5C19.881,4 21,5.119 21,6.5V9.5H3V6.5C3,5.119 4.119,4 5.5,4H8.25V2.749C8.25,2.335 8.586,1.999 9,1.999C9.414,1.999 9.75,2.335 9.75,2.749V4H14.25V2.749C14.25,2.335 14.586,1.999 15,1.999Z"
android:fillColor="#6E737D"/>
</vector>
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M18.722,7.471C19.015,7.178 19.49,7.178 19.782,7.471C20.075,7.764 20.075,8.238 19.782,8.531L10.531,17.782C10.391,17.923 10.2,18.002 10.001,18.002C9.802,18.002 9.612,17.923 9.471,17.782L4.22,12.531C3.927,12.238 3.927,11.764 4.22,11.471C4.513,11.178 4.988,11.178 5.28,11.471L10.001,16.191L18.722,7.471Z"
android:pathData="M20.677,4.266C20.945,3.95 21.418,3.91 21.734,4.177C22.05,4.444 22.09,4.918 21.823,5.234L9.573,19.734C9.431,19.902 9.223,19.999 9.003,20C8.784,20.001 8.575,19.906 8.432,19.74L2.182,12.496C1.912,12.182 1.947,11.709 2.26,11.439C2.574,11.168 3.047,11.203 3.318,11.517L8.994,18.095L20.677,4.266Z"
android:fillColor="#6E737D"/>
</vector>
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M11.749,4.555C11.908,4.482 12.092,4.482 12.251,4.555L21.251,8.702C21.716,8.917 21.716,9.579 21.251,9.794L18.75,10.946V15.443C18.75,16.365 18.19,17.194 17.336,17.536L12.835,19.339C12.634,19.42 12.424,19.47 12.212,19.49C12.176,19.493 12.141,19.496 12.106,19.497C12.035,19.501 11.963,19.501 11.892,19.497C11.857,19.496 11.821,19.493 11.786,19.49C11.574,19.47 11.364,19.42 11.163,19.339L6.662,17.536C5.808,17.194 5.248,16.365 5.247,15.443V10.945L4.214,10.469V15.727L4.647,16.479C4.73,16.622 4.682,16.809 4.529,16.873C4.235,16.997 3.918,17.062 3.597,17.062C3.276,17.062 2.959,16.997 2.665,16.873C2.513,16.809 2.464,16.622 2.547,16.479L3.014,15.668V9.915L2.749,9.794L2.668,9.748C2.311,9.515 2.311,8.981 2.668,8.747L2.749,8.702L11.749,4.555ZM6.748,15.443C6.748,15.559 6.774,15.67 6.822,15.769C6.854,15.835 6.896,15.897 6.945,15.951C6.995,16.005 7.053,16.053 7.118,16.091C7.15,16.11 7.184,16.126 7.219,16.141L11.72,17.944C11.743,17.953 11.766,17.961 11.788,17.967C11.949,18.014 12.121,18.006 12.277,17.944L16.778,16.141C16.814,16.126 16.848,16.11 16.88,16.091C16.945,16.053 17.003,16.005 17.052,15.951C17.102,15.897 17.144,15.835 17.176,15.769C17.223,15.67 17.25,15.559 17.25,15.443V11.637L12.251,13.941C12.092,14.014 11.908,14.014 11.749,13.941L6.748,11.636V15.443ZM5.154,9.248L12,12.402L18.847,9.248L12,6.093L5.154,9.248Z"
android:pathData="M19.063,16.725C19.063,17.543 18.65,18.306 17.966,18.754C14.418,21.074 9.832,21.074 6.284,18.754C5.599,18.306 5.186,17.543 5.186,16.725V11.942L10.537,14.606C11.536,15.104 12.713,15.104 13.713,14.606L19.063,11.942V16.725ZM10.99,3.766C11.704,3.41 12.545,3.41 13.259,3.766L21.439,7.839C22.185,8.21 22.185,9.268 21.439,9.64L13.259,13.713C12.545,14.068 11.704,14.068 10.99,13.713L4.251,10.356V16.292L4.801,17.245C4.883,17.389 4.835,17.574 4.682,17.639C4.389,17.763 4.072,17.827 3.751,17.827C3.43,17.827 3.113,17.763 2.819,17.639C2.667,17.574 2.618,17.389 2.701,17.245L3.251,16.292V9.858L2.81,9.64C2.065,9.268 2.065,8.21 2.81,7.839L10.99,3.766Z"
android:fillColor="#6E737D"/>
</vector>
Loading