From 6fd461c02527761575c22093f1e715a978ecf3d0 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Sun, 22 Mar 2026 02:49:27 +0900 Subject: [PATCH 01/42] =?UTF-8?q?feat:=20PrezelTouchArea=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../actions/button/PrezelButtonIcon.kt | 25 +++++++ .../component/base/PrezelTouchArea.kt | 65 +++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonIcon.kt create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelTouchArea.kt diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonIcon.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonIcon.kt new file mode 100644 index 0000000..0bf8cb2 --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonIcon.kt @@ -0,0 +1,25 @@ +package com.team.prezel.core.designsystem.component.actions.button + +import androidx.annotation.DrawableRes +import androidx.compose.foundation.Image +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource + +@Composable +internal fun PrezelButtonIcon( + modifier: Modifier, + @DrawableRes drawableRes: Int, + tint: Color, +) { + Image( + modifier = modifier, + painter = painterResource(id = drawableRes), + contentScale = ContentScale.FillHeight, + colorFilter = ColorFilter.tint(color = tint), + contentDescription = null, + ) +} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelTouchArea.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelTouchArea.kt new file mode 100644 index 0000000..dc31ef1 --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelTouchArea.kt @@ -0,0 +1,65 @@ +package com.team.prezel.core.designsystem.component.base + +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.BoxScope +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.wrapContentSize +import androidx.compose.material3.ripple +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +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.RectangleShape +import androidx.compose.ui.graphics.Shape +import androidx.compose.ui.unit.dp +import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.theme.PrezelTheme + +@Composable +fun PrezelTouchArea( + modifier: Modifier = Modifier, + extraTouchPadding: PaddingValues = PaddingValues(0.dp), + shape: Shape = RectangleShape, + enabled: Boolean = true, + rippleColor: Color = Color.Unspecified, + isUseRipple: Boolean = true, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, + onClick: () -> Unit, + content: @Composable BoxScope.() -> Unit, +) { + Box( + modifier = modifier + .wrapContentSize() + .clip(shape = shape) + .clickable( + enabled = enabled, + onClick = onClick, + indication = if (isUseRipple) ripple(color = rippleColor) else null, + interactionSource = interactionSource, + ).padding(extraTouchPadding), + contentAlignment = Alignment.Center, + ) { + content() + } +} + +@ThemePreview +@Composable +private fun PrezelTouchAreaPreview() { + PrezelTheme { + PrezelTouchArea(onClick = {}) { + Box( + modifier = Modifier + .size(48.dp) + .background(Color.Cyan), + ) + } + } +} From 729187fa845853c05a975f63e90e83a692601085 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Sun, 22 Mar 2026 02:50:02 +0900 Subject: [PATCH 02/42] =?UTF-8?q?feat:=20PrezelButtonLayout=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../actions/button/PrezelButtonLayout.kt | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonLayout.kt diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonLayout.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonLayout.kt new file mode 100644 index 0000000..7886a1a --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonLayout.kt @@ -0,0 +1,37 @@ +package com.team.prezel.core.designsystem.component.actions.button + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier + +@Composable +internal fun PrezelButtonLayout( + modifier: Modifier, + horizontalArrangement: Arrangement.Horizontal, + text: @Composable (() -> Unit)? = null, + leadingIcon: @Composable (() -> Unit)? = null, +) { + Box( + modifier = modifier, + contentAlignment = Alignment.Center, + ) { + Row( + horizontalArrangement = horizontalArrangement, + verticalAlignment = Alignment.CenterVertically, + ) { + leadingIcon?.let { leadingIcon() } + + text?.let { + Box( + modifier = Modifier.wrapContentHeight(), + contentAlignment = Alignment.Center, + content = { text() }, + ) + } + } + } +} From 2c516b8547998cc591cdfea20d05f1ba2a2b9ecf Mon Sep 17 00:00:00 2001 From: moondev03 Date: Sun, 22 Mar 2026 02:50:18 +0900 Subject: [PATCH 03/42] =?UTF-8?q?feat:=20=EB=B2=84=ED=8A=BC=20=EB=94=94?= =?UTF-8?q?=EC=9E=90=EC=9D=B8=20=EC=8B=9C=EC=8A=A4=ED=85=9C=20=EA=B5=AC?= =?UTF-8?q?=EC=84=B1=EC=9D=84=20=EC=9C=84=ED=95=9C=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=EB=B0=8F=20CompositionLocal=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../button/config/LocalPrezelButtonBorder.kt | 45 +++++++++ .../button/config/LocalPrezelButtonContent.kt | 99 +++++++++++++++++++ .../config/LocalPrezelButtonTextStyle.kt | 34 +++++++ .../button/config/PrezelButtonDefaults.kt | 79 +++++++++++++++ .../button/config/PrezelButtonUtils.kt | 80 +++++++++++++++ 5 files changed, 337 insertions(+) create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/LocalPrezelButtonBorder.kt create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/LocalPrezelButtonContent.kt create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/LocalPrezelButtonTextStyle.kt create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonDefaults.kt create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonUtils.kt diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/LocalPrezelButtonBorder.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/LocalPrezelButtonBorder.kt new file mode 100644 index 0000000..d526ed7 --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/LocalPrezelButtonBorder.kt @@ -0,0 +1,45 @@ +package com.team.prezel.core.designsystem.component.actions.button.config + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.ProvidableCompositionLocal +import androidx.compose.runtime.staticCompositionLocalOf +import androidx.compose.ui.graphics.Color +import com.team.prezel.core.designsystem.theme.PrezelTheme + +val LocalPrezelButtonBorder = PrezelButtonBorderCompositionLocal() + +interface PrezelButtonBorderLoader { + @Composable + fun getBorderColor( + type: ButtonType, + hierarchy: ButtonHierarchy, + enabled: Boolean, + ): Color +} + +internal class PrezelButtonBorderLoaderImpl : PrezelButtonBorderLoader { + @Composable + override fun getBorderColor( + type: ButtonType, + hierarchy: ButtonHierarchy, + enabled: Boolean, + ): Color { + if (type != ButtonType.OUTLINED) return Color.Transparent + if (!enabled) return PrezelTheme.colors.borderDisabled + + return when (hierarchy) { + ButtonHierarchy.PRIMARY -> PrezelTheme.colors.interactiveRegular + ButtonHierarchy.SECONDARY -> PrezelTheme.colors.borderMedium + } + } +} + +@JvmInline +value class PrezelButtonBorderCompositionLocal internal constructor( + private val delegate: ProvidableCompositionLocal = staticCompositionLocalOf { PrezelButtonBorderLoaderImpl() }, +) { + val current: PrezelButtonBorderLoader + @Composable get() = delegate.current + + infix fun provides(value: PrezelButtonBorderLoader) = delegate provides value +} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/LocalPrezelButtonContent.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/LocalPrezelButtonContent.kt new file mode 100644 index 0000000..47364a5 --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/LocalPrezelButtonContent.kt @@ -0,0 +1,99 @@ +package com.team.prezel.core.designsystem.component.actions.button.config + +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.Composable +import androidx.compose.runtime.ProvidableCompositionLocal +import androidx.compose.runtime.staticCompositionLocalOf +import androidx.compose.ui.graphics.Color +import com.team.prezel.core.designsystem.theme.PrezelColorScheme +import com.team.prezel.core.designsystem.theme.PrezelTheme + +val LocalPrezelButtonContent = PrezelButtonContentCompositionLocal() + +interface PrezelButtonContentLoader { + @Composable + fun getContentColor( + type: ButtonType, + hierarchy: ButtonHierarchy, + enabled: Boolean, + ): Color + + @Composable + fun getBackgroundColor( + type: ButtonType, + hierarchy: ButtonHierarchy, + enabled: Boolean, + ): Color + + @Composable + fun getShape( + isRounded: Boolean, + isIconOnly: Boolean, + size: ButtonSize, + ): RoundedCornerShape +} + +class PrezelButtonContentLoaderImpl : PrezelButtonContentLoader { + @Composable + override fun getContentColor( + type: ButtonType, + hierarchy: ButtonHierarchy, + enabled: Boolean, + ): Color { + if (!enabled) return PrezelTheme.colors.textDisabled + if (hierarchy == ButtonHierarchy.SECONDARY) return PrezelTheme.colors.textMedium + + return when (type) { + ButtonType.FILLED -> PrezelColorScheme.Dark.textLarge + ButtonType.OUTLINED -> PrezelTheme.colors.interactiveRegular + ButtonType.GHOST -> PrezelTheme.colors.interactiveRegular + } + } + + @Composable + override fun getBackgroundColor( + type: ButtonType, + hierarchy: ButtonHierarchy, + enabled: Boolean, + ): Color = + when (type) { + ButtonType.OUTLINED, + ButtonType.GHOST, + -> Color.Transparent + + ButtonType.FILLED -> { + if (!enabled) { + PrezelTheme.colors.bgLarge + } else if (hierarchy == ButtonHierarchy.SECONDARY) { + PrezelTheme.colors.bgLarge + } else { + PrezelTheme.colors.interactiveRegular + } + } + } + + @Composable + override fun getShape( + isRounded: Boolean, + isIconOnly: Boolean, + size: ButtonSize, + ): RoundedCornerShape { + if (isRounded) return PrezelTheme.shapes.V1000 + + return when (size) { + ButtonSize.REGULAR -> PrezelTheme.shapes.V8 + ButtonSize.SMALL -> if (isIconOnly) PrezelTheme.shapes.V6 else PrezelTheme.shapes.V4 + ButtonSize.XSMALL -> PrezelTheme.shapes.V4 + } + } +} + +@JvmInline +value class PrezelButtonContentCompositionLocal internal constructor( + private val delegate: ProvidableCompositionLocal = staticCompositionLocalOf { PrezelButtonContentLoaderImpl() }, +) { + val current: PrezelButtonContentLoader + @Composable get() = delegate.current + + infix fun provides(value: PrezelButtonContentLoader) = delegate provides value +} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/LocalPrezelButtonTextStyle.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/LocalPrezelButtonTextStyle.kt new file mode 100644 index 0000000..dc0fc98 --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/LocalPrezelButtonTextStyle.kt @@ -0,0 +1,34 @@ +package com.team.prezel.core.designsystem.component.actions.button.config + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.ProvidableCompositionLocal +import androidx.compose.runtime.staticCompositionLocalOf +import androidx.compose.ui.text.TextStyle +import com.team.prezel.core.designsystem.theme.PrezelTheme + +val LocalPrezelButtonTextStyle = PrezelButtonTextStyleCompositionLocal() + +interface PrezelButtonTextStyleLoader { + @Composable + fun getTextStyle(size: ButtonSize): TextStyle +} + +internal class PrezelButtonTextStyleLoaderImpl : PrezelButtonTextStyleLoader { + @Composable + override fun getTextStyle(size: ButtonSize): TextStyle = + when (size) { + ButtonSize.XSMALL -> PrezelTheme.typography.caption2Medium + ButtonSize.SMALL -> PrezelTheme.typography.body3Medium + ButtonSize.REGULAR -> PrezelTheme.typography.body2Bold + } +} + +@JvmInline +value class PrezelButtonTextStyleCompositionLocal internal constructor( + private val delegate: ProvidableCompositionLocal = staticCompositionLocalOf { PrezelButtonTextStyleLoaderImpl() }, +) { + val current: PrezelButtonTextStyleLoader + @Composable get() = delegate.current + + infix fun provides(value: PrezelButtonTextStyleLoader) = delegate provides value +} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonDefaults.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonDefaults.kt new file mode 100644 index 0000000..5c0da3f --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonDefaults.kt @@ -0,0 +1,79 @@ +package com.team.prezel.core.designsystem.component.actions.button.config + +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.TextStyle + +data class PrezelButtonDefault( + val type: ButtonType, + val size: ButtonSize, + val hierarchy: ButtonHierarchy, + val enabled: Boolean, + val leadingIconTintColor: Color, + val contentColor: Color, + val backgroundColor: Color, + val borderColor: Color, + val shape: RoundedCornerShape, + val textStyle: TextStyle, +) + +object PrezelButtonDefaults { + @Composable + fun getDefault( + isIconOnly: Boolean, + type: ButtonType = ButtonType.FILLED, + size: ButtonSize = ButtonSize.REGULAR, + hierarchy: ButtonHierarchy = ButtonHierarchy.PRIMARY, + enabled: Boolean = true, + isRounded: Boolean = false, + leadingIconTintColor: Color = getContentColor(type = type, hierarchy = hierarchy, enabled = enabled), + contentColor: Color = getContentColor(type = type, hierarchy = hierarchy, enabled = enabled), + backgroundColor: Color = getBackgroundColor(type = type, hierarchy = hierarchy, enabled = enabled), + borderColor: Color = getBorderColor(type = type, hierarchy = hierarchy, enabled = enabled), + shape: RoundedCornerShape = getShape(isRounded = isRounded, isIconOnly = isIconOnly, size = size), + textStyle: TextStyle = getTextStyle(size = size), + ) = PrezelButtonDefault( + type = type, + size = size, + hierarchy = hierarchy, + enabled = enabled, + leadingIconTintColor = leadingIconTintColor, + contentColor = contentColor, + backgroundColor = backgroundColor, + borderColor = borderColor, + shape = shape, + textStyle = textStyle, + ) + + @Composable + private fun getContentColor( + type: ButtonType, + hierarchy: ButtonHierarchy, + enabled: Boolean, + ): Color = LocalPrezelButtonContent.current.getContentColor(type = type, hierarchy = hierarchy, enabled = enabled) + + @Composable + private fun getBackgroundColor( + type: ButtonType, + hierarchy: ButtonHierarchy, + enabled: Boolean, + ): Color = LocalPrezelButtonContent.current.getBackgroundColor(type = type, hierarchy = hierarchy, enabled = enabled) + + @Composable + private fun getShape( + isRounded: Boolean, + isIconOnly: Boolean, + size: ButtonSize, + ): RoundedCornerShape = LocalPrezelButtonContent.current.getShape(isRounded = isRounded, isIconOnly = isIconOnly, size = size) + + @Composable + private fun getBorderColor( + type: ButtonType, + hierarchy: ButtonHierarchy, + enabled: Boolean, + ): Color = LocalPrezelButtonBorder.current.getBorderColor(type = type, hierarchy = hierarchy, enabled = enabled) + + @Composable + private fun getTextStyle(size: ButtonSize): TextStyle = LocalPrezelButtonTextStyle.current.getTextStyle(size = size) +} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonUtils.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonUtils.kt new file mode 100644 index 0000000..01be3e1 --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonUtils.kt @@ -0,0 +1,80 @@ +package com.team.prezel.core.designsystem.component.actions.button.config + +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Immutable +import androidx.compose.ui.Modifier +import com.team.prezel.core.designsystem.theme.PrezelTheme + +/** + * 버튼의 시각적 타입을 정의합니다. + * + * 버튼의 배경, 테두리, 강조 방식에 따라 스타일을 구분할 때 사용합니다. + */ +@Immutable +enum class ButtonType { + /** 배경이 채워진 버튼입니다. */ + FILLED, + + /** 테두리가 있는 버튼입니다. */ + OUTLINED, + + /** 배경과 테두리가 없는 버튼입니다. */ + GHOST, +} + +/** + * 버튼의 크기를 정의합니다. + * + * 버튼의 높이, 패딩, 아이콘 크기, 텍스트 스타일 등의 기준으로 사용합니다. + */ +@Immutable +enum class ButtonSize { + /** 가장 작은 크기의 버튼입니다. */ + XSMALL, + + /** 작은 크기의 버튼입니다. */ + SMALL, + + /** 기본 크기의 버튼입니다. */ + REGULAR, +} + +/** + * 버튼의 계층 구조를 정의합니다. + * + * 액션의 중요도와 강조 수준에 따라 버튼의 우선순위를 표현할 때 사용합니다. + */ +@Immutable +enum class ButtonHierarchy { + /** 가장 중요한 주요 액션에 사용되는 계층입니다. */ + PRIMARY, + + /** 보조 액션에 사용되는 계층입니다. */ + SECONDARY, +} + +@Composable +internal fun Modifier.buttonContentPadding(size: ButtonSize): Modifier = + this.padding( + horizontal = when (size) { + ButtonSize.XSMALL -> PrezelTheme.spacing.V10 + ButtonSize.SMALL -> PrezelTheme.spacing.V12 + ButtonSize.REGULAR -> PrezelTheme.spacing.V16 + }, + vertical = when (size) { + ButtonSize.XSMALL -> PrezelTheme.spacing.V6 + ButtonSize.SMALL -> PrezelTheme.spacing.V8 + ButtonSize.REGULAR -> PrezelTheme.spacing.V12 + }, + ) + +@Composable +internal fun Modifier.iconButtonContentPadding(size: ButtonSize): Modifier = + this.padding( + all = when (size) { + ButtonSize.XSMALL -> PrezelTheme.spacing.V8 + ButtonSize.SMALL -> PrezelTheme.spacing.V10 + ButtonSize.REGULAR -> PrezelTheme.spacing.V14 + }, + ) From f6651629a04b7caa92b5e56b03d9526ef6936e56 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Sun, 22 Mar 2026 02:50:30 +0900 Subject: [PATCH 04/42] =?UTF-8?q?feat:=20PrezelTextButton=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../actions/button/PrezelTextButton.kt | 289 ++++++++++++++++++ 1 file changed, 289 insertions(+) create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelTextButton.kt diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelTextButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelTextButton.kt new file mode 100644 index 0000000..8c27fd1 --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelTextButton.kt @@ -0,0 +1,289 @@ +package com.team.prezel.core.designsystem.component.actions.button + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.IntrinsicSize +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.defaultMinSize +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +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.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.team.prezel.core.designsystem.component.actions.button.config.ButtonHierarchy +import com.team.prezel.core.designsystem.component.actions.button.config.ButtonSize +import com.team.prezel.core.designsystem.component.actions.button.config.ButtonType +import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefault +import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefaults +import com.team.prezel.core.designsystem.component.actions.button.config.buttonContentPadding +import com.team.prezel.core.designsystem.component.base.PrezelTouchArea +import com.team.prezel.core.designsystem.preview.PreviewScaffold +import com.team.prezel.core.designsystem.preview.SectionTitle +import com.team.prezel.core.designsystem.theme.PrezelTheme +import com.team.prezel.core.designsystem.util.drawDashBorder + +@Composable +fun PrezelTextButton( + text: String, + modifier: Modifier = Modifier, + type: ButtonType = ButtonType.FILLED, + size: ButtonSize = ButtonSize.REGULAR, + hierarchy: ButtonHierarchy = ButtonHierarchy.PRIMARY, + enabled: Boolean = true, + isRounded: Boolean = false, + onClick: () -> Unit, + buttonDefault: PrezelButtonDefault = PrezelButtonDefaults.getDefault( + isIconOnly = false, + isRounded = isRounded, + type = type, + size = size, + hierarchy = hierarchy, + enabled = enabled, + ), +) { + PrezelTouchArea( + modifier = modifier, + onClick = onClick, + enabled = enabled, + shape = buttonDefault.shape, + isUseRipple = true, + content = { PrezelTextButtonContent(text = text, buttonDefault = buttonDefault) }, + ) +} + +@Composable +private fun PrezelTextButtonContent( + text: String, + modifier: Modifier = Modifier, + buttonDefault: PrezelButtonDefault, +) { + val textColor by remember(buttonDefault.enabled, buttonDefault.contentColor) { + mutableStateOf(buttonDefault.contentColor) + } + + val backgroundColor by remember(buttonDefault.enabled, buttonDefault.backgroundColor) { + mutableStateOf(buttonDefault.backgroundColor) + } + + PrezelButtonLayout( + modifier = modifier + .clip(shape = buttonDefault.shape) + .background(color = backgroundColor) + .then( + if (buttonDefault.type == ButtonType.OUTLINED) { + Modifier.border( + width = PrezelTheme.stroke.V1, + color = buttonDefault.borderColor, + shape = buttonDefault.shape, + ) + } else { + Modifier + }, + ).buttonContentPadding(size = buttonDefault.size), + horizontalArrangement = Arrangement.Center, + text = { + Text( + text = text, + style = buttonDefault.textStyle, + color = textColor, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + textAlign = TextAlign.Center, + ) + }, + ) +} + +@Preview(device = "spec:width=1080dp,height=1350dp") +@Composable +private fun PrezelTextButtons() { + PrezelTheme { + PreviewScaffold { + SectionTitle(title = "Button/Text") + Text( + text = "행은 Size, 열은 Type과 Hierarchy 조합입니다. 각 섹션은 Enabled와 Rounded 상태를 구분합니다.", + style = PrezelTheme.typography.body3Regular, + color = PrezelTheme.colors.textMedium, + modifier = Modifier + .fillMaxWidth() + .background(Color.LightGray.copy(alpha = 0.4f)) + .padding(8.dp), + ) + PrezelTextButtonTable( + title = "Enabled / Default", + enabled = true, + isRounded = false, + ) + PrezelTextButtonTable( + title = "Enabled / Rounded", + enabled = true, + isRounded = true, + ) + PrezelTextButtonTable( + title = "Disabled / Default", + enabled = false, + isRounded = false, + ) + PrezelTextButtonTable( + title = "Disabled / Rounded", + enabled = false, + isRounded = true, + ) + } + } +} + +@Composable +private fun PrezelTextButtonTable( + title: String, + enabled: Boolean, + isRounded: Boolean, +) { + Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { + Text( + text = title, + style = PrezelTheme.typography.body3Bold, + color = PrezelTheme.colors.textLarge, + ) + + Column( + modifier = Modifier.fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(0.dp), + ) { + PrezelTextButtonTableHeader() + + ButtonSize.entries.forEach { size -> + PrezelTextButtonTableRow( + size = size, + enabled = enabled, + isRounded = isRounded, + ) + } + } + } +} + +@Composable +private fun PrezelTextButtonTableHeader() { + Row( + modifier = Modifier.height(IntrinsicSize.Min), + horizontalArrangement = Arrangement.spacedBy(0.dp), + ) { + PreviewHeaderCell( + text = "Size", + modifier = Modifier.defaultMinSize(minWidth = 88.dp), + ) + + ButtonType.entries.forEach { type -> + ButtonHierarchy.entries.forEach { hierarchy -> + PreviewHeaderCell( + text = "${type.name}\n${hierarchy.name}", + modifier = Modifier.defaultMinSize(minWidth = 156.dp), + ) + } + } + } +} + +@Composable +private fun PrezelTextButtonTableRow( + size: ButtonSize, + enabled: Boolean, + isRounded: Boolean, +) { + Row( + modifier = Modifier.height(IntrinsicSize.Min), + horizontalArrangement = Arrangement.spacedBy(0.dp), + ) { + PreviewButtonCell(modifier = Modifier.defaultMinSize(minWidth = 88.dp)) { + Text( + text = size.name.lowercase(), + style = PrezelTheme.typography.body3Medium, + color = PrezelTheme.colors.textLarge, + ) + } + + ButtonType.entries.forEach { type -> + ButtonHierarchy.entries.forEach { hierarchy -> + PreviewButtonCell(modifier = Modifier.defaultMinSize(minWidth = 156.dp)) { + PrezelTextButton( + text = "Label", + type = type, + size = size, + hierarchy = hierarchy, + enabled = enabled, + isRounded = isRounded, + onClick = {}, + modifier = if (type == ButtonType.GHOST) { + Modifier.drawDashBorder( + shape = PrezelButtonDefaults + .getDefault( + isIconOnly = false, + isRounded = isRounded, + type = type, + size = size, + hierarchy = hierarchy, + ).shape, + ) + } else { + Modifier + }, + ) + } + } + } + } +} + +@Composable +private fun PreviewHeaderCell( + text: String, + modifier: Modifier = Modifier, +) { + Box( + modifier = modifier + .fillMaxHeight() + .border(width = PrezelTheme.stroke.V1, color = PrezelTheme.colors.borderRegular) + .background(PrezelTheme.colors.bgMedium) + .padding(horizontal = 12.dp, vertical = 10.dp), + contentAlignment = Alignment.Center, + ) { + Text( + text = text, + style = PrezelTheme.typography.body3Medium, + color = PrezelTheme.colors.textMedium, + textAlign = TextAlign.Center, + ) + } +} + +@Composable +private fun PreviewButtonCell( + modifier: Modifier = Modifier, + content: @Composable () -> Unit, +) { + Box( + modifier = modifier + .fillMaxHeight() + .border(width = PrezelTheme.stroke.V1, color = PrezelTheme.colors.borderRegular) + .padding(horizontal = 12.dp, vertical = 16.dp), + contentAlignment = Alignment.Center, + ) { + content() + } +} From 7ec5655a17e67eaa75183dccfa5bb0bf21a6bfb9 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Sun, 22 Mar 2026 19:08:41 +0900 Subject: [PATCH 05/42] =?UTF-8?q?feat:=20PrezelIconButton=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../actions/button/PrezelButtonIcon.kt | 2 +- .../actions/button/PrezelIconButton.kt | 290 ++++++++++++++++++ .../button/config/PrezelButtonDefaults.kt | 3 - 3 files changed, 291 insertions(+), 4 deletions(-) create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelIconButton.kt diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonIcon.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonIcon.kt index 0bf8cb2..be2c859 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonIcon.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonIcon.kt @@ -11,9 +11,9 @@ import androidx.compose.ui.res.painterResource @Composable internal fun PrezelButtonIcon( - modifier: Modifier, @DrawableRes drawableRes: Int, tint: Color, + modifier: Modifier = Modifier, ) { Image( modifier = modifier, diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelIconButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelIconButton.kt new file mode 100644 index 0000000..0a5cd08 --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelIconButton.kt @@ -0,0 +1,290 @@ +package com.team.prezel.core.designsystem.component.actions.button + +import androidx.annotation.DrawableRes +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.IntrinsicSize +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.defaultMinSize +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +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.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.team.prezel.core.designsystem.component.actions.button.config.ButtonHierarchy +import com.team.prezel.core.designsystem.component.actions.button.config.ButtonSize +import com.team.prezel.core.designsystem.component.actions.button.config.ButtonType +import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefault +import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefaults +import com.team.prezel.core.designsystem.component.actions.button.config.iconButtonContentPadding +import com.team.prezel.core.designsystem.component.base.PrezelTouchArea +import com.team.prezel.core.designsystem.icon.PrezelIcons +import com.team.prezel.core.designsystem.preview.PreviewScaffold +import com.team.prezel.core.designsystem.preview.SectionTitle +import com.team.prezel.core.designsystem.theme.PrezelTheme +import com.team.prezel.core.designsystem.util.drawDashBorder + +@Composable +fun PrezelIconButton( + @DrawableRes iconResId: Int, + modifier: Modifier = Modifier, + type: ButtonType = ButtonType.FILLED, + size: ButtonSize = ButtonSize.REGULAR, + hierarchy: ButtonHierarchy = ButtonHierarchy.PRIMARY, + enabled: Boolean = true, + isRounded: Boolean = false, + onClick: () -> Unit, + buttonDefault: PrezelButtonDefault = PrezelButtonDefaults.getDefault( + isIconOnly = true, + isRounded = isRounded, + type = type, + size = size, + hierarchy = hierarchy, + enabled = enabled, + ), +) { + PrezelTouchArea( + modifier = modifier, + onClick = onClick, + enabled = enabled, + shape = buttonDefault.shape, + isUseRipple = true, + content = { + PrezelIconButtonContent(iconResId = iconResId, buttonDefault = buttonDefault) + }, + ) +} + +@Composable +private fun PrezelIconButtonContent( + @DrawableRes iconResId: Int, + modifier: Modifier = Modifier, + buttonDefault: PrezelButtonDefault, +) { + val contentColor by remember(buttonDefault.enabled, buttonDefault.contentColor) { + mutableStateOf(buttonDefault.contentColor) + } + + val backgroundColor by remember(buttonDefault.enabled, buttonDefault.backgroundColor) { + mutableStateOf(buttonDefault.backgroundColor) + } + + PrezelButtonLayout( + modifier = modifier + .clip(shape = buttonDefault.shape) + .background(color = backgroundColor) + .then( + if (buttonDefault.type == ButtonType.OUTLINED) { + Modifier.border( + width = PrezelTheme.stroke.V1, + color = buttonDefault.borderColor, + shape = buttonDefault.shape, + ) + } else { + Modifier + }, + ) + .iconButtonContentPadding(size = buttonDefault.size), + horizontalArrangement = Arrangement.Center, + leadingIcon = { + PrezelButtonIcon( + drawableRes = iconResId, + tint = contentColor, + ) + }, + ) + +} + +@Preview(device = "spec:width=1080dp,height=1500dp") +@Composable +private fun PrezelIconButtons() { + PrezelTheme { + PreviewScaffold { + SectionTitle(title = "Button/Icon") + Text( + text = "행은 Size, 열은 Type과 Hierarchy 조합입니다. 각 섹션은 Enabled와 Rounded 상태를 구분합니다.", + style = PrezelTheme.typography.body3Regular, + color = PrezelTheme.colors.textMedium, + modifier = Modifier + .fillMaxWidth() + .background(Color.LightGray.copy(alpha = 0.4f)) + .padding(8.dp), + ) + PrezelIconButtonTable( + title = "Enabled / Default", + enabled = true, + isRounded = false, + ) + PrezelIconButtonTable( + title = "Enabled / Rounded", + enabled = true, + isRounded = true, + ) + PrezelIconButtonTable( + title = "Disabled / Default", + enabled = false, + isRounded = false, + ) + PrezelIconButtonTable( + title = "Disabled / Rounded", + enabled = false, + isRounded = true, + ) + } + } +} + +@Composable +private fun PrezelIconButtonTable( + title: String, + enabled: Boolean, + isRounded: Boolean, +) { + Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { + Text( + text = title, + style = PrezelTheme.typography.body3Bold, + color = PrezelTheme.colors.textLarge, + ) + + Column( + modifier = Modifier.fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(0.dp), + ) { + PrezelIconButtonTableHeader() + + ButtonSize.entries.forEach { size -> + PrezelIconButtonTableRow( + size = size, + enabled = enabled, + isRounded = isRounded, + ) + } + } + } +} + +@Composable +private fun PrezelIconButtonTableHeader() { + Row( + modifier = Modifier.height(IntrinsicSize.Min), + horizontalArrangement = Arrangement.spacedBy(0.dp), + ) { + PreviewHeaderCell( + text = "Size", + modifier = Modifier.defaultMinSize(minWidth = 88.dp), + ) + + ButtonType.entries.forEach { type -> + ButtonHierarchy.entries.forEach { hierarchy -> + PreviewHeaderCell( + text = "${type.name}\n${hierarchy.name}", + modifier = Modifier.defaultMinSize(minWidth = 156.dp), + ) + } + } + } +} + +@Composable +private fun PrezelIconButtonTableRow( + size: ButtonSize, + enabled: Boolean, + isRounded: Boolean, +) { + Row( + modifier = Modifier.height(IntrinsicSize.Min), + horizontalArrangement = Arrangement.spacedBy(0.dp), + ) { + PreviewButtonCell(modifier = Modifier.defaultMinSize(minWidth = 88.dp)) { + Text( + text = size.name.lowercase(), + style = PrezelTheme.typography.body3Medium, + color = PrezelTheme.colors.textLarge, + ) + } + + ButtonType.entries.forEach { type -> + ButtonHierarchy.entries.forEach { hierarchy -> + PreviewButtonCell(modifier = Modifier.defaultMinSize(minWidth = 156.dp)) { + PrezelIconButton( + iconResId = PrezelIcons.Blank, + type = type, + size = size, + hierarchy = hierarchy, + enabled = enabled, + isRounded = isRounded, + onClick = {}, + modifier = if (type == ButtonType.GHOST) { + Modifier.drawDashBorder( + shape = PrezelButtonDefaults + .getDefault( + isIconOnly = true, + isRounded = isRounded, + type = type, + size = size, + hierarchy = hierarchy, + ).shape, + ) + } else { + Modifier + }, + ) + } + } + } + } +} + +@Composable +private fun PreviewHeaderCell( + text: String, + modifier: Modifier = Modifier, +) { + Box( + modifier = modifier + .fillMaxHeight() + .border(width = PrezelTheme.stroke.V1, color = PrezelTheme.colors.borderRegular) + .background(PrezelTheme.colors.bgMedium) + .padding(horizontal = 12.dp, vertical = 10.dp), + contentAlignment = Alignment.Center, + ) { + Text( + text = text, + style = PrezelTheme.typography.body3Medium, + color = PrezelTheme.colors.textMedium, + textAlign = TextAlign.Center, + ) + } +} + +@Composable +private fun PreviewButtonCell( + modifier: Modifier = Modifier, + content: @Composable () -> Unit, +) { + Box( + modifier = modifier + .fillMaxHeight() + .border(width = PrezelTheme.stroke.V1, color = PrezelTheme.colors.borderRegular) + .padding(horizontal = 12.dp, vertical = 16.dp), + contentAlignment = Alignment.Center, + ) { + content() + } +} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonDefaults.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonDefaults.kt index 5c0da3f..9b09bd6 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonDefaults.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonDefaults.kt @@ -10,7 +10,6 @@ data class PrezelButtonDefault( val size: ButtonSize, val hierarchy: ButtonHierarchy, val enabled: Boolean, - val leadingIconTintColor: Color, val contentColor: Color, val backgroundColor: Color, val borderColor: Color, @@ -27,7 +26,6 @@ object PrezelButtonDefaults { hierarchy: ButtonHierarchy = ButtonHierarchy.PRIMARY, enabled: Boolean = true, isRounded: Boolean = false, - leadingIconTintColor: Color = getContentColor(type = type, hierarchy = hierarchy, enabled = enabled), contentColor: Color = getContentColor(type = type, hierarchy = hierarchy, enabled = enabled), backgroundColor: Color = getBackgroundColor(type = type, hierarchy = hierarchy, enabled = enabled), borderColor: Color = getBorderColor(type = type, hierarchy = hierarchy, enabled = enabled), @@ -38,7 +36,6 @@ object PrezelButtonDefaults { size = size, hierarchy = hierarchy, enabled = enabled, - leadingIconTintColor = leadingIconTintColor, contentColor = contentColor, backgroundColor = backgroundColor, borderColor = borderColor, From 11f9e287a6204ab6f883312ef19a5f9d26975141 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Sun, 22 Mar 2026 19:08:48 +0900 Subject: [PATCH 06/42] =?UTF-8?q?feat:=20PrezelIconButton=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../designsystem/component/actions/button/PrezelIconButton.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelIconButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelIconButton.kt index 0a5cd08..24796d3 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelIconButton.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelIconButton.kt @@ -97,8 +97,7 @@ private fun PrezelIconButtonContent( } else { Modifier }, - ) - .iconButtonContentPadding(size = buttonDefault.size), + ).iconButtonContentPadding(size = buttonDefault.size), horizontalArrangement = Arrangement.Center, leadingIcon = { PrezelButtonIcon( @@ -107,7 +106,6 @@ private fun PrezelIconButtonContent( ) }, ) - } @Preview(device = "spec:width=1080dp,height=1500dp") From 7c4d38a9c422ee2eb8cb74d2c114a96c3c815d52 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Sun, 22 Mar 2026 19:32:41 +0900 Subject: [PATCH 07/42] =?UTF-8?q?feat:=20PrezelButton=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84=20=EB=B0=8F=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../component/actions/button/PrezelButton.kt | 307 ++++++++++++++++++ .../actions/button/PrezelButtonIcon.kt | 12 +- 2 files changed, 318 insertions(+), 1 deletion(-) create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButton.kt diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButton.kt new file mode 100644 index 0000000..9fc8695 --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButton.kt @@ -0,0 +1,307 @@ +package com.team.prezel.core.designsystem.component.actions.button + +import androidx.annotation.DrawableRes +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.IntrinsicSize +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.defaultMinSize +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +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.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.team.prezel.core.designsystem.component.actions.button.config.ButtonHierarchy +import com.team.prezel.core.designsystem.component.actions.button.config.ButtonSize +import com.team.prezel.core.designsystem.component.actions.button.config.ButtonType +import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefault +import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefaults +import com.team.prezel.core.designsystem.component.actions.button.config.buttonContentPadding +import com.team.prezel.core.designsystem.component.base.PrezelTouchArea +import com.team.prezel.core.designsystem.icon.PrezelIcons +import com.team.prezel.core.designsystem.preview.PreviewScaffold +import com.team.prezel.core.designsystem.preview.SectionTitle +import com.team.prezel.core.designsystem.theme.PrezelTheme +import com.team.prezel.core.designsystem.util.drawDashBorder + +@Composable +fun PrezelButton( + text: String, + @DrawableRes iconResId: Int, + modifier: Modifier = Modifier, + type: ButtonType = ButtonType.FILLED, + size: ButtonSize = ButtonSize.REGULAR, + hierarchy: ButtonHierarchy = ButtonHierarchy.PRIMARY, + enabled: Boolean = true, + isRounded: Boolean = false, + onClick: () -> Unit, + buttonDefault: PrezelButtonDefault = PrezelButtonDefaults.getDefault( + isIconOnly = false, + isRounded = isRounded, + type = type, + size = size, + hierarchy = hierarchy, + enabled = enabled, + ), +) { + PrezelTouchArea( + modifier = modifier, + onClick = onClick, + enabled = enabled, + shape = buttonDefault.shape, + isUseRipple = true, + content = { PrezelButtonContent(text = text, iconResId = iconResId, buttonDefault = buttonDefault) }, + ) +} + +@Composable +private fun PrezelButtonContent( + text: String, + @DrawableRes iconResId: Int, + modifier: Modifier = Modifier, + buttonDefault: PrezelButtonDefault, +) { + val contentColor by remember(buttonDefault.enabled, buttonDefault.contentColor) { + mutableStateOf(buttonDefault.contentColor) + } + + val backgroundColor by remember(buttonDefault.enabled, buttonDefault.backgroundColor) { + mutableStateOf(buttonDefault.backgroundColor) + } + + PrezelButtonLayout( + modifier = modifier + .clip(shape = buttonDefault.shape) + .background(color = backgroundColor) + .then( + if (buttonDefault.type == ButtonType.OUTLINED) { + Modifier.border( + width = PrezelTheme.stroke.V1, + color = buttonDefault.borderColor, + shape = buttonDefault.shape, + ) + } else { + Modifier + }, + ).buttonContentPadding(size = buttonDefault.size), + horizontalArrangement = Arrangement.spacedBy( + when (buttonDefault.size) { + ButtonSize.XSMALL -> PrezelTheme.spacing.V4 + ButtonSize.SMALL -> PrezelTheme.spacing.V4 + ButtonSize.REGULAR -> PrezelTheme.spacing.V8 + }, + ), + text = { + Text( + text = text, + style = buttonDefault.textStyle, + color = contentColor, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + textAlign = TextAlign.Center, + ) + }, + leadingIcon = { + PrezelButtonIcon( + drawableRes = iconResId, + tint = contentColor, + size = buttonDefault.size, + ) + }, + ) +} + +@Preview(device = "spec:width=1080dp,height=1400dp") +@Composable +private fun PrezelButtons() { + PrezelTheme { + PreviewScaffold { + SectionTitle(title = "Button/Icon + Text") + Text( + text = "행은 Size, 열은 Type과 Hierarchy 조합입니다. 각 섹션은 Enabled와 Rounded 상태를 구분합니다.", + style = PrezelTheme.typography.body3Regular, + color = PrezelTheme.colors.textMedium, + modifier = Modifier + .fillMaxWidth() + .background(Color.LightGray.copy(alpha = 0.4f)) + .padding(8.dp), + ) + PrezelButtonTable( + title = "Enabled / Default", + enabled = true, + isRounded = false, + ) + PrezelButtonTable( + title = "Enabled / Rounded", + enabled = true, + isRounded = true, + ) + PrezelButtonTable( + title = "Disabled / Default", + enabled = false, + isRounded = false, + ) + PrezelButtonTable( + title = "Disabled / Rounded", + enabled = false, + isRounded = true, + ) + } + } +} + +@Composable +private fun PrezelButtonTable( + title: String, + enabled: Boolean, + isRounded: Boolean, +) { + Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { + Text( + text = title, + style = PrezelTheme.typography.body3Bold, + color = PrezelTheme.colors.textLarge, + ) + + Column( + modifier = Modifier.fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(0.dp), + ) { + PrezelButtonTableHeader() + + ButtonSize.entries.forEach { size -> + PrezelButtonTableRow( + size = size, + enabled = enabled, + isRounded = isRounded, + ) + } + } + } +} + +@Composable +private fun PrezelButtonTableHeader() { + Row( + modifier = Modifier.height(IntrinsicSize.Min), + horizontalArrangement = Arrangement.spacedBy(0.dp), + ) { + PreviewHeaderCell( + text = "Size", + modifier = Modifier.defaultMinSize(minWidth = 88.dp), + ) + + ButtonType.entries.forEach { type -> + ButtonHierarchy.entries.forEach { hierarchy -> + PreviewHeaderCell( + text = "${type.name}\n${hierarchy.name}", + modifier = Modifier.defaultMinSize(minWidth = 156.dp), + ) + } + } + } +} + +@Composable +private fun PrezelButtonTableRow( + size: ButtonSize, + enabled: Boolean, + isRounded: Boolean, +) { + Row( + modifier = Modifier.height(IntrinsicSize.Min), + horizontalArrangement = Arrangement.spacedBy(0.dp), + ) { + PreviewButtonCell(modifier = Modifier.defaultMinSize(minWidth = 88.dp)) { + Text( + text = size.name.lowercase(), + style = PrezelTheme.typography.body3Medium, + color = PrezelTheme.colors.textLarge, + ) + } + + ButtonType.entries.forEach { type -> + ButtonHierarchy.entries.forEach { hierarchy -> + PreviewButtonCell(modifier = Modifier.defaultMinSize(minWidth = 156.dp)) { + PrezelButton( + text = "Label", + iconResId = PrezelIcons.Blank, + type = type, + size = size, + hierarchy = hierarchy, + enabled = enabled, + isRounded = isRounded, + onClick = {}, + modifier = if (type == ButtonType.GHOST) { + Modifier.drawDashBorder( + shape = PrezelButtonDefaults + .getDefault( + isIconOnly = false, + isRounded = isRounded, + type = type, + size = size, + hierarchy = hierarchy, + ).shape, + ) + } else { + Modifier + }, + ) + } + } + } + } +} + +@Composable +private fun PreviewHeaderCell( + text: String, + modifier: Modifier = Modifier, +) { + Box( + modifier = modifier + .fillMaxHeight() + .border(width = PrezelTheme.stroke.V1, color = PrezelTheme.colors.borderRegular) + .background(PrezelTheme.colors.bgMedium) + .padding(horizontal = 12.dp, vertical = 10.dp), + contentAlignment = Alignment.Center, + ) { + Text( + text = text, + style = PrezelTheme.typography.body3Medium, + color = PrezelTheme.colors.textMedium, + textAlign = TextAlign.Center, + ) + } +} + +@Composable +private fun PreviewButtonCell( + modifier: Modifier = Modifier, + content: @Composable () -> Unit, +) { + Box( + modifier = modifier + .fillMaxHeight() + .border(width = PrezelTheme.stroke.V1, color = PrezelTheme.colors.borderRegular) + .padding(horizontal = 12.dp, vertical = 16.dp), + contentAlignment = Alignment.Center, + ) { + content() + } +} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonIcon.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonIcon.kt index be2c859..35607a6 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonIcon.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonIcon.kt @@ -2,21 +2,31 @@ package com.team.prezel.core.designsystem.component.actions.button import androidx.annotation.DrawableRes import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.size import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp +import com.team.prezel.core.designsystem.component.actions.button.config.ButtonSize @Composable internal fun PrezelButtonIcon( @DrawableRes drawableRes: Int, tint: Color, + size: ButtonSize, modifier: Modifier = Modifier, ) { Image( - modifier = modifier, + modifier = modifier.size( + when (size) { + ButtonSize.XSMALL -> 14.dp + ButtonSize.SMALL -> 16.dp + ButtonSize.REGULAR -> 20.dp + }, + ), painter = painterResource(id = drawableRes), contentScale = ContentScale.FillHeight, colorFilter = ColorFilter.tint(color = tint), From 2d7b2b021c20a0fd6ff958ed2cddc1598ad16032 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Mon, 23 Mar 2026 02:21:54 +0900 Subject: [PATCH 08/42] =?UTF-8?q?refactor:=20PrezelButton=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B5=AC=EC=A1=B0=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0=20=EB=B0=8F=20=EB=82=B4=EB=B6=80=20=EB=A1=9C=EC=A7=81?= =?UTF-8?q?=20=EC=B5=9C=EC=A0=81=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../component/actions/button/PrezelButton.kt | 290 +---------------- .../actions/button/PrezelButtonBase.kt | 149 +++++++++ .../actions/button/PrezelButtonIcon.kt | 35 --- .../actions/button/PrezelButtonLayout.kt | 37 --- .../actions/button/PrezelButtonPreview.kt | 294 ++++++++++++++++++ .../actions/button/PrezelIconButton.kt | 273 +--------------- .../actions/button/PrezelTextButton.kt | 275 +--------------- .../button/config/LocalPrezelButtonBorder.kt | 45 --- .../button/config/LocalPrezelButtonContent.kt | 99 ------ .../config/LocalPrezelButtonTextStyle.kt | 34 -- .../button/config/PrezelButtonDefaults.kt | 134 +++++++- ...elButtonUtils.kt => PrezelButtonModels.kt} | 29 -- 12 files changed, 600 insertions(+), 1094 deletions(-) create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonBase.kt delete mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonIcon.kt delete mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonLayout.kt create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonPreview.kt delete mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/LocalPrezelButtonBorder.kt delete mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/LocalPrezelButtonContent.kt delete mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/LocalPrezelButtonTextStyle.kt rename Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/{PrezelButtonUtils.kt => PrezelButtonModels.kt} (54%) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButton.kt index 9fc8695..0abd3c4 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButton.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButton.kt @@ -1,43 +1,13 @@ package com.team.prezel.core.designsystem.component.actions.button import androidx.annotation.DrawableRes -import androidx.compose.foundation.background -import androidx.compose.foundation.border -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.IntrinsicSize -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.defaultMinSize -import androidx.compose.foundation.layout.fillMaxHeight -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -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.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.component.actions.button.config.ButtonHierarchy import com.team.prezel.core.designsystem.component.actions.button.config.ButtonSize import com.team.prezel.core.designsystem.component.actions.button.config.ButtonType import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefault import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefaults -import com.team.prezel.core.designsystem.component.actions.button.config.buttonContentPadding -import com.team.prezel.core.designsystem.component.base.PrezelTouchArea -import com.team.prezel.core.designsystem.icon.PrezelIcons -import com.team.prezel.core.designsystem.preview.PreviewScaffold -import com.team.prezel.core.designsystem.preview.SectionTitle -import com.team.prezel.core.designsystem.theme.PrezelTheme -import com.team.prezel.core.designsystem.util.drawDashBorder @Composable fun PrezelButton( @@ -49,259 +19,21 @@ fun PrezelButton( hierarchy: ButtonHierarchy = ButtonHierarchy.PRIMARY, enabled: Boolean = true, isRounded: Boolean = false, + buttonDefault: PrezelButtonDefault? = null, onClick: () -> Unit, - buttonDefault: PrezelButtonDefault = PrezelButtonDefaults.getDefault( - isIconOnly = false, - isRounded = isRounded, - type = type, - size = size, - hierarchy = hierarchy, - enabled = enabled, - ), ) { - PrezelTouchArea( + PrezelButtonBase( + text = text, + iconResId = iconResId, modifier = modifier, onClick = onClick, - enabled = enabled, - shape = buttonDefault.shape, - isUseRipple = true, - content = { PrezelButtonContent(text = text, iconResId = iconResId, buttonDefault = buttonDefault) }, - ) -} - -@Composable -private fun PrezelButtonContent( - text: String, - @DrawableRes iconResId: Int, - modifier: Modifier = Modifier, - buttonDefault: PrezelButtonDefault, -) { - val contentColor by remember(buttonDefault.enabled, buttonDefault.contentColor) { - mutableStateOf(buttonDefault.contentColor) - } - - val backgroundColor by remember(buttonDefault.enabled, buttonDefault.backgroundColor) { - mutableStateOf(buttonDefault.backgroundColor) - } - - PrezelButtonLayout( - modifier = modifier - .clip(shape = buttonDefault.shape) - .background(color = backgroundColor) - .then( - if (buttonDefault.type == ButtonType.OUTLINED) { - Modifier.border( - width = PrezelTheme.stroke.V1, - color = buttonDefault.borderColor, - shape = buttonDefault.shape, - ) - } else { - Modifier - }, - ).buttonContentPadding(size = buttonDefault.size), - horizontalArrangement = Arrangement.spacedBy( - when (buttonDefault.size) { - ButtonSize.XSMALL -> PrezelTheme.spacing.V4 - ButtonSize.SMALL -> PrezelTheme.spacing.V4 - ButtonSize.REGULAR -> PrezelTheme.spacing.V8 - }, + buttonDefault = buttonDefault ?: PrezelButtonDefaults.getDefault( + isIconOnly = false, + isRounded = isRounded, + type = type, + size = size, + hierarchy = hierarchy, + enabled = enabled, ), - text = { - Text( - text = text, - style = buttonDefault.textStyle, - color = contentColor, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - textAlign = TextAlign.Center, - ) - }, - leadingIcon = { - PrezelButtonIcon( - drawableRes = iconResId, - tint = contentColor, - size = buttonDefault.size, - ) - }, ) } - -@Preview(device = "spec:width=1080dp,height=1400dp") -@Composable -private fun PrezelButtons() { - PrezelTheme { - PreviewScaffold { - SectionTitle(title = "Button/Icon + Text") - Text( - text = "행은 Size, 열은 Type과 Hierarchy 조합입니다. 각 섹션은 Enabled와 Rounded 상태를 구분합니다.", - style = PrezelTheme.typography.body3Regular, - color = PrezelTheme.colors.textMedium, - modifier = Modifier - .fillMaxWidth() - .background(Color.LightGray.copy(alpha = 0.4f)) - .padding(8.dp), - ) - PrezelButtonTable( - title = "Enabled / Default", - enabled = true, - isRounded = false, - ) - PrezelButtonTable( - title = "Enabled / Rounded", - enabled = true, - isRounded = true, - ) - PrezelButtonTable( - title = "Disabled / Default", - enabled = false, - isRounded = false, - ) - PrezelButtonTable( - title = "Disabled / Rounded", - enabled = false, - isRounded = true, - ) - } - } -} - -@Composable -private fun PrezelButtonTable( - title: String, - enabled: Boolean, - isRounded: Boolean, -) { - Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { - Text( - text = title, - style = PrezelTheme.typography.body3Bold, - color = PrezelTheme.colors.textLarge, - ) - - Column( - modifier = Modifier.fillMaxWidth(), - verticalArrangement = Arrangement.spacedBy(0.dp), - ) { - PrezelButtonTableHeader() - - ButtonSize.entries.forEach { size -> - PrezelButtonTableRow( - size = size, - enabled = enabled, - isRounded = isRounded, - ) - } - } - } -} - -@Composable -private fun PrezelButtonTableHeader() { - Row( - modifier = Modifier.height(IntrinsicSize.Min), - horizontalArrangement = Arrangement.spacedBy(0.dp), - ) { - PreviewHeaderCell( - text = "Size", - modifier = Modifier.defaultMinSize(minWidth = 88.dp), - ) - - ButtonType.entries.forEach { type -> - ButtonHierarchy.entries.forEach { hierarchy -> - PreviewHeaderCell( - text = "${type.name}\n${hierarchy.name}", - modifier = Modifier.defaultMinSize(minWidth = 156.dp), - ) - } - } - } -} - -@Composable -private fun PrezelButtonTableRow( - size: ButtonSize, - enabled: Boolean, - isRounded: Boolean, -) { - Row( - modifier = Modifier.height(IntrinsicSize.Min), - horizontalArrangement = Arrangement.spacedBy(0.dp), - ) { - PreviewButtonCell(modifier = Modifier.defaultMinSize(minWidth = 88.dp)) { - Text( - text = size.name.lowercase(), - style = PrezelTheme.typography.body3Medium, - color = PrezelTheme.colors.textLarge, - ) - } - - ButtonType.entries.forEach { type -> - ButtonHierarchy.entries.forEach { hierarchy -> - PreviewButtonCell(modifier = Modifier.defaultMinSize(minWidth = 156.dp)) { - PrezelButton( - text = "Label", - iconResId = PrezelIcons.Blank, - type = type, - size = size, - hierarchy = hierarchy, - enabled = enabled, - isRounded = isRounded, - onClick = {}, - modifier = if (type == ButtonType.GHOST) { - Modifier.drawDashBorder( - shape = PrezelButtonDefaults - .getDefault( - isIconOnly = false, - isRounded = isRounded, - type = type, - size = size, - hierarchy = hierarchy, - ).shape, - ) - } else { - Modifier - }, - ) - } - } - } - } -} - -@Composable -private fun PreviewHeaderCell( - text: String, - modifier: Modifier = Modifier, -) { - Box( - modifier = modifier - .fillMaxHeight() - .border(width = PrezelTheme.stroke.V1, color = PrezelTheme.colors.borderRegular) - .background(PrezelTheme.colors.bgMedium) - .padding(horizontal = 12.dp, vertical = 10.dp), - contentAlignment = Alignment.Center, - ) { - Text( - text = text, - style = PrezelTheme.typography.body3Medium, - color = PrezelTheme.colors.textMedium, - textAlign = TextAlign.Center, - ) - } -} - -@Composable -private fun PreviewButtonCell( - modifier: Modifier = Modifier, - content: @Composable () -> Unit, -) { - Box( - modifier = modifier - .fillMaxHeight() - .border(width = PrezelTheme.stroke.V1, color = PrezelTheme.colors.borderRegular) - .padding(horizontal = 12.dp, vertical = 16.dp), - contentAlignment = Alignment.Center, - ) { - content() - } -} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonBase.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonBase.kt new file mode 100644 index 0000000..a8d37eb --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonBase.kt @@ -0,0 +1,149 @@ +package com.team.prezel.core.designsystem.component.actions.button + +import androidx.annotation.DrawableRes +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.material3.Text +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.ColorFilter +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow +import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefault +import com.team.prezel.core.designsystem.component.base.PrezelTouchArea + +@Composable +internal fun PrezelButtonBase( + onClick: () -> Unit, + buttonDefault: PrezelButtonDefault, + modifier: Modifier = Modifier, + text: String? = null, + @DrawableRes iconResId: Int? = null, +) { + PrezelTouchArea( + modifier = modifier, + onClick = onClick, + enabled = buttonDefault.enabled, + shape = buttonDefault.shape, + isUseRipple = true, + ) { + ButtonContentLayout( + modifier = Modifier.buttonContent(buttonDefault), + horizontalArrangement = buttonDefault.contentArrangement( + hasText = text != null, + hasIcon = iconResId != null, + ), + text = text?.let { buttonText -> + { + ButtonLabel( + text = buttonText, + buttonDefault = buttonDefault, + ) + } + }, + leadingIcon = iconResId?.let { drawableRes -> + { + ButtonLeadingIcon( + drawableRes = drawableRes, + buttonDefault = buttonDefault, + ) + } + }, + ) + } +} + +@Composable +private fun ButtonContentLayout( + modifier: Modifier, + horizontalArrangement: Arrangement.Horizontal, + text: @Composable (() -> Unit)? = null, + leadingIcon: @Composable (() -> Unit)? = null, +) { + Box( + modifier = modifier, + contentAlignment = Alignment.Center, + ) { + Row( + horizontalArrangement = horizontalArrangement, + verticalAlignment = Alignment.CenterVertically, + ) { + leadingIcon?.invoke() + + text?.let { + Box( + modifier = Modifier.wrapContentHeight(), + contentAlignment = Alignment.Center, + ) { + text() + } + } + } + } +} + +@Composable +private fun ButtonLabel( + text: String, + buttonDefault: PrezelButtonDefault, +) { + Text( + text = text, + style = buttonDefault.textStyle, + color = buttonDefault.contentColor, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + textAlign = TextAlign.Center, + ) +} + +@Composable +private fun ButtonLeadingIcon( + @DrawableRes drawableRes: Int, + buttonDefault: PrezelButtonDefault, +) { + Image( + modifier = Modifier.size(buttonDefault.iconSize), + painter = painterResource(id = drawableRes), + contentScale = ContentScale.FillHeight, + colorFilter = ColorFilter.tint(color = buttonDefault.contentColor), + contentDescription = null, + ) +} + +private fun PrezelButtonDefault.contentArrangement( + hasText: Boolean, + hasIcon: Boolean, +): Arrangement.Horizontal = if (hasText && hasIcon) Arrangement.spacedBy(iconSpacing) else Arrangement.Center + +private fun Modifier.buttonContent(buttonDefault: PrezelButtonDefault): Modifier = + this + .buttonContainer(buttonDefault) + .padding(buttonDefault.contentPadding) + +private fun Modifier.buttonContainer(buttonDefault: PrezelButtonDefault): Modifier = + this + .clip(shape = buttonDefault.shape) + .background(color = buttonDefault.backgroundColor) + .then( + if (buttonDefault.hasBorder) { + Modifier.border( + width = buttonDefault.borderWidth, + color = buttonDefault.borderColor, + shape = buttonDefault.shape, + ) + } else { + Modifier + }, + ) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonIcon.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonIcon.kt deleted file mode 100644 index 35607a6..0000000 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonIcon.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.team.prezel.core.designsystem.component.actions.button - -import androidx.annotation.DrawableRes -import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.size -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.ColorFilter -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.unit.dp -import com.team.prezel.core.designsystem.component.actions.button.config.ButtonSize - -@Composable -internal fun PrezelButtonIcon( - @DrawableRes drawableRes: Int, - tint: Color, - size: ButtonSize, - modifier: Modifier = Modifier, -) { - Image( - modifier = modifier.size( - when (size) { - ButtonSize.XSMALL -> 14.dp - ButtonSize.SMALL -> 16.dp - ButtonSize.REGULAR -> 20.dp - }, - ), - painter = painterResource(id = drawableRes), - contentScale = ContentScale.FillHeight, - colorFilter = ColorFilter.tint(color = tint), - contentDescription = null, - ) -} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonLayout.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonLayout.kt deleted file mode 100644 index 7886a1a..0000000 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonLayout.kt +++ /dev/null @@ -1,37 +0,0 @@ -package com.team.prezel.core.designsystem.component.actions.button - -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.wrapContentHeight -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier - -@Composable -internal fun PrezelButtonLayout( - modifier: Modifier, - horizontalArrangement: Arrangement.Horizontal, - text: @Composable (() -> Unit)? = null, - leadingIcon: @Composable (() -> Unit)? = null, -) { - Box( - modifier = modifier, - contentAlignment = Alignment.Center, - ) { - Row( - horizontalArrangement = horizontalArrangement, - verticalAlignment = Alignment.CenterVertically, - ) { - leadingIcon?.let { leadingIcon() } - - text?.let { - Box( - modifier = Modifier.wrapContentHeight(), - contentAlignment = Alignment.Center, - content = { text() }, - ) - } - } - } -} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonPreview.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonPreview.kt new file mode 100644 index 0000000..b02a417 --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonPreview.kt @@ -0,0 +1,294 @@ +package com.team.prezel.core.designsystem.component.actions.button + +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.IntrinsicSize +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.defaultMinSize +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.team.prezel.core.designsystem.component.actions.button.config.ButtonHierarchy +import com.team.prezel.core.designsystem.component.actions.button.config.ButtonSize +import com.team.prezel.core.designsystem.component.actions.button.config.ButtonType +import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefaults +import com.team.prezel.core.designsystem.icon.PrezelIcons +import com.team.prezel.core.designsystem.preview.PreviewScaffold +import com.team.prezel.core.designsystem.preview.SectionTitle +import com.team.prezel.core.designsystem.theme.PrezelTheme +import com.team.prezel.core.designsystem.util.drawDashBorder + +private data class PreviewSection( + val title: String, + val enabled: Boolean, + val isRounded: Boolean, +) + +private val previewSections = + listOf( + PreviewSection(title = "Enabled / Default", enabled = true, isRounded = false), + PreviewSection(title = "Enabled / Rounded", enabled = true, isRounded = true), + PreviewSection(title = "Disabled / Default", enabled = false, isRounded = false), + PreviewSection(title = "Disabled / Rounded", enabled = false, isRounded = true), + ) + +@Preview(device = "spec:width=1080dp,height=1400dp") +@Composable +private fun PrezelButtonsPreview() { + PrezelButtonPreviewScreen(title = "Button/Icon + Text") { type, hierarchy, size, enabled, isRounded -> + PrezelButton( + text = "Label", + iconResId = PrezelIcons.Blank, + type = type, + size = size, + hierarchy = hierarchy, + enabled = enabled, + isRounded = isRounded, + onClick = {}, + modifier = Modifier.previewGhostBorderModifier( + type = type, + hierarchy = hierarchy, + size = size, + enabled = enabled, + isRounded = isRounded, + isIconOnly = false, + ), + ) + } +} + +@Preview(device = "spec:width=1080dp,height=1350dp") +@Composable +private fun PrezelTextButtonsPreview() { + PrezelButtonPreviewScreen(title = "Button/Text") { type, hierarchy, size, enabled, isRounded -> + PrezelTextButton( + text = "Label", + type = type, + size = size, + hierarchy = hierarchy, + enabled = enabled, + isRounded = isRounded, + onClick = {}, + modifier = Modifier.previewGhostBorderModifier( + type = type, + hierarchy = hierarchy, + size = size, + enabled = enabled, + isRounded = isRounded, + isIconOnly = false, + ), + ) + } +} + +@Preview(device = "spec:width=1080dp,height=1500dp") +@Composable +private fun PrezelIconButtonsPreview() { + PrezelButtonPreviewScreen(title = "Button/Icon") { type, hierarchy, size, enabled, isRounded -> + PrezelIconButton( + iconResId = PrezelIcons.Blank, + type = type, + size = size, + hierarchy = hierarchy, + enabled = enabled, + isRounded = isRounded, + onClick = {}, + modifier = Modifier.previewGhostBorderModifier( + type = type, + hierarchy = hierarchy, + size = size, + enabled = enabled, + isRounded = isRounded, + isIconOnly = true, + ), + ) + } +} + +@Composable +private fun PrezelButtonPreviewScreen( + title: String, + content: @Composable (ButtonType, ButtonHierarchy, ButtonSize, Boolean, Boolean) -> Unit, +) { + PrezelTheme { + PreviewScaffold { + SectionTitle(title = title) + Text( + text = "행은 Size, 열은 Type과 Hierarchy 조합입니다. 각 섹션은 Enabled와 Rounded 상태를 구분합니다.", + style = PrezelTheme.typography.body3Regular, + color = PrezelTheme.colors.textMedium, + modifier = Modifier + .fillMaxWidth() + .background(Color.LightGray.copy(alpha = 0.4f)) + .padding(8.dp), + ) + + previewSections.forEach { section -> + PrezelButtonPreviewTable( + title = section.title, + enabled = section.enabled, + isRounded = section.isRounded, + content = content, + ) + } + } + } +} + +@Composable +private fun PrezelButtonPreviewTable( + title: String, + enabled: Boolean, + isRounded: Boolean, + content: @Composable (ButtonType, ButtonHierarchy, ButtonSize, Boolean, Boolean) -> Unit, +) { + Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { + Text( + text = title, + style = PrezelTheme.typography.body3Bold, + color = PrezelTheme.colors.textLarge, + ) + + Column( + modifier = Modifier.fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(0.dp), + ) { + PrezelButtonTableHeader() + + ButtonSize.entries.forEach { size -> + PrezelButtonTableRow( + size = size, + enabled = enabled, + isRounded = isRounded, + content = content, + ) + } + } + } +} + +@Composable +private fun PrezelButtonTableHeader() { + Row( + modifier = Modifier.height(IntrinsicSize.Min), + horizontalArrangement = Arrangement.spacedBy(0.dp), + ) { + PreviewHeaderCell( + text = "Size", + modifier = Modifier.defaultMinSize(minWidth = 88.dp), + ) + + ButtonType.entries.forEach { type -> + ButtonHierarchy.entries.forEach { hierarchy -> + PreviewHeaderCell( + text = "${type.name}\n${hierarchy.name}", + modifier = Modifier.defaultMinSize(minWidth = 156.dp), + ) + } + } + } +} + +@Composable +private fun PrezelButtonTableRow( + size: ButtonSize, + enabled: Boolean, + isRounded: Boolean, + content: @Composable (ButtonType, ButtonHierarchy, ButtonSize, Boolean, Boolean) -> Unit, +) { + Row( + modifier = Modifier.height(IntrinsicSize.Min), + horizontalArrangement = Arrangement.spacedBy(0.dp), + ) { + PreviewButtonCell(modifier = Modifier.defaultMinSize(minWidth = 88.dp)) { + Text( + text = size.name.lowercase(), + style = PrezelTheme.typography.body3Medium, + color = PrezelTheme.colors.textLarge, + ) + } + + ButtonType.entries.forEach { type -> + ButtonHierarchy.entries.forEach { hierarchy -> + PreviewButtonCell(modifier = Modifier.defaultMinSize(minWidth = 156.dp)) { + content(type, hierarchy, size, enabled, isRounded) + } + } + } + } +} + +@Composable +private fun PreviewHeaderCell( + text: String, + modifier: Modifier = Modifier, +) { + Box( + modifier = modifier + .fillMaxHeight() + .border(width = PrezelTheme.stroke.V1, color = PrezelTheme.colors.borderRegular) + .background(PrezelTheme.colors.bgMedium) + .padding(horizontal = 12.dp, vertical = 10.dp), + contentAlignment = Alignment.Center, + ) { + Text( + text = text, + style = PrezelTheme.typography.body3Medium, + color = PrezelTheme.colors.textMedium, + textAlign = TextAlign.Center, + ) + } +} + +@Composable +private fun PreviewButtonCell( + modifier: Modifier = Modifier, + content: @Composable () -> Unit, +) { + Box( + modifier = modifier + .fillMaxHeight() + .border(width = PrezelTheme.stroke.V1, color = PrezelTheme.colors.borderRegular) + .padding(horizontal = 12.dp, vertical = 16.dp), + contentAlignment = Alignment.Center, + ) { + content() + } +} + +@Composable +private fun Modifier.previewGhostBorderModifier( + type: ButtonType, + hierarchy: ButtonHierarchy, + size: ButtonSize, + enabled: Boolean, + isRounded: Boolean, + isIconOnly: Boolean, +): Modifier = + if (type == ButtonType.GHOST) { + this.drawDashBorder( + shape = PrezelButtonDefaults + .getDefault( + isIconOnly = isIconOnly, + isRounded = isRounded, + type = type, + size = size, + hierarchy = hierarchy, + enabled = enabled, + ).shape, + ) + } else { + Modifier + } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelIconButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelIconButton.kt index 24796d3..b7cbdc8 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelIconButton.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelIconButton.kt @@ -1,42 +1,13 @@ package com.team.prezel.core.designsystem.component.actions.button import androidx.annotation.DrawableRes -import androidx.compose.foundation.background -import androidx.compose.foundation.border -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.IntrinsicSize -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.defaultMinSize -import androidx.compose.foundation.layout.fillMaxHeight -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -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.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.component.actions.button.config.ButtonHierarchy import com.team.prezel.core.designsystem.component.actions.button.config.ButtonSize import com.team.prezel.core.designsystem.component.actions.button.config.ButtonType import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefault import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefaults -import com.team.prezel.core.designsystem.component.actions.button.config.iconButtonContentPadding -import com.team.prezel.core.designsystem.component.base.PrezelTouchArea -import com.team.prezel.core.designsystem.icon.PrezelIcons -import com.team.prezel.core.designsystem.preview.PreviewScaffold -import com.team.prezel.core.designsystem.preview.SectionTitle -import com.team.prezel.core.designsystem.theme.PrezelTheme -import com.team.prezel.core.designsystem.util.drawDashBorder @Composable fun PrezelIconButton( @@ -47,242 +18,20 @@ fun PrezelIconButton( hierarchy: ButtonHierarchy = ButtonHierarchy.PRIMARY, enabled: Boolean = true, isRounded: Boolean = false, + buttonDefault: PrezelButtonDefault? = null, onClick: () -> Unit, - buttonDefault: PrezelButtonDefault = PrezelButtonDefaults.getDefault( - isIconOnly = true, - isRounded = isRounded, - type = type, - size = size, - hierarchy = hierarchy, - enabled = enabled, - ), ) { - PrezelTouchArea( + PrezelButtonBase( + iconResId = iconResId, modifier = modifier, onClick = onClick, - enabled = enabled, - shape = buttonDefault.shape, - isUseRipple = true, - content = { - PrezelIconButtonContent(iconResId = iconResId, buttonDefault = buttonDefault) - }, + buttonDefault = buttonDefault ?: PrezelButtonDefaults.getDefault( + isIconOnly = true, + isRounded = isRounded, + type = type, + size = size, + hierarchy = hierarchy, + enabled = enabled, + ), ) } - -@Composable -private fun PrezelIconButtonContent( - @DrawableRes iconResId: Int, - modifier: Modifier = Modifier, - buttonDefault: PrezelButtonDefault, -) { - val contentColor by remember(buttonDefault.enabled, buttonDefault.contentColor) { - mutableStateOf(buttonDefault.contentColor) - } - - val backgroundColor by remember(buttonDefault.enabled, buttonDefault.backgroundColor) { - mutableStateOf(buttonDefault.backgroundColor) - } - - PrezelButtonLayout( - modifier = modifier - .clip(shape = buttonDefault.shape) - .background(color = backgroundColor) - .then( - if (buttonDefault.type == ButtonType.OUTLINED) { - Modifier.border( - width = PrezelTheme.stroke.V1, - color = buttonDefault.borderColor, - shape = buttonDefault.shape, - ) - } else { - Modifier - }, - ).iconButtonContentPadding(size = buttonDefault.size), - horizontalArrangement = Arrangement.Center, - leadingIcon = { - PrezelButtonIcon( - drawableRes = iconResId, - tint = contentColor, - ) - }, - ) -} - -@Preview(device = "spec:width=1080dp,height=1500dp") -@Composable -private fun PrezelIconButtons() { - PrezelTheme { - PreviewScaffold { - SectionTitle(title = "Button/Icon") - Text( - text = "행은 Size, 열은 Type과 Hierarchy 조합입니다. 각 섹션은 Enabled와 Rounded 상태를 구분합니다.", - style = PrezelTheme.typography.body3Regular, - color = PrezelTheme.colors.textMedium, - modifier = Modifier - .fillMaxWidth() - .background(Color.LightGray.copy(alpha = 0.4f)) - .padding(8.dp), - ) - PrezelIconButtonTable( - title = "Enabled / Default", - enabled = true, - isRounded = false, - ) - PrezelIconButtonTable( - title = "Enabled / Rounded", - enabled = true, - isRounded = true, - ) - PrezelIconButtonTable( - title = "Disabled / Default", - enabled = false, - isRounded = false, - ) - PrezelIconButtonTable( - title = "Disabled / Rounded", - enabled = false, - isRounded = true, - ) - } - } -} - -@Composable -private fun PrezelIconButtonTable( - title: String, - enabled: Boolean, - isRounded: Boolean, -) { - Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { - Text( - text = title, - style = PrezelTheme.typography.body3Bold, - color = PrezelTheme.colors.textLarge, - ) - - Column( - modifier = Modifier.fillMaxWidth(), - verticalArrangement = Arrangement.spacedBy(0.dp), - ) { - PrezelIconButtonTableHeader() - - ButtonSize.entries.forEach { size -> - PrezelIconButtonTableRow( - size = size, - enabled = enabled, - isRounded = isRounded, - ) - } - } - } -} - -@Composable -private fun PrezelIconButtonTableHeader() { - Row( - modifier = Modifier.height(IntrinsicSize.Min), - horizontalArrangement = Arrangement.spacedBy(0.dp), - ) { - PreviewHeaderCell( - text = "Size", - modifier = Modifier.defaultMinSize(minWidth = 88.dp), - ) - - ButtonType.entries.forEach { type -> - ButtonHierarchy.entries.forEach { hierarchy -> - PreviewHeaderCell( - text = "${type.name}\n${hierarchy.name}", - modifier = Modifier.defaultMinSize(minWidth = 156.dp), - ) - } - } - } -} - -@Composable -private fun PrezelIconButtonTableRow( - size: ButtonSize, - enabled: Boolean, - isRounded: Boolean, -) { - Row( - modifier = Modifier.height(IntrinsicSize.Min), - horizontalArrangement = Arrangement.spacedBy(0.dp), - ) { - PreviewButtonCell(modifier = Modifier.defaultMinSize(minWidth = 88.dp)) { - Text( - text = size.name.lowercase(), - style = PrezelTheme.typography.body3Medium, - color = PrezelTheme.colors.textLarge, - ) - } - - ButtonType.entries.forEach { type -> - ButtonHierarchy.entries.forEach { hierarchy -> - PreviewButtonCell(modifier = Modifier.defaultMinSize(minWidth = 156.dp)) { - PrezelIconButton( - iconResId = PrezelIcons.Blank, - type = type, - size = size, - hierarchy = hierarchy, - enabled = enabled, - isRounded = isRounded, - onClick = {}, - modifier = if (type == ButtonType.GHOST) { - Modifier.drawDashBorder( - shape = PrezelButtonDefaults - .getDefault( - isIconOnly = true, - isRounded = isRounded, - type = type, - size = size, - hierarchy = hierarchy, - ).shape, - ) - } else { - Modifier - }, - ) - } - } - } - } -} - -@Composable -private fun PreviewHeaderCell( - text: String, - modifier: Modifier = Modifier, -) { - Box( - modifier = modifier - .fillMaxHeight() - .border(width = PrezelTheme.stroke.V1, color = PrezelTheme.colors.borderRegular) - .background(PrezelTheme.colors.bgMedium) - .padding(horizontal = 12.dp, vertical = 10.dp), - contentAlignment = Alignment.Center, - ) { - Text( - text = text, - style = PrezelTheme.typography.body3Medium, - color = PrezelTheme.colors.textMedium, - textAlign = TextAlign.Center, - ) - } -} - -@Composable -private fun PreviewButtonCell( - modifier: Modifier = Modifier, - content: @Composable () -> Unit, -) { - Box( - modifier = modifier - .fillMaxHeight() - .border(width = PrezelTheme.stroke.V1, color = PrezelTheme.colors.borderRegular) - .padding(horizontal = 12.dp, vertical = 16.dp), - contentAlignment = Alignment.Center, - ) { - content() - } -} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelTextButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelTextButton.kt index 8c27fd1..5408c4f 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelTextButton.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelTextButton.kt @@ -1,41 +1,12 @@ package com.team.prezel.core.designsystem.component.actions.button -import androidx.compose.foundation.background -import androidx.compose.foundation.border -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.IntrinsicSize -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.defaultMinSize -import androidx.compose.foundation.layout.fillMaxHeight -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -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.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.component.actions.button.config.ButtonHierarchy import com.team.prezel.core.designsystem.component.actions.button.config.ButtonSize import com.team.prezel.core.designsystem.component.actions.button.config.ButtonType import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefault import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefaults -import com.team.prezel.core.designsystem.component.actions.button.config.buttonContentPadding -import com.team.prezel.core.designsystem.component.base.PrezelTouchArea -import com.team.prezel.core.designsystem.preview.PreviewScaffold -import com.team.prezel.core.designsystem.preview.SectionTitle -import com.team.prezel.core.designsystem.theme.PrezelTheme -import com.team.prezel.core.designsystem.util.drawDashBorder @Composable fun PrezelTextButton( @@ -46,244 +17,20 @@ fun PrezelTextButton( hierarchy: ButtonHierarchy = ButtonHierarchy.PRIMARY, enabled: Boolean = true, isRounded: Boolean = false, + buttonDefault: PrezelButtonDefault? = null, onClick: () -> Unit, - buttonDefault: PrezelButtonDefault = PrezelButtonDefaults.getDefault( - isIconOnly = false, - isRounded = isRounded, - type = type, - size = size, - hierarchy = hierarchy, - enabled = enabled, - ), ) { - PrezelTouchArea( + PrezelButtonBase( + text = text, modifier = modifier, onClick = onClick, - enabled = enabled, - shape = buttonDefault.shape, - isUseRipple = true, - content = { PrezelTextButtonContent(text = text, buttonDefault = buttonDefault) }, + buttonDefault = buttonDefault ?: PrezelButtonDefaults.getDefault( + isIconOnly = false, + isRounded = isRounded, + type = type, + size = size, + hierarchy = hierarchy, + enabled = enabled, + ), ) } - -@Composable -private fun PrezelTextButtonContent( - text: String, - modifier: Modifier = Modifier, - buttonDefault: PrezelButtonDefault, -) { - val textColor by remember(buttonDefault.enabled, buttonDefault.contentColor) { - mutableStateOf(buttonDefault.contentColor) - } - - val backgroundColor by remember(buttonDefault.enabled, buttonDefault.backgroundColor) { - mutableStateOf(buttonDefault.backgroundColor) - } - - PrezelButtonLayout( - modifier = modifier - .clip(shape = buttonDefault.shape) - .background(color = backgroundColor) - .then( - if (buttonDefault.type == ButtonType.OUTLINED) { - Modifier.border( - width = PrezelTheme.stroke.V1, - color = buttonDefault.borderColor, - shape = buttonDefault.shape, - ) - } else { - Modifier - }, - ).buttonContentPadding(size = buttonDefault.size), - horizontalArrangement = Arrangement.Center, - text = { - Text( - text = text, - style = buttonDefault.textStyle, - color = textColor, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - textAlign = TextAlign.Center, - ) - }, - ) -} - -@Preview(device = "spec:width=1080dp,height=1350dp") -@Composable -private fun PrezelTextButtons() { - PrezelTheme { - PreviewScaffold { - SectionTitle(title = "Button/Text") - Text( - text = "행은 Size, 열은 Type과 Hierarchy 조합입니다. 각 섹션은 Enabled와 Rounded 상태를 구분합니다.", - style = PrezelTheme.typography.body3Regular, - color = PrezelTheme.colors.textMedium, - modifier = Modifier - .fillMaxWidth() - .background(Color.LightGray.copy(alpha = 0.4f)) - .padding(8.dp), - ) - PrezelTextButtonTable( - title = "Enabled / Default", - enabled = true, - isRounded = false, - ) - PrezelTextButtonTable( - title = "Enabled / Rounded", - enabled = true, - isRounded = true, - ) - PrezelTextButtonTable( - title = "Disabled / Default", - enabled = false, - isRounded = false, - ) - PrezelTextButtonTable( - title = "Disabled / Rounded", - enabled = false, - isRounded = true, - ) - } - } -} - -@Composable -private fun PrezelTextButtonTable( - title: String, - enabled: Boolean, - isRounded: Boolean, -) { - Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { - Text( - text = title, - style = PrezelTheme.typography.body3Bold, - color = PrezelTheme.colors.textLarge, - ) - - Column( - modifier = Modifier.fillMaxWidth(), - verticalArrangement = Arrangement.spacedBy(0.dp), - ) { - PrezelTextButtonTableHeader() - - ButtonSize.entries.forEach { size -> - PrezelTextButtonTableRow( - size = size, - enabled = enabled, - isRounded = isRounded, - ) - } - } - } -} - -@Composable -private fun PrezelTextButtonTableHeader() { - Row( - modifier = Modifier.height(IntrinsicSize.Min), - horizontalArrangement = Arrangement.spacedBy(0.dp), - ) { - PreviewHeaderCell( - text = "Size", - modifier = Modifier.defaultMinSize(minWidth = 88.dp), - ) - - ButtonType.entries.forEach { type -> - ButtonHierarchy.entries.forEach { hierarchy -> - PreviewHeaderCell( - text = "${type.name}\n${hierarchy.name}", - modifier = Modifier.defaultMinSize(minWidth = 156.dp), - ) - } - } - } -} - -@Composable -private fun PrezelTextButtonTableRow( - size: ButtonSize, - enabled: Boolean, - isRounded: Boolean, -) { - Row( - modifier = Modifier.height(IntrinsicSize.Min), - horizontalArrangement = Arrangement.spacedBy(0.dp), - ) { - PreviewButtonCell(modifier = Modifier.defaultMinSize(minWidth = 88.dp)) { - Text( - text = size.name.lowercase(), - style = PrezelTheme.typography.body3Medium, - color = PrezelTheme.colors.textLarge, - ) - } - - ButtonType.entries.forEach { type -> - ButtonHierarchy.entries.forEach { hierarchy -> - PreviewButtonCell(modifier = Modifier.defaultMinSize(minWidth = 156.dp)) { - PrezelTextButton( - text = "Label", - type = type, - size = size, - hierarchy = hierarchy, - enabled = enabled, - isRounded = isRounded, - onClick = {}, - modifier = if (type == ButtonType.GHOST) { - Modifier.drawDashBorder( - shape = PrezelButtonDefaults - .getDefault( - isIconOnly = false, - isRounded = isRounded, - type = type, - size = size, - hierarchy = hierarchy, - ).shape, - ) - } else { - Modifier - }, - ) - } - } - } - } -} - -@Composable -private fun PreviewHeaderCell( - text: String, - modifier: Modifier = Modifier, -) { - Box( - modifier = modifier - .fillMaxHeight() - .border(width = PrezelTheme.stroke.V1, color = PrezelTheme.colors.borderRegular) - .background(PrezelTheme.colors.bgMedium) - .padding(horizontal = 12.dp, vertical = 10.dp), - contentAlignment = Alignment.Center, - ) { - Text( - text = text, - style = PrezelTheme.typography.body3Medium, - color = PrezelTheme.colors.textMedium, - textAlign = TextAlign.Center, - ) - } -} - -@Composable -private fun PreviewButtonCell( - modifier: Modifier = Modifier, - content: @Composable () -> Unit, -) { - Box( - modifier = modifier - .fillMaxHeight() - .border(width = PrezelTheme.stroke.V1, color = PrezelTheme.colors.borderRegular) - .padding(horizontal = 12.dp, vertical = 16.dp), - contentAlignment = Alignment.Center, - ) { - content() - } -} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/LocalPrezelButtonBorder.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/LocalPrezelButtonBorder.kt deleted file mode 100644 index d526ed7..0000000 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/LocalPrezelButtonBorder.kt +++ /dev/null @@ -1,45 +0,0 @@ -package com.team.prezel.core.designsystem.component.actions.button.config - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.ProvidableCompositionLocal -import androidx.compose.runtime.staticCompositionLocalOf -import androidx.compose.ui.graphics.Color -import com.team.prezel.core.designsystem.theme.PrezelTheme - -val LocalPrezelButtonBorder = PrezelButtonBorderCompositionLocal() - -interface PrezelButtonBorderLoader { - @Composable - fun getBorderColor( - type: ButtonType, - hierarchy: ButtonHierarchy, - enabled: Boolean, - ): Color -} - -internal class PrezelButtonBorderLoaderImpl : PrezelButtonBorderLoader { - @Composable - override fun getBorderColor( - type: ButtonType, - hierarchy: ButtonHierarchy, - enabled: Boolean, - ): Color { - if (type != ButtonType.OUTLINED) return Color.Transparent - if (!enabled) return PrezelTheme.colors.borderDisabled - - return when (hierarchy) { - ButtonHierarchy.PRIMARY -> PrezelTheme.colors.interactiveRegular - ButtonHierarchy.SECONDARY -> PrezelTheme.colors.borderMedium - } - } -} - -@JvmInline -value class PrezelButtonBorderCompositionLocal internal constructor( - private val delegate: ProvidableCompositionLocal = staticCompositionLocalOf { PrezelButtonBorderLoaderImpl() }, -) { - val current: PrezelButtonBorderLoader - @Composable get() = delegate.current - - infix fun provides(value: PrezelButtonBorderLoader) = delegate provides value -} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/LocalPrezelButtonContent.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/LocalPrezelButtonContent.kt deleted file mode 100644 index 47364a5..0000000 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/LocalPrezelButtonContent.kt +++ /dev/null @@ -1,99 +0,0 @@ -package com.team.prezel.core.designsystem.component.actions.button.config - -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.runtime.Composable -import androidx.compose.runtime.ProvidableCompositionLocal -import androidx.compose.runtime.staticCompositionLocalOf -import androidx.compose.ui.graphics.Color -import com.team.prezel.core.designsystem.theme.PrezelColorScheme -import com.team.prezel.core.designsystem.theme.PrezelTheme - -val LocalPrezelButtonContent = PrezelButtonContentCompositionLocal() - -interface PrezelButtonContentLoader { - @Composable - fun getContentColor( - type: ButtonType, - hierarchy: ButtonHierarchy, - enabled: Boolean, - ): Color - - @Composable - fun getBackgroundColor( - type: ButtonType, - hierarchy: ButtonHierarchy, - enabled: Boolean, - ): Color - - @Composable - fun getShape( - isRounded: Boolean, - isIconOnly: Boolean, - size: ButtonSize, - ): RoundedCornerShape -} - -class PrezelButtonContentLoaderImpl : PrezelButtonContentLoader { - @Composable - override fun getContentColor( - type: ButtonType, - hierarchy: ButtonHierarchy, - enabled: Boolean, - ): Color { - if (!enabled) return PrezelTheme.colors.textDisabled - if (hierarchy == ButtonHierarchy.SECONDARY) return PrezelTheme.colors.textMedium - - return when (type) { - ButtonType.FILLED -> PrezelColorScheme.Dark.textLarge - ButtonType.OUTLINED -> PrezelTheme.colors.interactiveRegular - ButtonType.GHOST -> PrezelTheme.colors.interactiveRegular - } - } - - @Composable - override fun getBackgroundColor( - type: ButtonType, - hierarchy: ButtonHierarchy, - enabled: Boolean, - ): Color = - when (type) { - ButtonType.OUTLINED, - ButtonType.GHOST, - -> Color.Transparent - - ButtonType.FILLED -> { - if (!enabled) { - PrezelTheme.colors.bgLarge - } else if (hierarchy == ButtonHierarchy.SECONDARY) { - PrezelTheme.colors.bgLarge - } else { - PrezelTheme.colors.interactiveRegular - } - } - } - - @Composable - override fun getShape( - isRounded: Boolean, - isIconOnly: Boolean, - size: ButtonSize, - ): RoundedCornerShape { - if (isRounded) return PrezelTheme.shapes.V1000 - - return when (size) { - ButtonSize.REGULAR -> PrezelTheme.shapes.V8 - ButtonSize.SMALL -> if (isIconOnly) PrezelTheme.shapes.V6 else PrezelTheme.shapes.V4 - ButtonSize.XSMALL -> PrezelTheme.shapes.V4 - } - } -} - -@JvmInline -value class PrezelButtonContentCompositionLocal internal constructor( - private val delegate: ProvidableCompositionLocal = staticCompositionLocalOf { PrezelButtonContentLoaderImpl() }, -) { - val current: PrezelButtonContentLoader - @Composable get() = delegate.current - - infix fun provides(value: PrezelButtonContentLoader) = delegate provides value -} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/LocalPrezelButtonTextStyle.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/LocalPrezelButtonTextStyle.kt deleted file mode 100644 index dc0fc98..0000000 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/LocalPrezelButtonTextStyle.kt +++ /dev/null @@ -1,34 +0,0 @@ -package com.team.prezel.core.designsystem.component.actions.button.config - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.ProvidableCompositionLocal -import androidx.compose.runtime.staticCompositionLocalOf -import androidx.compose.ui.text.TextStyle -import com.team.prezel.core.designsystem.theme.PrezelTheme - -val LocalPrezelButtonTextStyle = PrezelButtonTextStyleCompositionLocal() - -interface PrezelButtonTextStyleLoader { - @Composable - fun getTextStyle(size: ButtonSize): TextStyle -} - -internal class PrezelButtonTextStyleLoaderImpl : PrezelButtonTextStyleLoader { - @Composable - override fun getTextStyle(size: ButtonSize): TextStyle = - when (size) { - ButtonSize.XSMALL -> PrezelTheme.typography.caption2Medium - ButtonSize.SMALL -> PrezelTheme.typography.body3Medium - ButtonSize.REGULAR -> PrezelTheme.typography.body2Bold - } -} - -@JvmInline -value class PrezelButtonTextStyleCompositionLocal internal constructor( - private val delegate: ProvidableCompositionLocal = staticCompositionLocalOf { PrezelButtonTextStyleLoaderImpl() }, -) { - val current: PrezelButtonTextStyleLoader - @Composable get() = delegate.current - - infix fun provides(value: PrezelButtonTextStyleLoader) = delegate provides value -} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonDefaults.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonDefaults.kt index 9b09bd6..bab1a03 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonDefaults.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonDefaults.kt @@ -1,10 +1,17 @@ package com.team.prezel.core.designsystem.component.actions.button.config +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable +import androidx.compose.runtime.Immutable import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import com.team.prezel.core.designsystem.theme.PrezelColorScheme +import com.team.prezel.core.designsystem.theme.PrezelTheme +@Immutable data class PrezelButtonDefault( val type: ButtonType, val size: ButtonSize, @@ -13,9 +20,15 @@ data class PrezelButtonDefault( val contentColor: Color, val backgroundColor: Color, val borderColor: Color, + val borderWidth: Dp, val shape: RoundedCornerShape, val textStyle: TextStyle, -) + val contentPadding: PaddingValues, + val iconSpacing: Dp, + val iconSize: Dp, +) { + val hasBorder: Boolean = borderWidth > 0.dp +} object PrezelButtonDefaults { @Composable @@ -29,8 +42,12 @@ object PrezelButtonDefaults { contentColor: Color = getContentColor(type = type, hierarchy = hierarchy, enabled = enabled), backgroundColor: Color = getBackgroundColor(type = type, hierarchy = hierarchy, enabled = enabled), borderColor: Color = getBorderColor(type = type, hierarchy = hierarchy, enabled = enabled), + borderWidth: Dp = getBorderWidth(type = type), shape: RoundedCornerShape = getShape(isRounded = isRounded, isIconOnly = isIconOnly, size = size), textStyle: TextStyle = getTextStyle(size = size), + contentPadding: PaddingValues = getContentPadding(size = size, isIconOnly = isIconOnly), + iconSpacing: Dp = getIconSpacing(size = size), + iconSize: Dp = getIconSize(size = size), ) = PrezelButtonDefault( type = type, size = size, @@ -39,8 +56,12 @@ object PrezelButtonDefaults { contentColor = contentColor, backgroundColor = backgroundColor, borderColor = borderColor, + borderWidth = borderWidth, shape = shape, textStyle = textStyle, + contentPadding = contentPadding, + iconSpacing = iconSpacing, + iconSize = iconSize, ) @Composable @@ -48,29 +69,122 @@ object PrezelButtonDefaults { type: ButtonType, hierarchy: ButtonHierarchy, enabled: Boolean, - ): Color = LocalPrezelButtonContent.current.getContentColor(type = type, hierarchy = hierarchy, enabled = enabled) + ): Color { + if (!enabled) return PrezelTheme.colors.textDisabled + if (hierarchy == ButtonHierarchy.SECONDARY) return PrezelTheme.colors.textMedium + + return when (type) { + ButtonType.FILLED -> PrezelColorScheme.Dark.textLarge + ButtonType.OUTLINED, + ButtonType.GHOST, + -> PrezelTheme.colors.interactiveRegular + } + } @Composable private fun getBackgroundColor( type: ButtonType, hierarchy: ButtonHierarchy, enabled: Boolean, - ): Color = LocalPrezelButtonContent.current.getBackgroundColor(type = type, hierarchy = hierarchy, enabled = enabled) + ): Color = + when (type) { + ButtonType.OUTLINED, + ButtonType.GHOST, + -> Color.Transparent + + ButtonType.FILLED -> { + if (!enabled || hierarchy == ButtonHierarchy.SECONDARY) { + PrezelTheme.colors.bgLarge + } else { + PrezelTheme.colors.interactiveRegular + } + } + } + + @Composable + private fun getBorderColor( + type: ButtonType, + hierarchy: ButtonHierarchy, + enabled: Boolean, + ): Color { + if (type != ButtonType.OUTLINED) return Color.Transparent + if (!enabled) return PrezelTheme.colors.borderDisabled + + return when (hierarchy) { + ButtonHierarchy.PRIMARY -> PrezelTheme.colors.interactiveRegular + ButtonHierarchy.SECONDARY -> PrezelTheme.colors.borderMedium + } + } + + @Composable + private fun getBorderWidth(type: ButtonType): Dp = if (type == ButtonType.OUTLINED) PrezelTheme.stroke.V1 else 0.dp @Composable private fun getShape( isRounded: Boolean, isIconOnly: Boolean, size: ButtonSize, - ): RoundedCornerShape = LocalPrezelButtonContent.current.getShape(isRounded = isRounded, isIconOnly = isIconOnly, size = size) + ): RoundedCornerShape { + if (isRounded) return PrezelTheme.shapes.V1000 + + return when (size) { + ButtonSize.REGULAR -> PrezelTheme.shapes.V8 + ButtonSize.SMALL -> if (isIconOnly) PrezelTheme.shapes.V6 else PrezelTheme.shapes.V4 + ButtonSize.XSMALL -> PrezelTheme.shapes.V4 + } + } @Composable - private fun getBorderColor( - type: ButtonType, - hierarchy: ButtonHierarchy, - enabled: Boolean, - ): Color = LocalPrezelButtonBorder.current.getBorderColor(type = type, hierarchy = hierarchy, enabled = enabled) + private fun getTextStyle(size: ButtonSize): TextStyle = + when (size) { + ButtonSize.XSMALL -> PrezelTheme.typography.caption2Medium + ButtonSize.SMALL -> PrezelTheme.typography.body3Medium + ButtonSize.REGULAR -> PrezelTheme.typography.body2Bold + } @Composable - private fun getTextStyle(size: ButtonSize): TextStyle = LocalPrezelButtonTextStyle.current.getTextStyle(size = size) + private fun getContentPadding( + size: ButtonSize, + isIconOnly: Boolean, + ): PaddingValues { + if (isIconOnly) { + val all = when (size) { + ButtonSize.XSMALL -> PrezelTheme.spacing.V8 + ButtonSize.SMALL -> PrezelTheme.spacing.V10 + ButtonSize.REGULAR -> PrezelTheme.spacing.V14 + } + + return PaddingValues(all = all) + } + + val horizontal = when (size) { + ButtonSize.XSMALL -> PrezelTheme.spacing.V10 + ButtonSize.SMALL -> PrezelTheme.spacing.V12 + ButtonSize.REGULAR -> PrezelTheme.spacing.V16 + } + val vertical = when (size) { + ButtonSize.XSMALL -> PrezelTheme.spacing.V6 + ButtonSize.SMALL -> PrezelTheme.spacing.V8 + ButtonSize.REGULAR -> PrezelTheme.spacing.V12 + } + + return PaddingValues(horizontal = horizontal, vertical = vertical) + } + + @Composable + private fun getIconSpacing(size: ButtonSize): Dp = + when (size) { + ButtonSize.XSMALL, + ButtonSize.SMALL, + -> PrezelTheme.spacing.V4 + + ButtonSize.REGULAR -> PrezelTheme.spacing.V8 + } + + private fun getIconSize(size: ButtonSize): Dp = + when (size) { + ButtonSize.XSMALL -> 14.dp + ButtonSize.SMALL -> 16.dp + ButtonSize.REGULAR -> 20.dp + } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonUtils.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonModels.kt similarity index 54% rename from Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonUtils.kt rename to Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonModels.kt index 01be3e1..4a47aa3 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonUtils.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonModels.kt @@ -1,10 +1,6 @@ package com.team.prezel.core.designsystem.component.actions.button.config -import androidx.compose.foundation.layout.padding -import androidx.compose.runtime.Composable import androidx.compose.runtime.Immutable -import androidx.compose.ui.Modifier -import com.team.prezel.core.designsystem.theme.PrezelTheme /** * 버튼의 시각적 타입을 정의합니다. @@ -53,28 +49,3 @@ enum class ButtonHierarchy { /** 보조 액션에 사용되는 계층입니다. */ SECONDARY, } - -@Composable -internal fun Modifier.buttonContentPadding(size: ButtonSize): Modifier = - this.padding( - horizontal = when (size) { - ButtonSize.XSMALL -> PrezelTheme.spacing.V10 - ButtonSize.SMALL -> PrezelTheme.spacing.V12 - ButtonSize.REGULAR -> PrezelTheme.spacing.V16 - }, - vertical = when (size) { - ButtonSize.XSMALL -> PrezelTheme.spacing.V6 - ButtonSize.SMALL -> PrezelTheme.spacing.V8 - ButtonSize.REGULAR -> PrezelTheme.spacing.V12 - }, - ) - -@Composable -internal fun Modifier.iconButtonContentPadding(size: ButtonSize): Modifier = - this.padding( - all = when (size) { - ButtonSize.XSMALL -> PrezelTheme.spacing.V8 - ButtonSize.SMALL -> PrezelTheme.spacing.V10 - ButtonSize.REGULAR -> PrezelTheme.spacing.V14 - }, - ) From d986a9be92339c38aa4217b58913a6594cdee2e6 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Mon, 23 Mar 2026 02:36:16 +0900 Subject: [PATCH 09/42] =?UTF-8?q?refactor:=20=EB=B2=84=ED=8A=BC=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=ED=94=84=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EA=B5=AC=EC=A1=B0=20=EA=B0=9C=EC=84=A0=20=EB=B0=8F?= =?UTF-8?q?=20=EB=A6=AC=ED=8C=A9=ED=84=B0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../component/actions/button/PrezelButton.kt | 30 ++++ .../actions/button/PrezelIconButton.kt | 29 ++++ .../actions/button/PrezelTextButton.kt | 28 +++ .../button/{ => config}/PrezelButtonBase.kt | 3 +- .../{ => config}/PrezelButtonPreview.kt | 164 +++++------------- 5 files changed, 130 insertions(+), 124 deletions(-) rename Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/{ => config}/PrezelButtonBase.kt (97%) rename Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/{ => config}/PrezelButtonPreview.kt (62%) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButton.kt index 0abd3c4..3f2f6b2 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButton.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButton.kt @@ -3,11 +3,16 @@ package com.team.prezel.core.designsystem.component.actions.button import androidx.annotation.DrawableRes import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview import com.team.prezel.core.designsystem.component.actions.button.config.ButtonHierarchy import com.team.prezel.core.designsystem.component.actions.button.config.ButtonSize import com.team.prezel.core.designsystem.component.actions.button.config.ButtonType +import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonBase import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefault import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefaults +import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonPreviewContent +import com.team.prezel.core.designsystem.component.actions.button.config.previewGhostBorder +import com.team.prezel.core.designsystem.icon.PrezelIcons @Composable fun PrezelButton( @@ -37,3 +42,28 @@ fun PrezelButton( ), ) } + +@Preview(device = "spec:width=1080dp,height=1400dp") +@Composable +private fun PrezelButtonPreview() { + PrezelButtonPreviewContent(title = "Button/Icon + Text") { type, hierarchy, size, enabled, isRounded -> + PrezelButton( + text = "Label", + iconResId = PrezelIcons.Blank, + type = type, + size = size, + hierarchy = hierarchy, + enabled = enabled, + isRounded = isRounded, + onClick = {}, + modifier = Modifier.previewGhostBorder( + type = type, + hierarchy = hierarchy, + size = size, + enabled = enabled, + isRounded = isRounded, + isIconOnly = false, + ), + ) + } +} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelIconButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelIconButton.kt index b7cbdc8..71f97cb 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelIconButton.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelIconButton.kt @@ -3,11 +3,16 @@ package com.team.prezel.core.designsystem.component.actions.button import androidx.annotation.DrawableRes import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview import com.team.prezel.core.designsystem.component.actions.button.config.ButtonHierarchy import com.team.prezel.core.designsystem.component.actions.button.config.ButtonSize import com.team.prezel.core.designsystem.component.actions.button.config.ButtonType +import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonBase import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefault import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefaults +import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonPreviewContent +import com.team.prezel.core.designsystem.component.actions.button.config.previewGhostBorder +import com.team.prezel.core.designsystem.icon.PrezelIcons @Composable fun PrezelIconButton( @@ -35,3 +40,27 @@ fun PrezelIconButton( ), ) } + +@Preview(device = "spec:width=1080dp,height=1500dp") +@Composable +private fun PrezelIconButtonPreview() { + PrezelButtonPreviewContent(title = "Button/Icon") { type, hierarchy, size, enabled, isRounded -> + PrezelIconButton( + iconResId = PrezelIcons.Blank, + type = type, + size = size, + hierarchy = hierarchy, + enabled = enabled, + isRounded = isRounded, + onClick = {}, + modifier = Modifier.previewGhostBorder( + type = type, + hierarchy = hierarchy, + size = size, + enabled = enabled, + isRounded = isRounded, + isIconOnly = true, + ), + ) + } +} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelTextButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelTextButton.kt index 5408c4f..b015f92 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelTextButton.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelTextButton.kt @@ -2,11 +2,15 @@ package com.team.prezel.core.designsystem.component.actions.button import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview import com.team.prezel.core.designsystem.component.actions.button.config.ButtonHierarchy import com.team.prezel.core.designsystem.component.actions.button.config.ButtonSize import com.team.prezel.core.designsystem.component.actions.button.config.ButtonType +import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonBase import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefault import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefaults +import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonPreviewContent +import com.team.prezel.core.designsystem.component.actions.button.config.previewGhostBorder @Composable fun PrezelTextButton( @@ -34,3 +38,27 @@ fun PrezelTextButton( ), ) } + +@Preview(device = "spec:width=1080dp,height=1350dp") +@Composable +private fun PrezelTextButtonPreview() { + PrezelButtonPreviewContent(title = "Button/Text") { type, hierarchy, size, enabled, isRounded -> + PrezelTextButton( + text = "Label", + type = type, + size = size, + hierarchy = hierarchy, + enabled = enabled, + isRounded = isRounded, + onClick = {}, + modifier = Modifier.previewGhostBorder( + type = type, + hierarchy = hierarchy, + size = size, + enabled = enabled, + isRounded = isRounded, + isIconOnly = false, + ), + ) + } +} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonBase.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonBase.kt similarity index 97% rename from Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonBase.kt rename to Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonBase.kt index a8d37eb..e86e76d 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonBase.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonBase.kt @@ -1,4 +1,4 @@ -package com.team.prezel.core.designsystem.component.actions.button +package com.team.prezel.core.designsystem.component.actions.button.config import androidx.annotation.DrawableRes import androidx.compose.foundation.Image @@ -20,7 +20,6 @@ import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow -import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefault import com.team.prezel.core.designsystem.component.base.PrezelTouchArea @Composable diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonPreview.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonPreview.kt similarity index 62% rename from Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonPreview.kt rename to Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonPreview.kt index b02a417..0b34e39 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButtonPreview.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonPreview.kt @@ -1,4 +1,4 @@ -package com.team.prezel.core.designsystem.component.actions.button +package com.team.prezel.core.designsystem.component.actions.button.config import androidx.compose.foundation.background import androidx.compose.foundation.border @@ -7,7 +7,6 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.IntrinsicSize import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.defaultMinSize import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height @@ -18,13 +17,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.team.prezel.core.designsystem.component.actions.button.config.ButtonHierarchy -import com.team.prezel.core.designsystem.component.actions.button.config.ButtonSize -import com.team.prezel.core.designsystem.component.actions.button.config.ButtonType -import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefaults -import com.team.prezel.core.designsystem.icon.PrezelIcons import com.team.prezel.core.designsystem.preview.PreviewScaffold import com.team.prezel.core.designsystem.preview.SectionTitle import com.team.prezel.core.designsystem.theme.PrezelTheme @@ -44,81 +37,8 @@ private val previewSections = PreviewSection(title = "Disabled / Rounded", enabled = false, isRounded = true), ) -@Preview(device = "spec:width=1080dp,height=1400dp") @Composable -private fun PrezelButtonsPreview() { - PrezelButtonPreviewScreen(title = "Button/Icon + Text") { type, hierarchy, size, enabled, isRounded -> - PrezelButton( - text = "Label", - iconResId = PrezelIcons.Blank, - type = type, - size = size, - hierarchy = hierarchy, - enabled = enabled, - isRounded = isRounded, - onClick = {}, - modifier = Modifier.previewGhostBorderModifier( - type = type, - hierarchy = hierarchy, - size = size, - enabled = enabled, - isRounded = isRounded, - isIconOnly = false, - ), - ) - } -} - -@Preview(device = "spec:width=1080dp,height=1350dp") -@Composable -private fun PrezelTextButtonsPreview() { - PrezelButtonPreviewScreen(title = "Button/Text") { type, hierarchy, size, enabled, isRounded -> - PrezelTextButton( - text = "Label", - type = type, - size = size, - hierarchy = hierarchy, - enabled = enabled, - isRounded = isRounded, - onClick = {}, - modifier = Modifier.previewGhostBorderModifier( - type = type, - hierarchy = hierarchy, - size = size, - enabled = enabled, - isRounded = isRounded, - isIconOnly = false, - ), - ) - } -} - -@Preview(device = "spec:width=1080dp,height=1500dp") -@Composable -private fun PrezelIconButtonsPreview() { - PrezelButtonPreviewScreen(title = "Button/Icon") { type, hierarchy, size, enabled, isRounded -> - PrezelIconButton( - iconResId = PrezelIcons.Blank, - type = type, - size = size, - hierarchy = hierarchy, - enabled = enabled, - isRounded = isRounded, - onClick = {}, - modifier = Modifier.previewGhostBorderModifier( - type = type, - hierarchy = hierarchy, - size = size, - enabled = enabled, - isRounded = isRounded, - isIconOnly = true, - ), - ) - } -} - -@Composable -private fun PrezelButtonPreviewScreen( +internal fun PrezelButtonPreviewContent( title: String, content: @Composable (ButtonType, ButtonHierarchy, ButtonSize, Boolean, Boolean) -> Unit, ) { @@ -136,7 +56,7 @@ private fun PrezelButtonPreviewScreen( ) previewSections.forEach { section -> - PrezelButtonPreviewTable( + ButtonPreviewSection( title = section.title, enabled = section.enabled, isRounded = section.isRounded, @@ -148,7 +68,32 @@ private fun PrezelButtonPreviewScreen( } @Composable -private fun PrezelButtonPreviewTable( +internal fun Modifier.previewGhostBorder( + type: ButtonType, + hierarchy: ButtonHierarchy, + size: ButtonSize, + enabled: Boolean, + isRounded: Boolean, + isIconOnly: Boolean, +): Modifier = + if (type == ButtonType.GHOST) { + this.drawDashBorder( + shape = PrezelButtonDefaults + .getDefault( + isIconOnly = isIconOnly, + isRounded = isRounded, + type = type, + size = size, + hierarchy = hierarchy, + enabled = enabled, + ).shape, + ) + } else { + Modifier + } + +@Composable +private fun ButtonPreviewSection( title: String, enabled: Boolean, isRounded: Boolean, @@ -165,10 +110,10 @@ private fun PrezelButtonPreviewTable( modifier = Modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(0.dp), ) { - PrezelButtonTableHeader() + ButtonPreviewHeaderRow() ButtonSize.entries.forEach { size -> - PrezelButtonTableRow( + ButtonPreviewRow( size = size, enabled = enabled, isRounded = isRounded, @@ -180,21 +125,21 @@ private fun PrezelButtonPreviewTable( } @Composable -private fun PrezelButtonTableHeader() { +private fun ButtonPreviewHeaderRow() { Row( modifier = Modifier.height(IntrinsicSize.Min), horizontalArrangement = Arrangement.spacedBy(0.dp), ) { - PreviewHeaderCell( + ButtonPreviewHeaderCell( text = "Size", - modifier = Modifier.defaultMinSize(minWidth = 88.dp), + modifier = Modifier.weight(1f), ) ButtonType.entries.forEach { type -> ButtonHierarchy.entries.forEach { hierarchy -> - PreviewHeaderCell( + ButtonPreviewHeaderCell( text = "${type.name}\n${hierarchy.name}", - modifier = Modifier.defaultMinSize(minWidth = 156.dp), + modifier = Modifier.weight(1f), ) } } @@ -202,7 +147,7 @@ private fun PrezelButtonTableHeader() { } @Composable -private fun PrezelButtonTableRow( +private fun ButtonPreviewRow( size: ButtonSize, enabled: Boolean, isRounded: Boolean, @@ -212,9 +157,9 @@ private fun PrezelButtonTableRow( modifier = Modifier.height(IntrinsicSize.Min), horizontalArrangement = Arrangement.spacedBy(0.dp), ) { - PreviewButtonCell(modifier = Modifier.defaultMinSize(minWidth = 88.dp)) { + ButtonPreviewCell(modifier = Modifier.weight(1f)) { Text( - text = size.name.lowercase(), + text = size.name, style = PrezelTheme.typography.body3Medium, color = PrezelTheme.colors.textLarge, ) @@ -222,7 +167,7 @@ private fun PrezelButtonTableRow( ButtonType.entries.forEach { type -> ButtonHierarchy.entries.forEach { hierarchy -> - PreviewButtonCell(modifier = Modifier.defaultMinSize(minWidth = 156.dp)) { + ButtonPreviewCell(modifier = Modifier.weight(1f)) { content(type, hierarchy, size, enabled, isRounded) } } @@ -231,7 +176,7 @@ private fun PrezelButtonTableRow( } @Composable -private fun PreviewHeaderCell( +private fun ButtonPreviewHeaderCell( text: String, modifier: Modifier = Modifier, ) { @@ -253,7 +198,7 @@ private fun PreviewHeaderCell( } @Composable -private fun PreviewButtonCell( +private fun ButtonPreviewCell( modifier: Modifier = Modifier, content: @Composable () -> Unit, ) { @@ -267,28 +212,3 @@ private fun PreviewButtonCell( content() } } - -@Composable -private fun Modifier.previewGhostBorderModifier( - type: ButtonType, - hierarchy: ButtonHierarchy, - size: ButtonSize, - enabled: Boolean, - isRounded: Boolean, - isIconOnly: Boolean, -): Modifier = - if (type == ButtonType.GHOST) { - this.drawDashBorder( - shape = PrezelButtonDefaults - .getDefault( - isIconOnly = isIconOnly, - isRounded = isRounded, - type = type, - size = size, - hierarchy = hierarchy, - enabled = enabled, - ).shape, - ) - } else { - Modifier - } From eabfead634a94abc1b94eb91b26159a1590f04aa Mon Sep 17 00:00:00 2001 From: moondev03 Date: Mon, 23 Mar 2026 04:52:29 +0900 Subject: [PATCH 10/42] =?UTF-8?q?refactor:=20PrezelButton=20=EA=B3=84?= =?UTF-8?q?=EC=97=B4=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=EC=9D=98=20?= =?UTF-8?q?=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20=EA=B5=AC=EC=A1=B0=20?= =?UTF-8?q?=EB=B0=8F=20=EA=B8=B0=EB=B3=B8=EA=B0=92=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../component/actions/button/PrezelButton.kt | 20 +++++++++---------- .../actions/button/PrezelIconButton.kt | 18 ++++++++--------- .../actions/button/PrezelTextButton.kt | 18 ++++++++--------- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButton.kt index 3f2f6b2..207dbd9 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButton.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButton.kt @@ -17,14 +17,21 @@ import com.team.prezel.core.designsystem.icon.PrezelIcons @Composable fun PrezelButton( text: String, - @DrawableRes iconResId: Int, modifier: Modifier = Modifier, + @DrawableRes iconResId: Int? = null, type: ButtonType = ButtonType.FILLED, size: ButtonSize = ButtonSize.REGULAR, hierarchy: ButtonHierarchy = ButtonHierarchy.PRIMARY, enabled: Boolean = true, isRounded: Boolean = false, - buttonDefault: PrezelButtonDefault? = null, + buttonDefault: PrezelButtonDefault = PrezelButtonDefaults.getDefault( + isIconOnly = false, + isRounded = isRounded, + type = type, + size = size, + hierarchy = hierarchy, + enabled = enabled, + ), onClick: () -> Unit, ) { PrezelButtonBase( @@ -32,14 +39,7 @@ fun PrezelButton( iconResId = iconResId, modifier = modifier, onClick = onClick, - buttonDefault = buttonDefault ?: PrezelButtonDefaults.getDefault( - isIconOnly = false, - isRounded = isRounded, - type = type, - size = size, - hierarchy = hierarchy, - enabled = enabled, - ), + buttonDefault = buttonDefault, ) } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelIconButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelIconButton.kt index 71f97cb..13c81c2 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelIconButton.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelIconButton.kt @@ -23,21 +23,21 @@ fun PrezelIconButton( hierarchy: ButtonHierarchy = ButtonHierarchy.PRIMARY, enabled: Boolean = true, isRounded: Boolean = false, - buttonDefault: PrezelButtonDefault? = null, + buttonDefault: PrezelButtonDefault = PrezelButtonDefaults.getDefault( + isIconOnly = true, + isRounded = isRounded, + type = type, + size = size, + hierarchy = hierarchy, + enabled = enabled, + ), onClick: () -> Unit, ) { PrezelButtonBase( iconResId = iconResId, modifier = modifier, onClick = onClick, - buttonDefault = buttonDefault ?: PrezelButtonDefaults.getDefault( - isIconOnly = true, - isRounded = isRounded, - type = type, - size = size, - hierarchy = hierarchy, - enabled = enabled, - ), + buttonDefault = buttonDefault, ) } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelTextButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelTextButton.kt index b015f92..3db3523 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelTextButton.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelTextButton.kt @@ -21,21 +21,21 @@ fun PrezelTextButton( hierarchy: ButtonHierarchy = ButtonHierarchy.PRIMARY, enabled: Boolean = true, isRounded: Boolean = false, - buttonDefault: PrezelButtonDefault? = null, + buttonDefault: PrezelButtonDefault = PrezelButtonDefaults.getDefault( + isIconOnly = false, + isRounded = isRounded, + type = type, + size = size, + hierarchy = hierarchy, + enabled = enabled, + ), onClick: () -> Unit, ) { PrezelButtonBase( text = text, modifier = modifier, onClick = onClick, - buttonDefault = buttonDefault ?: PrezelButtonDefaults.getDefault( - isIconOnly = false, - isRounded = isRounded, - type = type, - size = size, - hierarchy = hierarchy, - enabled = enabled, - ), + buttonDefault = buttonDefault, ) } From c436c658291f16eff150c6946e394ef1d13760f5 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Mon, 23 Mar 2026 04:52:38 +0900 Subject: [PATCH 11/42] =?UTF-8?q?refactor:=20PrezelTouchArea=20=EB=82=B4?= =?UTF-8?q?=EB=B6=80=20Box=EC=9D=98=20wrapContentSize=20=EC=86=8D=EC=84=B1?= =?UTF-8?q?=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../actions/button/config/PrezelButtonBase.kt | 11 +++-------- .../designsystem/component/base/PrezelTouchArea.kt | 2 -- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonBase.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonBase.kt index e86e76d..3ec56f2 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonBase.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonBase.kt @@ -7,7 +7,6 @@ import androidx.compose.foundation.border import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.material3.Text @@ -31,14 +30,15 @@ internal fun PrezelButtonBase( @DrawableRes iconResId: Int? = null, ) { PrezelTouchArea( - modifier = modifier, + modifier = modifier.buttonContainer(buttonDefault), + extraTouchPadding = buttonDefault.contentPadding, onClick = onClick, enabled = buttonDefault.enabled, shape = buttonDefault.shape, isUseRipple = true, ) { ButtonContentLayout( - modifier = Modifier.buttonContent(buttonDefault), + modifier = Modifier, horizontalArrangement = buttonDefault.contentArrangement( hasText = text != null, hasIcon = iconResId != null, @@ -126,11 +126,6 @@ private fun PrezelButtonDefault.contentArrangement( hasIcon: Boolean, ): Arrangement.Horizontal = if (hasText && hasIcon) Arrangement.spacedBy(iconSpacing) else Arrangement.Center -private fun Modifier.buttonContent(buttonDefault: PrezelButtonDefault): Modifier = - this - .buttonContainer(buttonDefault) - .padding(buttonDefault.contentPadding) - private fun Modifier.buttonContainer(buttonDefault: PrezelButtonDefault): Modifier = this .clip(shape = buttonDefault.shape) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelTouchArea.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelTouchArea.kt index dc31ef1..da327cb 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelTouchArea.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelTouchArea.kt @@ -8,7 +8,6 @@ import androidx.compose.foundation.layout.BoxScope import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.material3.ripple import androidx.compose.runtime.Composable import androidx.compose.runtime.remember @@ -36,7 +35,6 @@ fun PrezelTouchArea( ) { Box( modifier = modifier - .wrapContentSize() .clip(shape = shape) .clickable( enabled = enabled, From 65ffb6bcab2e8607a2356685be6b6aa287717f70 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Mon, 23 Mar 2026 04:53:16 +0900 Subject: [PATCH 12/42] =?UTF-8?q?feat:=20PrezelButtonArea=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../actions/area/PrezelButtonArea.kt | 358 ++++++++++++++++++ .../actions/area/PrezelButtonAreaDefaults.kt | 43 +++ 2 files changed, 401 insertions(+) create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonArea.kt create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonAreaDefaults.kt diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonArea.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonArea.kt new file mode 100644 index 0000000..ba7022b --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonArea.kt @@ -0,0 +1,358 @@ +package com.team.prezel.core.designsystem.component.actions.area + +import androidx.annotation.DrawableRes +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.IntrinsicSize +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +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.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Immutable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.team.prezel.core.designsystem.component.PrezelDividerType +import com.team.prezel.core.designsystem.component.PrezelHorizontalDivider +import com.team.prezel.core.designsystem.component.actions.button.PrezelButton +import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefault +import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefaults +import com.team.prezel.core.designsystem.icon.PrezelIcons +import com.team.prezel.core.designsystem.preview.PreviewScaffold +import com.team.prezel.core.designsystem.preview.SectionTitle +import com.team.prezel.core.designsystem.theme.PrezelTheme + +@Immutable +data class ButtonAreaButtonSpec( + @param:DrawableRes val iconResId: Int? = null, + val label: String, + val enabled: Boolean = true, + val onClick: () -> Unit, +) + +@Composable +fun PrezelButtonArea( + mainButton: ButtonAreaButtonSpec, + modifier: Modifier = Modifier, + subButton: ButtonAreaButtonSpec? = null, + isVertical: Boolean = true, + showBackground: Boolean = false, + isStrongStrength: Boolean = true, + isNested: Boolean = false, + config: PrezelButtonAreaDefault = PrezelButtonAreaDefaults.getDefault( + showBackground = showBackground, + isNested = isNested, + ), +) { + Column(modifier = modifier) { + if (showBackground) PrezelHorizontalDivider(type = PrezelDividerType.THICK) + + val contentModifier = Modifier + .background(config.backgroundColor) + .padding(config.contentPadding) + .fillMaxWidth() + + if (isVertical) { + ButtonAreaVertical( + modifier = contentModifier, + mainButton = mainButton, + subButton = subButton, + buttonAreaDefault = config, + ) + } else { + ButtonAreaHorizontal( + modifier = contentModifier, + isStrongStrength = isStrongStrength, + mainButton = mainButton, + subButton = subButton, + buttonAreaDefault = config, + ) + } + } +} + +@Composable +private fun ButtonAreaVertical( + modifier: Modifier, + mainButton: ButtonAreaButtonSpec, + subButton: ButtonAreaButtonSpec?, + buttonAreaDefault: PrezelButtonAreaDefault, +) { + Column(modifier = modifier) { + PrezelButton( + modifier = Modifier.fillMaxWidth(), + text = mainButton.label, + iconResId = mainButton.iconResId, + onClick = mainButton.onClick, + enabled = mainButton.enabled, + buttonDefault = buttonAreaDefault.mainButtonDefault.applyEnabled(mainButton.enabled), + ) + + if (subButton != null) { + Spacer(modifier = Modifier.height(PrezelTheme.spacing.V12)) + PrezelButton( + modifier = Modifier.fillMaxWidth(), + text = subButton.label, + iconResId = subButton.iconResId, + onClick = subButton.onClick, + enabled = subButton.enabled, + buttonDefault = buttonAreaDefault.subButtonDefault.applyEnabled(subButton.enabled), + ) + } + } +} + +@Composable +private fun ButtonAreaHorizontal( + modifier: Modifier, + mainButton: ButtonAreaButtonSpec, + subButton: ButtonAreaButtonSpec?, + isStrongStrength: Boolean, + buttonAreaDefault: PrezelButtonAreaDefault, +) { + Row(modifier = modifier) { + if (subButton != null) { + PrezelButton( + modifier = if (isStrongStrength) Modifier else Modifier.weight(1f), + text = subButton.label, + iconResId = subButton.iconResId, + onClick = subButton.onClick, + enabled = subButton.enabled, + buttonDefault = buttonAreaDefault.subButtonDefault.applyEnabled(subButton.enabled), + ) + Spacer(modifier = Modifier.width(PrezelTheme.spacing.V12)) + } + + PrezelButton( + modifier = Modifier.weight(1f), + text = mainButton.label, + iconResId = mainButton.iconResId, + onClick = mainButton.onClick, + enabled = mainButton.enabled, + buttonDefault = buttonAreaDefault.mainButtonDefault.applyEnabled(mainButton.enabled), + ) + } +} + +@Composable +private fun PrezelButtonDefault.applyEnabled(enabled: Boolean): PrezelButtonDefault { + if (this.enabled == enabled) return this + + val resolvedStateDefault = PrezelButtonDefaults.getDefault( + isIconOnly = false, + type = type, + size = size, + hierarchy = hierarchy, + enabled = enabled, + ) + + return copy( + contentColor = resolvedStateDefault.contentColor, + backgroundColor = resolvedStateDefault.backgroundColor, + borderColor = resolvedStateDefault.borderColor, + borderWidth = resolvedStateDefault.borderWidth, + shape = resolvedStateDefault.shape, + textStyle = resolvedStateDefault.textStyle, + contentPadding = resolvedStateDefault.contentPadding, + iconSpacing = resolvedStateDefault.iconSpacing, + iconSize = resolvedStateDefault.iconSize, + ) +} + +private data class ButtonAreaPreviewVariant( + val title: String, + val isVertical: Boolean, + val isStrongStrength: Boolean, +) + +private val buttonAreaPreviewVariants = + listOf( + ButtonAreaPreviewVariant(title = "Vertical", isVertical = true, isStrongStrength = true), + ButtonAreaPreviewVariant(title = "Horizontal / Strong Strength", isVertical = false, isStrongStrength = true), + ButtonAreaPreviewVariant(title = "Horizontal / Weak Strength", isVertical = false, isStrongStrength = false), + ) + +private val buttonAreaPreviewStates = + listOf( + true to "Enabled", + false to "Disabled", + ) + +@Preview(device = "spec:width=1080dp,height=1800dp") +@Composable +private fun PrezelButtonAreaPreview() { + PrezelTheme { + PreviewScaffold { + SectionTitle(title = "Button Area") + Text( + text = "행은 버튼 상태, 열은 배경 여부입니다. 각 섹션은 배치 방향과 강도 옵션을 구분합니다.", + style = PrezelTheme.typography.body3Regular, + color = PrezelTheme.colors.textMedium, + modifier = Modifier + .fillMaxWidth() + .background(Color.LightGray.copy(alpha = 0.4f)) + .padding(8.dp), + ) + + buttonAreaPreviewVariants.forEach { variant -> + ButtonAreaPreviewSection(variant = variant) + } + } + } +} + +@Composable +private fun ButtonAreaPreviewSection(variant: ButtonAreaPreviewVariant) { + Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { + Text( + text = variant.title, + style = PrezelTheme.typography.body3Bold, + color = PrezelTheme.colors.textLarge, + ) + + Column( + modifier = Modifier.fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(0.dp), + ) { + ButtonAreaPreviewHeaderRow() + + buttonAreaPreviewStates.forEach { (enabled, label) -> + ButtonAreaPreviewRow( + variant = variant, + enabled = enabled, + label = label, + ) + } + } + } +} + +@Composable +private fun ButtonAreaPreviewHeaderRow() { + Row( + modifier = Modifier.height(IntrinsicSize.Min), + horizontalArrangement = Arrangement.spacedBy(0.dp), + ) { + ButtonAreaPreviewHeaderCell( + text = "State", + modifier = Modifier.weight(0.5f), + ) + ButtonAreaPreviewHeaderCell( + text = "No Background", + modifier = Modifier.weight(1f), + ) + ButtonAreaPreviewHeaderCell( + text = "Background", + modifier = Modifier.weight(1f), + ) + } +} + +@Composable +private fun ButtonAreaPreviewRow( + variant: ButtonAreaPreviewVariant, + enabled: Boolean, + label: String, +) { + Row( + modifier = Modifier.height(IntrinsicSize.Min), + horizontalArrangement = Arrangement.spacedBy(0.dp), + ) { + ButtonAreaPreviewCell(modifier = Modifier.weight(0.5f)) { + Text( + text = label, + style = PrezelTheme.typography.body3Medium, + color = PrezelTheme.colors.textLarge, + textAlign = TextAlign.Center, + ) + } + + ButtonAreaPreviewCell(modifier = Modifier.weight(1f)) { + ButtonAreaPreviewSample( + variant = variant, + enabled = enabled, + showBackground = false, + ) + } + + ButtonAreaPreviewCell(modifier = Modifier.weight(1f)) { + ButtonAreaPreviewSample( + variant = variant, + enabled = enabled, + showBackground = true, + ) + } + } +} + +@Composable +private fun ButtonAreaPreviewSample( + variant: ButtonAreaPreviewVariant, + enabled: Boolean, + showBackground: Boolean, +) { + val button = ButtonAreaButtonSpec( + label = "Label", + iconResId = PrezelIcons.Blank, + enabled = enabled, + onClick = {}, + ) + + PrezelButtonArea( + modifier = Modifier.fillMaxWidth(), + isVertical = variant.isVertical, + isStrongStrength = variant.isStrongStrength, + showBackground = showBackground, + mainButton = button, + subButton = button, + ) +} + +@Composable +private fun ButtonAreaPreviewHeaderCell( + text: String, + modifier: Modifier = Modifier, +) { + Box( + modifier = modifier + .fillMaxHeight() + .border(width = PrezelTheme.stroke.V1, color = PrezelTheme.colors.borderRegular) + .background(PrezelTheme.colors.bgMedium) + .padding(horizontal = 12.dp, vertical = 10.dp), + contentAlignment = Alignment.Center, + ) { + Text( + text = text, + style = PrezelTheme.typography.body3Medium, + color = PrezelTheme.colors.textMedium, + textAlign = TextAlign.Center, + ) + } +} + +@Composable +private fun ButtonAreaPreviewCell( + modifier: Modifier = Modifier, + content: @Composable () -> Unit, +) { + Box( + modifier = modifier + .fillMaxHeight() + .border(width = PrezelTheme.stroke.V1, color = PrezelTheme.colors.borderRegular) + .padding(horizontal = 12.dp, vertical = 16.dp), + contentAlignment = Alignment.Center, + ) { + content() + } +} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonAreaDefaults.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonAreaDefaults.kt new file mode 100644 index 0000000..2db07b8 --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonAreaDefaults.kt @@ -0,0 +1,43 @@ +package com.team.prezel.core.designsystem.component.actions.area + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Immutable +import androidx.compose.ui.graphics.Color +import com.team.prezel.core.designsystem.component.actions.button.config.ButtonHierarchy +import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefault +import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefaults +import com.team.prezel.core.designsystem.theme.PrezelTheme + +@Immutable +data class PrezelButtonAreaDefault( + val mainButtonDefault: PrezelButtonDefault, + val subButtonDefault: PrezelButtonDefault, + val backgroundColor: Color, + val contentPadding: PaddingValues, +) + +object PrezelButtonAreaDefaults { + @Composable + fun getDefault( + mainButtonDefault: PrezelButtonDefault = PrezelButtonDefaults.getDefault(isIconOnly = false), + subButtonDefault: PrezelButtonDefault = PrezelButtonDefaults.getDefault( + isIconOnly = false, + hierarchy = ButtonHierarchy.SECONDARY, + ), + showBackground: Boolean = false, + isNested: Boolean = false, + ): PrezelButtonAreaDefault = + PrezelButtonAreaDefault( + mainButtonDefault = mainButtonDefault, + subButtonDefault = subButtonDefault, + backgroundColor = getBackgroundColor(showBackground = showBackground), + contentPadding = getContentPadding(isNested = isNested), + ) + + @Composable + private fun getBackgroundColor(showBackground: Boolean): Color = if (showBackground) PrezelTheme.colors.bgRegular else Color.Transparent + + @Composable + private fun getContentPadding(isNested: Boolean): PaddingValues = PaddingValues(if (isNested) PrezelTheme.spacing.V0 else PrezelTheme.spacing.V20) +} From d8536ada090e31f7045d4ff50364bbecb811ee91 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Tue, 24 Mar 2026 16:12:00 +0900 Subject: [PATCH 13/42] =?UTF-8?q?feat:=20PrezelDropShadow=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EB=B0=8F=20Modifier=20=ED=99=95?= =?UTF-8?q?=EC=9E=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../component/base/PrezelDropShadow.kt | 231 ++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelDropShadow.kt diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelDropShadow.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelDropShadow.kt new file mode 100644 index 0000000..d944846 --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelDropShadow.kt @@ -0,0 +1,231 @@ +package com.team.prezel.core.designsystem.component.base + +import android.graphics.BlurMaskFilter +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.drawBehind +import androidx.compose.ui.graphics.ClipOp +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Paint +import androidx.compose.ui.graphics.Path +import androidx.compose.ui.graphics.drawscope.drawIntoCanvas +import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.theme.PrezelTheme + +@Composable +fun Modifier.prezelDropShadow(style: PrezelDropShadowDefaults.PrezelShadowStyle): Modifier { + val cachedShadows = remember(style) { style.getShadow() } + + return this + .dropShadow( + shadows = cachedShadows, + borderRadius = style.borderRadius, + isBackgroundTransparent = style.backgroundColor == Color.Transparent, + ).background( + color = style.backgroundColor, + shape = RoundedCornerShape(style.borderRadius), + ) +} + +private fun Modifier.dropShadow( + shadows: List, + borderRadius: Dp = 0.dp, + isBackgroundTransparent: Boolean = false, +) = this.then( + Modifier.drawBehind { + // Early return으로 불필요한 연산 방지 + if (shadows.isEmpty()) return@drawBehind + + // BlurMaskFilter 캐시 - dropShadow 함수 내부에서만 사용 + val blurMaskFilterCache = mutableMapOf() + + this.drawIntoCanvas { canvas -> + val paint = Paint() + val frameworkPaint = paint.asFrameworkPaint() + + // transparent 배경인 경우를 위한 Path - 재사용 가능하도록 미리 생성 + var clipPath: Path? = null + val borderRadiusPx = borderRadius.toPx() + + if (isBackgroundTransparent && borderRadiusPx > 0f) { + clipPath = Path().apply { + addRoundRect( + androidx.compose.ui.geometry.RoundRect( + left = 0f, + top = 0f, + right = size.width, + bottom = size.height, + radiusX = borderRadiusPx, + radiusY = borderRadiusPx, + ), + ) + } + } + + // shadow를 뒤에서부터 그려서 올바른 layering 구현 + for (i in shadows.size - 1 downTo 0) { + val shadow = shadows[i] + + // 색상 설정 + frameworkPaint.color = shadow.color.toArgb() + + // BlurMaskFilter 캐싱 및 재사용 - 같은 drawBehind 호출 내에서만 캐싱 + val blurRadiusPx = shadow.blurRadius.toPx() + if (blurRadiusPx > 0f) { + frameworkPaint.maskFilter = blurMaskFilterCache.getOrPut(blurRadiusPx) { + BlurMaskFilter(blurRadiusPx, BlurMaskFilter.Blur.NORMAL) + } + } else { + frameworkPaint.maskFilter = null + } + + // 그리기 영역 계산 - 변수 재사용으로 메모리 할당 최소화 + val spreadPixel = shadow.spreadRadius.toPx() + val offsetXPx = shadow.offsetX.toPx() + val offsetYPx = shadow.offsetY.toPx() + + val left = -spreadPixel + offsetXPx + val top = -spreadPixel + offsetYPx + val right = size.width + spreadPixel + offsetXPx + val bottom = size.height + spreadPixel + offsetYPx + + // Clipping 처리 최적화 + var needsRestore = false + if (isBackgroundTransparent) { + canvas.save() + needsRestore = true + + // 미리 생성된 clipPath 재사용 + clipPath?.let { path -> + canvas.clipPath(path, ClipOp.Difference) + } + } + + // 그리기 - 조건부 radius 최적화 + if (borderRadiusPx > 0f) { + canvas.drawRoundRect( + left = left, + top = top, + right = right, + bottom = bottom, + radiusX = borderRadiusPx, + radiusY = borderRadiusPx, + paint = paint, + ) + } else { + // radius가 0이면 더 빠른 drawRect 사용 + canvas.drawRect( + left = left, + top = top, + right = right, + bottom = bottom, + paint = paint, + ) + } + + if (needsRestore) { + canvas.restore() + } + } + } + }, +) + +object PrezelDropShadowDefaults { + sealed class PrezelShadowStyle( + open val borderRadius: Dp, + open val backgroundColor: Color, + ) { + abstract fun getShadow(): List + } + + data object None : PrezelShadowStyle( + borderRadius = 0.dp, + backgroundColor = Color.Transparent, + ) { + override fun getShadow(): List = emptyList() + } + + data class Default( + override val borderRadius: Dp, + override val backgroundColor: Color = Color.Transparent, + ) : PrezelShadowStyle(borderRadius, backgroundColor) { + private val shadowList by lazy { + listOf( + PrezelShadowToken( + offsetX = 0.dp, + offsetY = 2.dp, + blurRadius = 4.dp, + spreadRadius = 0.dp, + color = Color(0x1F000713), + ), + ) + } + + override fun getShadow(): List = shadowList + } + + /** + * data class PrezelShadowToken + * + * Shadow의 개별 속성을 정의하는 데이터 클래스입니다. + * Shadow의 위치, 크기, 색상 등을 설정할 수 있습니다. + * + * @param offsetX Dp: Shadow의 수평 오프셋입니다. + * @param offsetY Dp: Shadow의 수직 오프셋입니다. + * @param blurRadius Dp: Shadow의 블러 반경입니다. + * @param spreadRadius Dp: Shadow의 확산 반경입니다. + * @param color Color: Shadow의 색상입니다. + */ + data class PrezelShadowToken( + val offsetX: Dp, + val offsetY: Dp, + val blurRadius: Dp, + val spreadRadius: Dp, + val color: Color, + ) +} + +@ThemePreview +@Composable +private fun WantedDropShadowPreview() { + PrezelTheme { + Surface { + Column( + modifier = Modifier + .background(PrezelTheme.colors.bgRegular) + .padding(20.dp), + verticalArrangement = Arrangement.spacedBy(20.dp), + ) { + Box( + Modifier + .size(100.dp) + .background(color = Color.Green, shape = RoundedCornerShape(10.dp)) + .prezelDropShadow(style = PrezelDropShadowDefaults.None), + ) + Box( + Modifier + .size(100.dp) + .prezelDropShadow( + style = PrezelDropShadowDefaults.Default( + borderRadius = 10.dp, + backgroundColor = Color.Green, + ), + ), + ) + } + } + } +} From 3c6f174692c51ac10066d7bee45ff1f8aa49a072 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Tue, 24 Mar 2026 18:00:38 +0900 Subject: [PATCH 14/42] =?UTF-8?q?feat:=20=ED=94=8C=EB=A1=9C=ED=8C=85=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EB=B0=8F=20=ED=94=8C=EB=A1=9C=ED=8C=85=20?= =?UTF-8?q?=EB=A9=94=EB=89=B4=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../button/floating/PrezelFloatingButton.kt | 87 ++++++++++++++ .../button/floating/PrezelFloatingMenu.kt | 98 ++++++++++++++++ .../button/floating/menu/PrezelMenu.kt | 69 +++++++++++ .../floating/menu/PrezelMenuDefaults.kt | 51 +++++++++ .../button/floating/menu/PrezelMenuItem.kt | 108 ++++++++++++++++++ .../floating/menu/PrezelMenuItemDefaults.kt | 90 +++++++++++++++ .../button/floating/menu/PrezelMenuScope.kt | 41 +++++++ 7 files changed, 544 insertions(+) create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingButton.kt create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingMenu.kt create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenu.kt create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuDefaults.kt create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuItem.kt create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuItemDefaults.kt create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuScope.kt diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingButton.kt new file mode 100644 index 0000000..a1fb2c5 --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingButton.kt @@ -0,0 +1,87 @@ +package com.team.prezel.core.designsystem.component.actions.button.floating + +import androidx.annotation.DrawableRes +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +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.unit.dp +import com.team.prezel.core.designsystem.component.actions.button.PrezelIconButton +import com.team.prezel.core.designsystem.component.actions.button.config.ButtonHierarchy +import com.team.prezel.core.designsystem.component.actions.button.config.ButtonSize +import com.team.prezel.core.designsystem.icon.PrezelIcons +import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.theme.PrezelTheme + +@Composable +fun PrezelFloatingButton( + isExpanded: Boolean, + onChangeExpanded: (Boolean) -> Unit, + @DrawableRes iconResId: Int, + modifier: Modifier = Modifier, + size: ButtonSize = ButtonSize.REGULAR, + hierarchy: ButtonHierarchy = ButtonHierarchy.PRIMARY, + @DrawableRes openIconResId: Int = PrezelIcons.Cancel, +) { + PrezelIconButton( + iconResId = if (isExpanded) openIconResId else iconResId, + size = size, + hierarchy = hierarchy, + isRounded = true, + modifier = modifier, + onClick = { onChangeExpanded(!isExpanded) }, + ) +} + +@ThemePreview +@Composable +private fun PrezelFloatingButtonPreview() { + var expanded by remember { mutableStateOf(false) } + + PrezelTheme { + Column( + modifier = Modifier + .background(PrezelTheme.colors.bgRegular) + .padding(12.dp), + verticalArrangement = Arrangement.spacedBy(8.dp), + ) { + PrezelFloatingButton( + isExpanded = expanded, + onChangeExpanded = { expanded = it }, + iconResId = PrezelIcons.Blank, + hierarchy = ButtonHierarchy.PRIMARY, + size = ButtonSize.REGULAR, + ) + + PrezelFloatingButton( + isExpanded = expanded, + onChangeExpanded = { expanded = it }, + iconResId = PrezelIcons.Blank, + hierarchy = ButtonHierarchy.SECONDARY, + size = ButtonSize.REGULAR, + ) + + PrezelFloatingButton( + isExpanded = expanded, + onChangeExpanded = { expanded = it }, + iconResId = PrezelIcons.Blank, + hierarchy = ButtonHierarchy.PRIMARY, + size = ButtonSize.SMALL, + ) + + PrezelFloatingButton( + isExpanded = expanded, + onChangeExpanded = { expanded = it }, + iconResId = PrezelIcons.Blank, + hierarchy = ButtonHierarchy.SECONDARY, + size = ButtonSize.SMALL, + ) + } + } +} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingMenu.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingMenu.kt new file mode 100644 index 0000000..5d691c9 --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingMenu.kt @@ -0,0 +1,98 @@ +package com.team.prezel.core.designsystem.component.actions.button.floating + +import androidx.annotation.DrawableRes +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +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.graphics.Color +import androidx.compose.ui.unit.dp +import com.team.prezel.core.designsystem.component.actions.button.config.ButtonHierarchy +import com.team.prezel.core.designsystem.component.actions.button.config.ButtonSize +import com.team.prezel.core.designsystem.component.actions.button.floating.menu.MenuSize +import com.team.prezel.core.designsystem.component.actions.button.floating.menu.PrezelMenu +import com.team.prezel.core.designsystem.component.actions.button.floating.menu.PrezelMenuScope +import com.team.prezel.core.designsystem.icon.PrezelIcons +import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.theme.PrezelTheme + +@Composable +fun PrezelFloatingMenu( + isExpanded: Boolean, + onChangeExpanded: (Boolean) -> Unit, + @DrawableRes iconResId: Int, + modifier: Modifier = Modifier, + @DrawableRes openIconResId: Int = PrezelIcons.Cancel, + size: ButtonSize = ButtonSize.REGULAR, + hierarchy: ButtonHierarchy = ButtonHierarchy.PRIMARY, + items: @Composable PrezelMenuScope.() -> Unit, +) { + Column( + modifier = modifier, + horizontalAlignment = Alignment.End, + ) { + if (isExpanded) { + PrezelMenu( + size = when (size) { + ButtonSize.SMALL -> MenuSize.SMALL + ButtonSize.REGULAR -> MenuSize.REGULAR + else -> MenuSize.REGULAR + }, + content = items, + ) + } + + Spacer(modifier = Modifier.height(PrezelTheme.spacing.V16)) + + PrezelFloatingButton( + isExpanded = isExpanded, + onChangeExpanded = onChangeExpanded, + iconResId = iconResId, + openIconResId = openIconResId, + size = size, + hierarchy = hierarchy, + ) + } +} + +@ThemePreview +@Composable +private fun PrezelFloatingMenuPreview() { + var expanded by remember { mutableStateOf(true) } + + PrezelTheme { + Box( + modifier = Modifier + .background(Color.LightGray) + .size(width = 200.dp, height = 300.dp) + .padding(8.dp), + ) { + PrezelFloatingMenu( + isExpanded = expanded, + onChangeExpanded = { expanded = it }, + iconResId = PrezelIcons.Blank, + hierarchy = ButtonHierarchy.PRIMARY, + size = ButtonSize.REGULAR, + modifier = Modifier.align(Alignment.BottomEnd), + ) { + repeat(5) { + MenuItem( + label = "Label", + iconResId = PrezelIcons.Blank, + onClick = { expanded = !expanded }, + ) + } + } + } + } +} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenu.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenu.kt new file mode 100644 index 0000000..63cf6f0 --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenu.kt @@ -0,0 +1,69 @@ +package com.team.prezel.core.designsystem.component.actions.button.floating.menu + +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.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import com.team.prezel.core.designsystem.icon.PrezelIcons +import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.theme.PrezelTheme + +@Composable +fun PrezelMenu( + modifier: Modifier = Modifier, + size: MenuSize = MenuSize.REGULAR, + config: PrezelMenuDefault = PrezelMenuDefaults.getDefault(size), + content: @Composable PrezelMenuScope.() -> Unit, +) { + val scope = remember(size) { DefaultPrezelMenuScope(menuSize = size) } + + Column( + modifier = modifier + .clip(shape = config.shape) + .background(color = config.backgroundColor) + .padding(config.contentPadding), + verticalArrangement = config.verticalArrangement, + ) { + scope.content() + } +} + +@ThemePreview +@Composable +private fun PrezelMenuPreview() { + PrezelTheme { + Row( + horizontalArrangement = Arrangement.spacedBy(8.dp), + modifier = Modifier + .background(Color.LightGray) + .padding(8.dp), + ) { + PrezelMenu { + repeat(5) { + MenuItem( + label = "Label", + iconResId = PrezelIcons.Blank, + onClick = {}, + ) + } + } + + PrezelMenu(size = MenuSize.SMALL) { + repeat(5) { + MenuItem( + label = "Label", + iconResId = PrezelIcons.Blank, + onClick = {}, + ) + } + } + } + } +} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuDefaults.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuDefaults.kt new file mode 100644 index 0000000..b7087ba --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuDefaults.kt @@ -0,0 +1,51 @@ +package com.team.prezel.core.designsystem.component.actions.button.floating.menu + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Immutable +import androidx.compose.ui.graphics.Color +import com.team.prezel.core.designsystem.theme.PrezelTheme + +enum class MenuSize { + SMALL, + REGULAR, +} + +@Immutable +data class PrezelMenuDefault( + val contentPadding: PaddingValues, + val backgroundColor: Color, + val verticalArrangement: Arrangement.Vertical, + val shape: RoundedCornerShape, +) + +object PrezelMenuDefaults { + @Composable + fun getDefault(size: MenuSize): PrezelMenuDefault = + PrezelMenuDefault( + contentPadding = getContentPadding(size), + backgroundColor = getBackgroundColor(), + verticalArrangement = getVerticalArrangement(), + shape = getShape(), + ) + + @Composable + private fun getContentPadding(size: MenuSize): PaddingValues = + PaddingValues( + when (size) { + MenuSize.SMALL -> PrezelTheme.spacing.V4 + MenuSize.REGULAR -> PrezelTheme.spacing.V6 + }, + ) + + @Composable + private fun getBackgroundColor(): Color = PrezelTheme.colors.bgRegular + + @Composable + private fun getVerticalArrangement(): Arrangement.Vertical = Arrangement.spacedBy(PrezelTheme.spacing.V4) + + @Composable + private fun getShape(): RoundedCornerShape = PrezelTheme.shapes.V12 +} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuItem.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuItem.kt new file mode 100644 index 0000000..a1f281f --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuItem.kt @@ -0,0 +1,108 @@ +package com.team.prezel.core.designsystem.component.actions.button.floating.menu + +import androidx.annotation.DrawableRes +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +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.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp +import com.team.prezel.core.designsystem.component.base.PrezelTouchArea +import com.team.prezel.core.designsystem.icon.PrezelIcons +import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.theme.PrezelTheme +import com.team.prezel.core.designsystem.util.drawDashBorder + +@Composable +internal fun PrezelMenuItem( + label: String, + @DrawableRes iconResId: Int, + modifier: Modifier = Modifier, + size: MenuItemSize = MenuItemSize.REGULAR, + config: PrezelMenuItemDefault = PrezelMenuItemDefaults.getDefault(size), + onClick: () -> Unit, +) { + PrezelTouchArea( + modifier = modifier, + onClick = onClick, + shape = config.shape, + extraTouchPadding = config.contentPadding, + ) { + PrezelMenuItemLayout( + label = label, + iconResId = iconResId, + config = config, + ) + } +} + +@Composable +private fun PrezelMenuItemLayout( + label: String, + @DrawableRes iconResId: Int, + config: PrezelMenuItemDefault, + modifier: Modifier = Modifier, +) { + Row( + modifier = modifier, + verticalAlignment = Alignment.CenterVertically, + ) { + Icon( + painter = painterResource(id = iconResId), + contentDescription = null, + modifier = Modifier.size(config.iconSize), + tint = config.contentColor, + ) + + Spacer(modifier = Modifier.width(config.spacing)) + + Text( + text = label, + style = config.textStyle, + color = config.contentColor, + ) + } +} + +@ThemePreview +@Composable +private fun PrezelMenuMenuItemPreview() { + PrezelTheme { + Column(modifier = Modifier.padding(8.dp)) { + PrezelMenu( + size = MenuSize.REGULAR, + modifier = Modifier.drawDashBorder( + shape = PrezelMenuDefaults.getDefault(size = MenuSize.REGULAR).shape, + ), + ) { + MenuItem( + label = "Label", + iconResId = PrezelIcons.Blank, + onClick = {}, + ) + } + + PrezelMenu( + size = MenuSize.SMALL, + modifier = Modifier + .padding(top = 8.dp) + .drawDashBorder( + shape = PrezelMenuDefaults.getDefault(size = MenuSize.SMALL).shape, + ), + ) { + MenuItem( + label = "Label", + iconResId = PrezelIcons.Blank, + onClick = {}, + ) + } + } + } +} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuItemDefaults.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuItemDefaults.kt new file mode 100644 index 0000000..9ed44f5 --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuItemDefaults.kt @@ -0,0 +1,90 @@ +package com.team.prezel.core.designsystem.component.actions.button.floating.menu + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Immutable +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import com.team.prezel.core.designsystem.theme.PrezelTheme + +enum class MenuItemSize { + SMALL, + REGULAR, +} + +@Immutable +data class PrezelMenuItemDefault( + val iconSize: Dp, + val contentPadding: PaddingValues, + val spacing: Dp, + val textStyle: TextStyle, + val contentColor: Color, + val shape: RoundedCornerShape, +) + +object PrezelMenuItemDefaults { + @Composable + fun getDefault(size: MenuItemSize): PrezelMenuItemDefault = + PrezelMenuItemDefault( + iconSize = getIconSize(size), + contentPadding = getContentPadding(size), + spacing = getSpacing(size), + textStyle = getTextStyle(size), + contentColor = getContentColor(), + shape = getShape(), + ) + + private fun getIconSize(size: MenuItemSize): Dp = + when (size) { + MenuItemSize.SMALL -> 16.dp + MenuItemSize.REGULAR -> 20.dp + } + + @Composable + private fun getContentPadding(size: MenuItemSize): PaddingValues { + val verticalPadding = when (size) { + MenuItemSize.SMALL -> PrezelTheme.spacing.V4 + MenuItemSize.REGULAR -> PrezelTheme.spacing.V8 + } + + val startPadding = when (size) { + MenuItemSize.SMALL -> PrezelTheme.spacing.V8 + MenuItemSize.REGULAR -> PrezelTheme.spacing.V12 + } + + val endPadding = when (size) { + MenuItemSize.SMALL -> PrezelTheme.spacing.V10 + MenuItemSize.REGULAR -> PrezelTheme.spacing.V16 + } + + return PaddingValues( + start = startPadding, + end = endPadding, + top = verticalPadding, + bottom = verticalPadding, + ) + } + + @Composable + private fun getSpacing(size: MenuItemSize): Dp = + when (size) { + MenuItemSize.SMALL -> PrezelTheme.spacing.V4 + MenuItemSize.REGULAR -> PrezelTheme.spacing.V8 + } + + @Composable + private fun getTextStyle(size: MenuItemSize): TextStyle = + when (size) { + MenuItemSize.SMALL -> PrezelTheme.typography.body3Regular + MenuItemSize.REGULAR -> PrezelTheme.typography.body2Regular + } + + @Composable + private fun getContentColor(): Color = PrezelTheme.colors.textMedium + + @Composable + private fun getShape(): RoundedCornerShape = PrezelTheme.shapes.V8 +} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuScope.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuScope.kt new file mode 100644 index 0000000..94277a0 --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuScope.kt @@ -0,0 +1,41 @@ +package com.team.prezel.core.designsystem.component.actions.button.floating.menu + +import androidx.annotation.DrawableRes +import androidx.compose.foundation.layout.LayoutScopeMarker +import androidx.compose.runtime.Composable + +@LayoutScopeMarker +interface PrezelMenuScope { + val menuSize: MenuSize + val itemSize: MenuItemSize + + @Composable + fun MenuItem( + label: String, + @DrawableRes iconResId: Int, + onClick: () -> Unit, + ) +} + +internal class DefaultPrezelMenuScope( + override val menuSize: MenuSize, +) : PrezelMenuScope { + override val itemSize: MenuItemSize = when (menuSize) { + MenuSize.SMALL -> MenuItemSize.SMALL + MenuSize.REGULAR -> MenuItemSize.REGULAR + } + + @Composable + override fun MenuItem( + label: String, + @DrawableRes iconResId: Int, + onClick: () -> Unit, + ) { + PrezelMenuItem( + label = label, + iconResId = iconResId, + size = itemSize, + onClick = onClick, + ) + } +} From 52e9373fcf34c738b099909e325f2d64cdc0a11d Mon Sep 17 00:00:00 2001 From: moondev03 Date: Tue, 24 Mar 2026 18:15:31 +0900 Subject: [PATCH 15/42] =?UTF-8?q?feat:=20PrezelHyperlinkButton=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../component/actions/button/PrezelButton.kt | 9 +-- .../actions/button/PrezelHyperlinkButton.kt | 73 ++++++++++++++++++ .../actions/button/PrezelIconButton.kt | 8 +- .../actions/button/PrezelTextButton.kt | 10 +-- .../actions/button/config/PrezelButtonBase.kt | 60 ++++++++------- .../button/config/PrezelButtonDefaults.kt | 75 ++++++++++++------- .../button/config/PrezelButtonPreview.kt | 31 ++++---- 7 files changed, 181 insertions(+), 85 deletions(-) create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelHyperlinkButton.kt diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButton.kt index 207dbd9..fb98e3a 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButton.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButton.kt @@ -24,22 +24,22 @@ fun PrezelButton( hierarchy: ButtonHierarchy = ButtonHierarchy.PRIMARY, enabled: Boolean = true, isRounded: Boolean = false, - buttonDefault: PrezelButtonDefault = PrezelButtonDefaults.getDefault( + config: PrezelButtonDefault = PrezelButtonDefaults.getDefault( isIconOnly = false, isRounded = isRounded, type = type, size = size, hierarchy = hierarchy, - enabled = enabled, ), onClick: () -> Unit, ) { PrezelButtonBase( text = text, iconResId = iconResId, - modifier = modifier, + enabled = enabled, onClick = onClick, - buttonDefault = buttonDefault, + modifier = modifier, + config = config, ) } @@ -60,7 +60,6 @@ private fun PrezelButtonPreview() { type = type, hierarchy = hierarchy, size = size, - enabled = enabled, isRounded = isRounded, isIconOnly = false, ), diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelHyperlinkButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelHyperlinkButton.kt new file mode 100644 index 0000000..dd46c1e --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelHyperlinkButton.kt @@ -0,0 +1,73 @@ +package com.team.prezel.core.designsystem.component.actions.button + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.drawBehind +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.unit.dp +import com.team.prezel.core.designsystem.component.actions.button.config.ButtonHierarchy +import com.team.prezel.core.designsystem.component.actions.button.config.ButtonSize +import com.team.prezel.core.designsystem.component.actions.button.config.ButtonType +import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonBase +import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefault +import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefaults +import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.theme.PrezelTheme + +@Composable +fun PrezelHyperlinkButton( + text: String, + onClick: () -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + size: ButtonSize = ButtonSize.XSMALL, + config: PrezelButtonDefault = PrezelButtonDefaults.getDefault( + isIconOnly = false, + isRounded = false, + size = size, + type = ButtonType.GHOST, + hierarchy = ButtonHierarchy.SECONDARY, + ), +) { + PrezelButtonBase( + text = text, + iconResId = null, + onClick = onClick, + enabled = enabled, + modifier = modifier, + layoutModifier = Modifier.prezelButtonUnderline(), + config = config, + ) +} + +@Composable +private fun Modifier.prezelButtonUnderline(): Modifier { + val underlineThickness = with(LocalDensity.current) { 1.dp.toPx() } + val underlineColor = PrezelTheme.colors.borderLarge + + return this.drawBehind { + val y = size.height - (underlineThickness / 2) + drawLine( + color = underlineColor, + start = Offset(0f, y), + end = Offset(size.width, y), + strokeWidth = underlineThickness, + ) + } +} + +@ThemePreview +@Composable +private fun PrezelHyperlinkButtonPreview() { + PrezelTheme { + Box(modifier = Modifier.padding(8.dp)) { + PrezelHyperlinkButton( + text = "자세히 보기", + onClick = {}, + ) + } + } +} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelIconButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelIconButton.kt index 13c81c2..89402f1 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelIconButton.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelIconButton.kt @@ -29,15 +29,16 @@ fun PrezelIconButton( type = type, size = size, hierarchy = hierarchy, - enabled = enabled, ), onClick: () -> Unit, ) { PrezelButtonBase( + text = null, iconResId = iconResId, - modifier = modifier, + enabled = enabled, onClick = onClick, - buttonDefault = buttonDefault, + modifier = modifier, + config = buttonDefault, ) } @@ -57,7 +58,6 @@ private fun PrezelIconButtonPreview() { type = type, hierarchy = hierarchy, size = size, - enabled = enabled, isRounded = isRounded, isIconOnly = true, ), diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelTextButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelTextButton.kt index 3db3523..a99d0d4 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelTextButton.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelTextButton.kt @@ -21,21 +21,22 @@ fun PrezelTextButton( hierarchy: ButtonHierarchy = ButtonHierarchy.PRIMARY, enabled: Boolean = true, isRounded: Boolean = false, - buttonDefault: PrezelButtonDefault = PrezelButtonDefaults.getDefault( + config: PrezelButtonDefault = PrezelButtonDefaults.getDefault( isIconOnly = false, isRounded = isRounded, type = type, size = size, hierarchy = hierarchy, - enabled = enabled, ), onClick: () -> Unit, ) { PrezelButtonBase( text = text, - modifier = modifier, + iconResId = null, onClick = onClick, - buttonDefault = buttonDefault, + enabled = enabled, + modifier = modifier, + config = config, ) } @@ -55,7 +56,6 @@ private fun PrezelTextButtonPreview() { type = type, hierarchy = hierarchy, size = size, - enabled = enabled, isRounded = isRounded, isIconOnly = false, ), diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonBase.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonBase.kt index 3ec56f2..2730d7e 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonBase.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonBase.kt @@ -23,23 +23,26 @@ import com.team.prezel.core.designsystem.component.base.PrezelTouchArea @Composable internal fun PrezelButtonBase( + text: String?, + @DrawableRes iconResId: Int?, + enabled: Boolean, onClick: () -> Unit, - buttonDefault: PrezelButtonDefault, + config: PrezelButtonDefault, modifier: Modifier = Modifier, - text: String? = null, - @DrawableRes iconResId: Int? = null, + layoutModifier: Modifier = Modifier, + isUseRipple: Boolean = true, ) { PrezelTouchArea( - modifier = modifier.buttonContainer(buttonDefault), - extraTouchPadding = buttonDefault.contentPadding, + modifier = modifier.buttonContainer(enabled = enabled, config = config), + extraTouchPadding = config.contentPadding, onClick = onClick, - enabled = buttonDefault.enabled, - shape = buttonDefault.shape, - isUseRipple = true, + enabled = enabled, + shape = config.shape, + isUseRipple = isUseRipple, ) { ButtonContentLayout( - modifier = Modifier, - horizontalArrangement = buttonDefault.contentArrangement( + modifier = layoutModifier, + horizontalArrangement = config.contentArrangement( hasText = text != null, hasIcon = iconResId != null, ), @@ -47,7 +50,8 @@ internal fun PrezelButtonBase( { ButtonLabel( text = buttonText, - buttonDefault = buttonDefault, + enabled = enabled, + config = config, ) } }, @@ -55,7 +59,8 @@ internal fun PrezelButtonBase( { ButtonLeadingIcon( drawableRes = drawableRes, - buttonDefault = buttonDefault, + enabled = enabled, + config = config, ) } }, @@ -95,12 +100,13 @@ private fun ButtonContentLayout( @Composable private fun ButtonLabel( text: String, - buttonDefault: PrezelButtonDefault, + enabled: Boolean, + config: PrezelButtonDefault, ) { Text( text = text, - style = buttonDefault.textStyle, - color = buttonDefault.contentColor, + style = config.textStyle, + color = config.contentColor(enabled = enabled), maxLines = 1, overflow = TextOverflow.Ellipsis, textAlign = TextAlign.Center, @@ -110,13 +116,14 @@ private fun ButtonLabel( @Composable private fun ButtonLeadingIcon( @DrawableRes drawableRes: Int, - buttonDefault: PrezelButtonDefault, + enabled: Boolean, + config: PrezelButtonDefault, ) { Image( - modifier = Modifier.size(buttonDefault.iconSize), + modifier = Modifier.size(config.iconSize), painter = painterResource(id = drawableRes), contentScale = ContentScale.FillHeight, - colorFilter = ColorFilter.tint(color = buttonDefault.contentColor), + colorFilter = ColorFilter.tint(color = config.contentColor(enabled = enabled)), contentDescription = null, ) } @@ -126,16 +133,19 @@ private fun PrezelButtonDefault.contentArrangement( hasIcon: Boolean, ): Arrangement.Horizontal = if (hasText && hasIcon) Arrangement.spacedBy(iconSpacing) else Arrangement.Center -private fun Modifier.buttonContainer(buttonDefault: PrezelButtonDefault): Modifier = +private fun Modifier.buttonContainer( + enabled: Boolean, + config: PrezelButtonDefault, +): Modifier = this - .clip(shape = buttonDefault.shape) - .background(color = buttonDefault.backgroundColor) + .clip(shape = config.shape) + .background(color = config.backgroundColor(enabled = enabled)) .then( - if (buttonDefault.hasBorder) { + if (config.hasBorder) { Modifier.border( - width = buttonDefault.borderWidth, - color = buttonDefault.borderColor, - shape = buttonDefault.shape, + width = config.borderWidth, + color = config.borderColor(enabled = enabled), + shape = config.shape, ) } else { Modifier diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonDefaults.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonDefaults.kt index bab1a03..e3851fb 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonDefaults.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonDefaults.kt @@ -13,13 +13,12 @@ import com.team.prezel.core.designsystem.theme.PrezelTheme @Immutable data class PrezelButtonDefault( - val type: ButtonType, - val size: ButtonSize, - val hierarchy: ButtonHierarchy, - val enabled: Boolean, - val contentColor: Color, - val backgroundColor: Color, - val borderColor: Color, + private val contentColor: Color, + private val disabledContentColor: Color, + private val backgroundColor: Color, + private val disabledBackgroundColor: Color, + private val borderColor: Color, + private val disabledBorderColor: Color, val borderWidth: Dp, val shape: RoundedCornerShape, val textStyle: TextStyle, @@ -28,20 +27,28 @@ data class PrezelButtonDefault( val iconSize: Dp, ) { val hasBorder: Boolean = borderWidth > 0.dp + + fun contentColor(enabled: Boolean): Color = if (enabled) contentColor else disabledContentColor + + fun backgroundColor(enabled: Boolean): Color = if (enabled) backgroundColor else disabledBackgroundColor + + fun borderColor(enabled: Boolean): Color = if (enabled) borderColor else disabledBorderColor } object PrezelButtonDefaults { @Composable fun getDefault( isIconOnly: Boolean, - type: ButtonType = ButtonType.FILLED, - size: ButtonSize = ButtonSize.REGULAR, - hierarchy: ButtonHierarchy = ButtonHierarchy.PRIMARY, - enabled: Boolean = true, - isRounded: Boolean = false, - contentColor: Color = getContentColor(type = type, hierarchy = hierarchy, enabled = enabled), - backgroundColor: Color = getBackgroundColor(type = type, hierarchy = hierarchy, enabled = enabled), - borderColor: Color = getBorderColor(type = type, hierarchy = hierarchy, enabled = enabled), + type: ButtonType, + size: ButtonSize, + hierarchy: ButtonHierarchy, + isRounded: Boolean, + contentColor: Color = getContentColor(type = type, hierarchy = hierarchy), + disabledContentColor: Color = getDisabledContentColor(), + backgroundColor: Color = getBackgroundColor(type = type, hierarchy = hierarchy), + disabledBackgroundColor: Color = getDisabledBackgroundColor(type = type), + borderColor: Color = getBorderColor(type = type, hierarchy = hierarchy), + disabledBorderColor: Color = getDisabledBorderColor(type = type), borderWidth: Dp = getBorderWidth(type = type), shape: RoundedCornerShape = getShape(isRounded = isRounded, isIconOnly = isIconOnly, size = size), textStyle: TextStyle = getTextStyle(size = size), @@ -49,13 +56,12 @@ object PrezelButtonDefaults { iconSpacing: Dp = getIconSpacing(size = size), iconSize: Dp = getIconSize(size = size), ) = PrezelButtonDefault( - type = type, - size = size, - hierarchy = hierarchy, - enabled = enabled, contentColor = contentColor, + disabledContentColor = disabledContentColor, backgroundColor = backgroundColor, + disabledBackgroundColor = disabledBackgroundColor, borderColor = borderColor, + disabledBorderColor = disabledBorderColor, borderWidth = borderWidth, shape = shape, textStyle = textStyle, @@ -68,9 +74,7 @@ object PrezelButtonDefaults { private fun getContentColor( type: ButtonType, hierarchy: ButtonHierarchy, - enabled: Boolean, ): Color { - if (!enabled) return PrezelTheme.colors.textDisabled if (hierarchy == ButtonHierarchy.SECONDARY) return PrezelTheme.colors.textMedium return when (type) { @@ -81,11 +85,13 @@ object PrezelButtonDefaults { } } + @Composable + private fun getDisabledContentColor(): Color = PrezelTheme.colors.textDisabled + @Composable private fun getBackgroundColor( type: ButtonType, hierarchy: ButtonHierarchy, - enabled: Boolean, ): Color = when (type) { ButtonType.OUTLINED, @@ -93,22 +99,26 @@ object PrezelButtonDefaults { -> Color.Transparent ButtonType.FILLED -> { - if (!enabled || hierarchy == ButtonHierarchy.SECONDARY) { - PrezelTheme.colors.bgLarge - } else { - PrezelTheme.colors.interactiveRegular - } + if (hierarchy == ButtonHierarchy.SECONDARY) PrezelTheme.colors.bgLarge else PrezelTheme.colors.interactiveRegular } } + @Composable + private fun getDisabledBackgroundColor(type: ButtonType): Color = + when (type) { + ButtonType.OUTLINED, + ButtonType.GHOST, + -> Color.Transparent + + ButtonType.FILLED -> PrezelTheme.colors.bgLarge + } + @Composable private fun getBorderColor( type: ButtonType, hierarchy: ButtonHierarchy, - enabled: Boolean, ): Color { if (type != ButtonType.OUTLINED) return Color.Transparent - if (!enabled) return PrezelTheme.colors.borderDisabled return when (hierarchy) { ButtonHierarchy.PRIMARY -> PrezelTheme.colors.interactiveRegular @@ -116,6 +126,13 @@ object PrezelButtonDefaults { } } + @Composable + private fun getDisabledBorderColor(type: ButtonType): Color { + if (type != ButtonType.OUTLINED) return Color.Transparent + + return PrezelTheme.colors.borderDisabled + } + @Composable private fun getBorderWidth(type: ButtonType): Dp = if (type == ButtonType.OUTLINED) PrezelTheme.stroke.V1 else 0.dp diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonPreview.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonPreview.kt index 0b34e39..1738870 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonPreview.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonPreview.kt @@ -72,25 +72,22 @@ internal fun Modifier.previewGhostBorder( type: ButtonType, hierarchy: ButtonHierarchy, size: ButtonSize, - enabled: Boolean, isRounded: Boolean, isIconOnly: Boolean, -): Modifier = - if (type == ButtonType.GHOST) { - this.drawDashBorder( - shape = PrezelButtonDefaults - .getDefault( - isIconOnly = isIconOnly, - isRounded = isRounded, - type = type, - size = size, - hierarchy = hierarchy, - enabled = enabled, - ).shape, - ) - } else { - Modifier - } +): Modifier { + if (type != ButtonType.GHOST) return this + + return this.drawDashBorder( + shape = PrezelButtonDefaults + .getDefault( + isIconOnly = isIconOnly, + isRounded = isRounded, + type = type, + size = size, + hierarchy = hierarchy, + ).shape, + ) +} @Composable private fun ButtonPreviewSection( From 55a5f4506dd309758e22859d057d69756eef0681 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Tue, 24 Mar 2026 20:54:13 +0900 Subject: [PATCH 16/42] =?UTF-8?q?refactor:=20PrezelButtonArea=20=EA=B5=AC?= =?UTF-8?q?=EC=A1=B0=20=EA=B0=9C=EC=84=A0=20=EB=B0=8F=20DSL=20=EA=B8=B0?= =?UTF-8?q?=EB=B0=98=20ButtonAreaScope=20=EB=8F=84=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../component/actions/area/ButtonAreaScope.kt | 108 +++++++++++++ .../actions/area/PrezelButtonArea.kt | 145 +++++------------- .../actions/area/PrezelButtonAreaDefaults.kt | 24 ++- 3 files changed, 159 insertions(+), 118 deletions(-) create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/ButtonAreaScope.kt diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/ButtonAreaScope.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/ButtonAreaScope.kt new file mode 100644 index 0000000..2844a41 --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/ButtonAreaScope.kt @@ -0,0 +1,108 @@ +package com.team.prezel.core.designsystem.component.actions.area + +import androidx.annotation.DrawableRes +import androidx.compose.foundation.layout.LayoutScopeMarker +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.team.prezel.core.designsystem.component.actions.button.PrezelButton +import com.team.prezel.core.designsystem.component.actions.button.config.ButtonHierarchy +import com.team.prezel.core.designsystem.component.actions.button.config.ButtonType +import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefault + +@LayoutScopeMarker +@Suppress("FunctionName") +interface ButtonAreaScope { + fun MainButton( + @DrawableRes iconResId: Int? = null, + label: String, + enabled: Boolean = true, + onClick: () -> Unit, + ) + + fun SubButton( + @DrawableRes iconResId: Int? = null, + label: String, + enabled: Boolean = true, + onClick: () -> Unit, + ) + + fun CustomButton( + @DrawableRes iconResId: Int? = null, + label: String, + enabled: Boolean, + onClick: () -> Unit, + config: PrezelButtonDefault, + ) +} + +internal class DefaultButtonAreaScope : ButtonAreaScope { + private val _buttons = mutableListOf<@Composable (Modifier) -> Unit>() + internal val buttons: List<@Composable (Modifier) -> Unit> get() = _buttons.toList() + + override fun MainButton( + @DrawableRes iconResId: Int?, + label: String, + enabled: Boolean, + onClick: () -> Unit, + ) { + validateButtonCount() + + _buttons += { modifier -> + PrezelButton( + modifier = modifier, + text = label, + iconResId = iconResId, + onClick = onClick, + enabled = enabled, + type = ButtonType.FILLED, + hierarchy = ButtonHierarchy.PRIMARY, + ) + } + } + + override fun SubButton( + @DrawableRes iconResId: Int?, + label: String, + enabled: Boolean, + onClick: () -> Unit, + ) { + validateButtonCount() + + _buttons += { modifier -> + PrezelButton( + modifier = modifier, + text = label, + iconResId = iconResId, + onClick = onClick, + enabled = enabled, + type = ButtonType.FILLED, + hierarchy = ButtonHierarchy.SECONDARY, + ) + } + } + + override fun CustomButton( + @DrawableRes iconResId: Int?, + label: String, + enabled: Boolean, + onClick: () -> Unit, + config: PrezelButtonDefault, + ) { + validateButtonCount() + + _buttons += { modifier -> + PrezelButton( + modifier = modifier, + text = label, + iconResId = iconResId, + onClick = onClick, + enabled = enabled, + config = config, + ) + } + } + + private fun validateButtonCount() { + require(buttons.size <= 2) { "버튼은 최대 2개까지 선언할 수 있습니다." } + } +} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonArea.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonArea.kt index ba7022b..3d062f7 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonArea.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonArea.kt @@ -1,6 +1,5 @@ package com.team.prezel.core.designsystem.component.actions.area -import androidx.annotation.DrawableRes import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.layout.Arrangement @@ -16,7 +15,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.Immutable +import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -25,58 +24,46 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.component.PrezelDividerType import com.team.prezel.core.designsystem.component.PrezelHorizontalDivider -import com.team.prezel.core.designsystem.component.actions.button.PrezelButton -import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefault -import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefaults import com.team.prezel.core.designsystem.icon.PrezelIcons import com.team.prezel.core.designsystem.preview.PreviewScaffold import com.team.prezel.core.designsystem.preview.SectionTitle import com.team.prezel.core.designsystem.theme.PrezelTheme -@Immutable -data class ButtonAreaButtonSpec( - @param:DrawableRes val iconResId: Int? = null, - val label: String, - val enabled: Boolean = true, - val onClick: () -> Unit, -) - @Composable fun PrezelButtonArea( - mainButton: ButtonAreaButtonSpec, modifier: Modifier = Modifier, - subButton: ButtonAreaButtonSpec? = null, isVertical: Boolean = true, - showBackground: Boolean = false, isStrongStrength: Boolean = true, + showBackground: Boolean = false, isNested: Boolean = false, config: PrezelButtonAreaDefault = PrezelButtonAreaDefaults.getDefault( showBackground = showBackground, isNested = isNested, ), + content: @Composable ButtonAreaScope.() -> Unit, ) { - Column(modifier = modifier) { - if (showBackground) PrezelHorizontalDivider(type = PrezelDividerType.THICK) + val scope = remember { DefaultButtonAreaScope() } + scope.content() - val contentModifier = Modifier - .background(config.backgroundColor) - .padding(config.contentPadding) + Column( + modifier = modifier .fillMaxWidth() + .background(config.backgroundColor), + ) { + PrezelHorizontalDivider(type = PrezelDividerType.THICK, color = config.borderColor) if (isVertical) { ButtonAreaVertical( - modifier = contentModifier, - mainButton = mainButton, - subButton = subButton, - buttonAreaDefault = config, + mainButton = scope.buttons[0], + subButton = scope.buttons[1], + modifier = Modifier.padding(config.contentPadding), ) } else { ButtonAreaHorizontal( - modifier = contentModifier, isStrongStrength = isStrongStrength, - mainButton = mainButton, - subButton = subButton, - buttonAreaDefault = config, + mainButton = scope.buttons[0], + subButton = scope.buttons[1], + modifier = Modifier.padding(config.contentPadding), ) } } @@ -84,92 +71,37 @@ fun PrezelButtonArea( @Composable private fun ButtonAreaVertical( - modifier: Modifier, - mainButton: ButtonAreaButtonSpec, - subButton: ButtonAreaButtonSpec?, - buttonAreaDefault: PrezelButtonAreaDefault, + mainButton: @Composable (Modifier) -> Unit, + subButton: @Composable ((Modifier) -> Unit)?, + modifier: Modifier = Modifier, ) { Column(modifier = modifier) { - PrezelButton( - modifier = Modifier.fillMaxWidth(), - text = mainButton.label, - iconResId = mainButton.iconResId, - onClick = mainButton.onClick, - enabled = mainButton.enabled, - buttonDefault = buttonAreaDefault.mainButtonDefault.applyEnabled(mainButton.enabled), - ) + mainButton(Modifier.fillMaxWidth()) if (subButton != null) { Spacer(modifier = Modifier.height(PrezelTheme.spacing.V12)) - PrezelButton( - modifier = Modifier.fillMaxWidth(), - text = subButton.label, - iconResId = subButton.iconResId, - onClick = subButton.onClick, - enabled = subButton.enabled, - buttonDefault = buttonAreaDefault.subButtonDefault.applyEnabled(subButton.enabled), - ) + subButton(Modifier.fillMaxWidth()) } } } @Composable private fun ButtonAreaHorizontal( - modifier: Modifier, - mainButton: ButtonAreaButtonSpec, - subButton: ButtonAreaButtonSpec?, isStrongStrength: Boolean, - buttonAreaDefault: PrezelButtonAreaDefault, + mainButton: @Composable (Modifier) -> Unit, + subButton: @Composable ((Modifier) -> Unit)?, + modifier: Modifier = Modifier, ) { Row(modifier = modifier) { if (subButton != null) { - PrezelButton( - modifier = if (isStrongStrength) Modifier else Modifier.weight(1f), - text = subButton.label, - iconResId = subButton.iconResId, - onClick = subButton.onClick, - enabled = subButton.enabled, - buttonDefault = buttonAreaDefault.subButtonDefault.applyEnabled(subButton.enabled), - ) + subButton(if (isStrongStrength) Modifier else Modifier.weight(1f)) Spacer(modifier = Modifier.width(PrezelTheme.spacing.V12)) } - PrezelButton( - modifier = Modifier.weight(1f), - text = mainButton.label, - iconResId = mainButton.iconResId, - onClick = mainButton.onClick, - enabled = mainButton.enabled, - buttonDefault = buttonAreaDefault.mainButtonDefault.applyEnabled(mainButton.enabled), - ) + mainButton(Modifier.weight(1f)) } } -@Composable -private fun PrezelButtonDefault.applyEnabled(enabled: Boolean): PrezelButtonDefault { - if (this.enabled == enabled) return this - - val resolvedStateDefault = PrezelButtonDefaults.getDefault( - isIconOnly = false, - type = type, - size = size, - hierarchy = hierarchy, - enabled = enabled, - ) - - return copy( - contentColor = resolvedStateDefault.contentColor, - backgroundColor = resolvedStateDefault.backgroundColor, - borderColor = resolvedStateDefault.borderColor, - borderWidth = resolvedStateDefault.borderWidth, - shape = resolvedStateDefault.shape, - textStyle = resolvedStateDefault.textStyle, - contentPadding = resolvedStateDefault.contentPadding, - iconSpacing = resolvedStateDefault.iconSpacing, - iconSize = resolvedStateDefault.iconSize, - ) -} - private data class ButtonAreaPreviewVariant( val title: String, val isVertical: Boolean, @@ -302,21 +234,26 @@ private fun ButtonAreaPreviewSample( enabled: Boolean, showBackground: Boolean, ) { - val button = ButtonAreaButtonSpec( - label = "Label", - iconResId = PrezelIcons.Blank, - enabled = enabled, - onClick = {}, - ) - PrezelButtonArea( modifier = Modifier.fillMaxWidth(), isVertical = variant.isVertical, isStrongStrength = variant.isStrongStrength, showBackground = showBackground, - mainButton = button, - subButton = button, - ) + ) { + MainButton( + iconResId = PrezelIcons.Blank, + label = "Label", + enabled = enabled, + onClick = {}, + ) + + SubButton( + iconResId = PrezelIcons.Blank, + label = "Label", + enabled = enabled, + onClick = {}, + ) + } } @Composable diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonAreaDefaults.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonAreaDefaults.kt index 2db07b8..c6091a7 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonAreaDefaults.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonAreaDefaults.kt @@ -4,40 +4,36 @@ import androidx.compose.foundation.layout.PaddingValues import androidx.compose.runtime.Composable import androidx.compose.runtime.Immutable import androidx.compose.ui.graphics.Color -import com.team.prezel.core.designsystem.component.actions.button.config.ButtonHierarchy -import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefault -import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefaults import com.team.prezel.core.designsystem.theme.PrezelTheme @Immutable data class PrezelButtonAreaDefault( - val mainButtonDefault: PrezelButtonDefault, - val subButtonDefault: PrezelButtonDefault, val backgroundColor: Color, + val borderColor: Color, val contentPadding: PaddingValues, ) object PrezelButtonAreaDefaults { @Composable fun getDefault( - mainButtonDefault: PrezelButtonDefault = PrezelButtonDefaults.getDefault(isIconOnly = false), - subButtonDefault: PrezelButtonDefault = PrezelButtonDefaults.getDefault( - isIconOnly = false, - hierarchy = ButtonHierarchy.SECONDARY, - ), showBackground: Boolean = false, isNested: Boolean = false, + backgroundColor: Color = getBackgroundColor(showBackground = showBackground), + borderColor: Color = getBorderColor(showBackground = showBackground), + contentPadding: PaddingValues = getContentPadding(isNested = isNested), ): PrezelButtonAreaDefault = PrezelButtonAreaDefault( - mainButtonDefault = mainButtonDefault, - subButtonDefault = subButtonDefault, - backgroundColor = getBackgroundColor(showBackground = showBackground), - contentPadding = getContentPadding(isNested = isNested), + backgroundColor = backgroundColor, + borderColor = borderColor, + contentPadding = contentPadding, ) @Composable private fun getBackgroundColor(showBackground: Boolean): Color = if (showBackground) PrezelTheme.colors.bgRegular else Color.Transparent + @Composable + private fun getBorderColor(showBackground: Boolean): Color = if (showBackground) PrezelTheme.colors.borderRegular else Color.Transparent + @Composable private fun getContentPadding(isNested: Boolean): PaddingValues = PaddingValues(if (isNested) PrezelTheme.spacing.V0 else PrezelTheme.spacing.V20) } From a849bd0cd4a318ebf6cd3c555a78495849a6466f Mon Sep 17 00:00:00 2001 From: moondev03 Date: Tue, 24 Mar 2026 20:55:07 +0900 Subject: [PATCH 17/42] =?UTF-8?q?refactor:=20=EA=B8=B0=EC=A1=B4=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EB=B0=8F=20=ED=94=8C=EB=A1=9C=ED=8C=85=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EA=B4=80=EB=A0=A8=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=EB=93=A4=EC=9D=84=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../component/button/PrezelButton.kt | 151 ----------- .../component/button/PrezelButtonArea.kt | 190 -------------- .../component/button/PrezelButtonPreview.kt | 127 --------- .../component/button/PrezelButtonStyle.kt | 243 ------------------ .../component/button/PrezelHyperlinkButton.kt | 42 --- .../component/button/PrezelIconButton.kt | 64 ----- .../component/button/PrezelTextButton.kt | 62 ----- .../button/floating/PrezelFloatingButton.kt | 79 ------ .../floating/PrezelFloatingButtonMenuItem.kt | 83 ------ .../PrezelFloatingButtonMenuItemStyle.kt | 64 ----- .../floating/PrezelFloatingButtonStyle.kt | 101 -------- .../floating/PrezelFloatingMenuButton.kt | 234 ----------------- 12 files changed, 1440 deletions(-) delete mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButton.kt delete mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonArea.kt delete mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonPreview.kt delete mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonStyle.kt delete mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelHyperlinkButton.kt delete mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelIconButton.kt delete mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelTextButton.kt delete mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/floating/PrezelFloatingButton.kt delete mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/floating/PrezelFloatingButtonMenuItem.kt delete mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/floating/PrezelFloatingButtonMenuItemStyle.kt delete mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/floating/PrezelFloatingButtonStyle.kt delete mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/floating/PrezelFloatingMenuButton.kt diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButton.kt deleted file mode 100644 index acd2cbf..0000000 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButton.kt +++ /dev/null @@ -1,151 +0,0 @@ -package com.team.prezel.core.designsystem.component.button - -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -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.LocalContentColor -import androidx.compose.material3.Text -import androidx.compose.material3.ripple -import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.drawBehind -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.semantics.Role -import androidx.compose.ui.unit.dp -import com.team.prezel.core.designsystem.icon.IconSource -import com.team.prezel.core.designsystem.icon.PrezelIcons -import com.team.prezel.core.designsystem.preview.ThemePreview -import com.team.prezel.core.designsystem.theme.PrezelTheme - -@Composable -fun PrezelButton( - onClick: () -> Unit, - modifier: Modifier = Modifier, - text: String? = null, - icon: IconSource? = null, - enabled: Boolean = true, - style: PrezelButtonStyle = PrezelButtonStyle(), -) { - require(text != null || icon != null) { "버튼은 텍스트 또는 아이콘 중 하나는 반드시 필요합니다." } - val appearance = PrezelButtonAppearance.of(style = style, isIconOnly = text == null, enabled = enabled) - - Box( - modifier = modifier - .applyButtonAppearance(appearance) - .clickable( - enabled = enabled, - onClick = onClick, - role = Role.Button, - indication = ripple(), - interactionSource = null, - ), - contentAlignment = Alignment.Center, - ) { - PrezelButtonContent( - text = text, - icon = icon, - showUnderline = style.showUnderline, - appearance = appearance, - ) - } -} - -@Composable -private fun PrezelButtonContent( - text: String?, - icon: IconSource?, - showUnderline: Boolean, - appearance: PrezelButtonAppearance, -) { - CompositionLocalProvider(LocalContentColor provides appearance.contentColor) { - Row( - modifier = Modifier.padding(appearance.contentPadding), - horizontalArrangement = Arrangement.Center, - verticalAlignment = Alignment.CenterVertically, - ) { - icon?.let { source -> - Icon( - painter = source.painter(), - contentDescription = source.contentDescription(), - modifier = Modifier.size(appearance.iconSize), - ) - } - - text?.let { label -> - if (icon != null) { - Spacer(modifier = Modifier.width(width = appearance.iconSpacing)) - } - Text( - text = label, - style = appearance.textStyle, - modifier = if (showUnderline) Modifier.prezelButtonUnderline() else Modifier, - ) - } - } - } -} - -@Composable -private fun Modifier.prezelButtonUnderline(): Modifier { - val underlineThickness = with(LocalDensity.current) { 1.dp.toPx() } - val underlineColor = PrezelTheme.colors.borderLarge - - return this.drawBehind { - val y = size.height - (underlineThickness / 2) - drawLine( - color = underlineColor, - start = Offset(0f, y), - end = Offset(size.width, y), - strokeWidth = underlineThickness, - ) - } -} - -@ThemePreview -@Composable -private fun PrezelButtonPreviewFilled() { - PrezelTheme { - PrezelButtonPreviewByType(type = PrezelButtonType.FILLED, content = ::PrezelButtonPreviewItem) - } -} - -@ThemePreview -@Composable -private fun PrezelButtonPreviewOutlined() { - PrezelTheme { - PrezelButtonPreviewByType(type = PrezelButtonType.OUTLINED, content = ::PrezelButtonPreviewItem) - } -} - -@ThemePreview -@Composable -private fun PrezelButtonPreviewGhost() { - PrezelTheme { - PrezelButtonPreviewByType(type = PrezelButtonType.GHOST, content = ::PrezelButtonPreviewItem) - } -} - -@Composable -private fun PrezelButtonPreviewItem( - style: PrezelButtonStyle, - enabled: Boolean, - modifier: Modifier = Modifier, -) { - PrezelButton( - text = "Label", - icon = IconSource(resId = PrezelIcons.Blank), - onClick = {}, - enabled = enabled, - style = style, - modifier = modifier, - ) -} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonArea.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonArea.kt deleted file mode 100644 index cd94db1..0000000 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonArea.kt +++ /dev/null @@ -1,190 +0,0 @@ -package com.team.prezel.core.designsystem.component.button - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -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.runtime.Composable -import androidx.compose.runtime.Immutable -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.unit.dp -import com.team.prezel.core.designsystem.component.PrezelDividerType -import com.team.prezel.core.designsystem.component.PrezelHorizontalDivider -import com.team.prezel.core.designsystem.icon.IconSource -import com.team.prezel.core.designsystem.icon.PrezelIcons -import com.team.prezel.core.designsystem.preview.SectionTitle -import com.team.prezel.core.designsystem.preview.ThemePreview -import com.team.prezel.core.designsystem.theme.PrezelTheme - -@Immutable -data class ButtonAreaButtonSpec( - val icon: IconSource? = null, - val label: String, - val enabled: Boolean = true, - val onClick: () -> Unit, -) - -@Composable -fun PrezelButtonArea( - mainButton: ButtonAreaButtonSpec, - subButton: ButtonAreaButtonSpec?, - modifier: Modifier = Modifier, - isVertical: Boolean = true, - showBackground: Boolean = false, - isStrongStrength: Boolean = true, - contentPadding: PaddingValues = PaddingValues(PrezelTheme.spacing.V20), -) { - Column(modifier = modifier) { - if (showBackground) PrezelHorizontalDivider(type = PrezelDividerType.THICK) - - val contentModifier = Modifier - .background(if (showBackground) PrezelTheme.colors.bgRegular else Color.Transparent) - .padding(contentPadding) - .fillMaxWidth() - - if (isVertical) { - ButtonAreaVertical( - modifier = contentModifier, - mainButton = mainButton, - subButton = subButton, - ) - } else { - ButtonAreaHorizontal( - modifier = contentModifier, - isStrongStrength = isStrongStrength, - mainButton = mainButton, - subButton = subButton, - ) - } - } -} - -@Composable -private fun ButtonAreaVertical( - modifier: Modifier, - mainButton: ButtonAreaButtonSpec, - subButton: ButtonAreaButtonSpec?, -) { - Column(modifier = modifier) { - PrezelButton( - modifier = Modifier.fillMaxWidth(), - text = mainButton.label, - icon = mainButton.icon, - onClick = mainButton.onClick, - enabled = mainButton.enabled, - style = PrezelButtonStyle(buttonHierarchy = PrezelButtonHierarchy.PRIMARY), - ) - - if (subButton != null) { - Spacer(modifier = Modifier.height(PrezelTheme.spacing.V12)) - PrezelButton( - modifier = Modifier.fillMaxWidth(), - text = subButton.label, - icon = subButton.icon, - onClick = subButton.onClick, - enabled = subButton.enabled, - style = PrezelButtonStyle(buttonHierarchy = PrezelButtonHierarchy.SECONDARY), - ) - } - } -} - -@Composable -private fun ButtonAreaHorizontal( - modifier: Modifier, - isStrongStrength: Boolean, - mainButton: ButtonAreaButtonSpec, - subButton: ButtonAreaButtonSpec?, -) { - Row(modifier = modifier) { - val mainModifier = Modifier.weight(1f) - val subModifier = if (isStrongStrength) Modifier else Modifier.weight(1f) - - if (subButton != null) { - PrezelButton( - modifier = subModifier, - text = subButton.label, - icon = subButton.icon, - onClick = subButton.onClick, - enabled = subButton.enabled, - style = PrezelButtonStyle(buttonHierarchy = PrezelButtonHierarchy.SECONDARY), - ) - Spacer(modifier = Modifier.width(PrezelTheme.spacing.V12)) - } - - PrezelButton( - modifier = mainModifier, - text = mainButton.label, - icon = mainButton.icon, - onClick = mainButton.onClick, - enabled = mainButton.enabled, - style = PrezelButtonStyle(buttonHierarchy = PrezelButtonHierarchy.PRIMARY), - ) - } -} - -@ThemePreview -@Composable -private fun PrezelButtonAreaVerticalPreview() { - PrezelButtonAreaTypedPreview(title = "Vertical", isVertical = true, isStrongStrength = true) -} - -@ThemePreview -@Composable -private fun PrezelButtonAreaHorizontalStrongPreview() { - PrezelButtonAreaTypedPreview(title = "Horizontal & Strong Strength", isVertical = false, isStrongStrength = true) -} - -@ThemePreview -@Composable -private fun PrezelButtonAreaHorizontalWeakPreview() { - PrezelButtonAreaTypedPreview(title = "Horizontal & Weak Strength", isVertical = false, isStrongStrength = false) -} - -@Composable -private fun PrezelButtonAreaTypedPreview( - title: String, - isVertical: Boolean, - isStrongStrength: Boolean, -) { - val mainButton = ButtonAreaButtonSpec( - label = "Main Button", - icon = IconSource(resId = PrezelIcons.Blank), - onClick = {}, - ) - val subButton = ButtonAreaButtonSpec( - label = "Sub", - icon = IconSource(resId = PrezelIcons.Blank), - onClick = {}, - ) - - PrezelTheme { - Column( - modifier = Modifier.background(PrezelTheme.colors.bgMedium), - verticalArrangement = Arrangement.spacedBy(8.dp), - ) { - SectionTitle(title = title) - PrezelButtonArea( - isVertical = isVertical, - isStrongStrength = isStrongStrength, - showBackground = false, - mainButton = mainButton, - subButton = subButton, - ) - PrezelButtonArea( - isVertical = isVertical, - isStrongStrength = isStrongStrength, - showBackground = true, - mainButton = mainButton, - subButton = subButton, - ) - } - } -} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonPreview.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonPreview.kt deleted file mode 100644 index 70d4fa7..0000000 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonPreview.kt +++ /dev/null @@ -1,127 +0,0 @@ -package com.team.prezel.core.designsystem.component.button - -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.material3.HorizontalDivider -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.Immutable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import com.team.prezel.core.designsystem.preview.PreviewScaffold -import com.team.prezel.core.designsystem.theme.PrezelTheme -import com.team.prezel.core.designsystem.util.drawDashBorder -import kotlinx.collections.immutable.persistentListOf - -internal typealias PrezelButtonPreviewContent = @Composable (style: PrezelButtonStyle, enabled: Boolean, contentModifier: Modifier) -> Unit - -@Immutable -private data class PreviewVariant( - val enabled: Boolean, - val isRounded: Boolean, -) - -private val PreviewVariants = persistentListOf( - PreviewVariant(enabled = true, isRounded = false), - PreviewVariant(enabled = true, isRounded = true), - PreviewVariant(enabled = false, isRounded = true), - PreviewVariant(enabled = false, isRounded = false), -) - -@Composable -internal fun PrezelButtonPreviewByType( - type: PrezelButtonType, - content: PrezelButtonPreviewContent, - isIconOnly: Boolean = false, -) { - PreviewScaffold { - Text(text = type.name, style = PrezelTheme.typography.title2Medium) - - PreviewVariants.forEach { variant -> - HorizontalDivider() - PrezelButtonVariantSection( - type = type, - enabled = variant.enabled, - isRounded = variant.isRounded, - isIconOnly = isIconOnly, - content = content, - ) - } - } -} - -@Composable -private fun PrezelButtonVariantSection( - type: PrezelButtonType, - enabled: Boolean, - isRounded: Boolean, - isIconOnly: Boolean, - content: PrezelButtonPreviewContent, - modifier: Modifier = Modifier, - contentModifier: Modifier = Modifier, -) { - Column( - modifier = modifier, - verticalArrangement = Arrangement.spacedBy(12.dp), - ) { - Text(text = "Hierarchy: Primary | Enabled: $enabled | Radius: $isRounded", style = PrezelTheme.typography.body3Medium) - PrezelButtonPreviewHierarchyBlock( - type = type, - hierarchy = PrezelButtonHierarchy.PRIMARY, - enabled = enabled, - isRounded = isRounded, - isIconOnly = isIconOnly, - content = content, - contentModifier = contentModifier, - ) - Text(text = "Hierarchy: Secondary | Enabled: $enabled | Radius: $isRounded", style = PrezelTheme.typography.body3Medium) - PrezelButtonPreviewHierarchyBlock( - type = type, - hierarchy = PrezelButtonHierarchy.SECONDARY, - enabled = enabled, - isRounded = isRounded, - isIconOnly = isIconOnly, - content = content, - contentModifier = contentModifier, - ) - } -} - -@Composable -private fun PrezelButtonPreviewHierarchyBlock( - type: PrezelButtonType, - hierarchy: PrezelButtonHierarchy, - enabled: Boolean, - isRounded: Boolean, - isIconOnly: Boolean, - content: PrezelButtonPreviewContent, - modifier: Modifier = Modifier, - contentModifier: Modifier = Modifier, -) { - Row( - modifier = modifier, - horizontalArrangement = Arrangement.spacedBy(8.dp), - verticalAlignment = Alignment.CenterVertically, - ) { - PrezelButtonSize.entries.forEach { size -> - val style = PrezelButtonStyle( - buttonType = type, - buttonHierarchy = hierarchy, - buttonSize = size, - isRounded = isRounded, - ) - val appearance = PrezelButtonAppearance.of(style = style, isIconOnly = isIconOnly, enabled = enabled) - - content( - style, - enabled, - contentModifier - .then( - if (type == PrezelButtonType.GHOST) Modifier.drawDashBorder(shape = appearance.shape) else Modifier, - ), - ) - } - } -} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonStyle.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonStyle.kt deleted file mode 100644 index 2f5d73a..0000000 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonStyle.kt +++ /dev/null @@ -1,243 +0,0 @@ -package com.team.prezel.core.designsystem.component.button - -import androidx.compose.foundation.BorderStroke -import androidx.compose.foundation.background -import androidx.compose.foundation.border -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.runtime.Composable -import androidx.compose.runtime.Immutable -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.text.TextStyle -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp -import com.team.prezel.core.designsystem.foundation.color.PrezelColors -import com.team.prezel.core.designsystem.foundation.number.PrezelShapes -import com.team.prezel.core.designsystem.foundation.number.PrezelSpacing -import com.team.prezel.core.designsystem.foundation.number.PrezelStroke -import com.team.prezel.core.designsystem.theme.PrezelColorScheme -import com.team.prezel.core.designsystem.theme.PrezelTheme - -enum class PrezelButtonType { - FILLED, - OUTLINED, - GHOST, -} - -enum class PrezelButtonHierarchy { - PRIMARY, - SECONDARY, -} - -enum class PrezelButtonSize { - XSMALL, - SMALL, - REGULAR, -} - -@Immutable -data class PrezelButtonStyle( - val buttonType: PrezelButtonType = PrezelButtonType.FILLED, - val buttonHierarchy: PrezelButtonHierarchy = PrezelButtonHierarchy.PRIMARY, - val buttonSize: PrezelButtonSize = PrezelButtonSize.REGULAR, - val isRounded: Boolean = false, - val showUnderline: Boolean = false, -) - -@Immutable -internal data class PrezelButtonAppearance( - val textStyle: TextStyle, - val contentColor: Color, - val contentPadding: PaddingValues, - val iconSpacing: Dp, - val shape: Shape, - val containerColor: Color, - val borderStroke: BorderStroke, - val iconSize: Dp, -) { - companion object { - @Composable - fun of( - style: PrezelButtonStyle, - isIconOnly: Boolean, - enabled: Boolean, - ): PrezelButtonAppearance = - PrezelButtonAppearance( - textStyle = prezelButtonTextStyle(size = style.buttonSize), - contentColor = prezelButtonContentColor( - type = style.buttonType, - hierarchy = style.buttonHierarchy, - enabled = enabled, - ), - contentPadding = prezelButtonContentPadding( - size = style.buttonSize, - isIconOnly = isIconOnly, - ), - iconSpacing = prezelButtonIconSpacing(size = style.buttonSize), - shape = prezelButtonShape( - isIconOnly = isIconOnly, - isRounded = style.isRounded, - buttonSize = style.buttonSize, - ), - containerColor = prezelButtonContainerColor( - type = style.buttonType, - hierarchy = style.buttonHierarchy, - enabled = enabled, - ), - borderStroke = prezelButtonBorderStroke( - type = style.buttonType, - hierarchy = style.buttonHierarchy, - enabled = enabled, - ), - iconSize = prezelButtonIconSize(size = style.buttonSize), - ) - } -} - -internal fun Modifier.applyButtonAppearance(appearance: PrezelButtonAppearance): Modifier = - this - .clip(appearance.shape) - .background(appearance.containerColor) - .border( - border = appearance.borderStroke, - shape = appearance.shape, - ) - -@Composable -private fun prezelButtonIconSpacing( - size: PrezelButtonSize, - spacing: PrezelSpacing = PrezelTheme.spacing, -): Dp = - when (size) { - PrezelButtonSize.XSMALL -> spacing.V4 - PrezelButtonSize.SMALL -> spacing.V4 - PrezelButtonSize.REGULAR -> spacing.V8 - } - -@Composable -private fun prezelButtonShape( - isIconOnly: Boolean, - isRounded: Boolean, - buttonSize: PrezelButtonSize, - shapes: PrezelShapes = PrezelTheme.shapes, -): Shape = - when (isRounded) { - true -> shapes.V1000 - false -> { - when (buttonSize) { - PrezelButtonSize.REGULAR -> shapes.V8 - PrezelButtonSize.SMALL -> if (isIconOnly) shapes.V6 else shapes.V4 - PrezelButtonSize.XSMALL -> shapes.V4 - } - } - } - -@Composable -private fun prezelButtonBorderStroke( - type: PrezelButtonType, - hierarchy: PrezelButtonHierarchy, - enabled: Boolean, - colors: PrezelColors = PrezelTheme.colors, - stroke: PrezelStroke = PrezelTheme.stroke, -): BorderStroke { - if (type != PrezelButtonType.OUTLINED) return BorderStroke(0.dp, Color.Transparent) - if (!enabled) return BorderStroke(width = stroke.V1, color = colors.borderDisabled) - - val borderColor = when (hierarchy) { - PrezelButtonHierarchy.PRIMARY -> colors.interactiveRegular - PrezelButtonHierarchy.SECONDARY -> colors.borderMedium - } - - return BorderStroke(width = stroke.V1, color = borderColor) -} - -@Composable -private fun prezelButtonTextStyle(size: PrezelButtonSize): TextStyle = - when (size) { - PrezelButtonSize.XSMALL -> PrezelTheme.typography.caption2Medium - PrezelButtonSize.SMALL -> PrezelTheme.typography.body3Medium - PrezelButtonSize.REGULAR -> PrezelTheme.typography.body2Bold - } - -@Composable -private fun prezelButtonContainerColor( - type: PrezelButtonType, - hierarchy: PrezelButtonHierarchy, - enabled: Boolean, - colors: PrezelColors = PrezelTheme.colors, -): Color = - when (type) { - PrezelButtonType.FILLED -> { - if (!enabled || hierarchy == PrezelButtonHierarchy.SECONDARY) { - colors.bgLarge - } else { - colors.interactiveRegular - } - } - - PrezelButtonType.OUTLINED -> Color.Transparent - PrezelButtonType.GHOST -> Color.Transparent - } - -@Composable -private fun prezelButtonContentColor( - type: PrezelButtonType, - hierarchy: PrezelButtonHierarchy, - enabled: Boolean, - colors: PrezelColors = PrezelTheme.colors, -): Color { - if (!enabled) return colors.textDisabled - if (hierarchy == PrezelButtonHierarchy.SECONDARY) return colors.textMedium - - return when (type) { - PrezelButtonType.FILLED -> PrezelColorScheme.Dark.textLarge - PrezelButtonType.OUTLINED -> colors.interactiveRegular - PrezelButtonType.GHOST -> colors.interactiveRegular - } -} - -@Composable -private fun prezelButtonContentPadding( - size: PrezelButtonSize, - isIconOnly: Boolean, - spacing: PrezelSpacing = PrezelTheme.spacing, -): PaddingValues { - if (isIconOnly) return prezelIconButtonContentPadding(size) - - val horizontal = when (size) { - PrezelButtonSize.XSMALL -> spacing.V10 - PrezelButtonSize.SMALL -> spacing.V12 - PrezelButtonSize.REGULAR -> spacing.V16 - } - - val vertical = when (size) { - PrezelButtonSize.XSMALL -> spacing.V6 - PrezelButtonSize.SMALL -> spacing.V8 - PrezelButtonSize.REGULAR -> spacing.V12 - } - - return PaddingValues(horizontal = horizontal, vertical = vertical) -} - -@Composable -private fun prezelIconButtonContentPadding( - size: PrezelButtonSize, - spacing: PrezelSpacing = PrezelTheme.spacing, -): PaddingValues = - PaddingValues( - when (size) { - PrezelButtonSize.XSMALL -> spacing.V8 - PrezelButtonSize.SMALL -> spacing.V10 - PrezelButtonSize.REGULAR -> spacing.V14 - }, - ) - -@Composable -private fun prezelButtonIconSize(size: PrezelButtonSize): Dp = - when (size) { - PrezelButtonSize.XSMALL -> 14.dp - PrezelButtonSize.SMALL -> 16.dp - PrezelButtonSize.REGULAR -> 20.dp - } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelHyperlinkButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelHyperlinkButton.kt deleted file mode 100644 index b5b4438..0000000 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelHyperlinkButton.kt +++ /dev/null @@ -1,42 +0,0 @@ -package com.team.prezel.core.designsystem.component.button - -import androidx.compose.foundation.layout.padding -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import com.team.prezel.core.designsystem.preview.ThemePreview -import com.team.prezel.core.designsystem.theme.PrezelTheme - -@Composable -fun PrezelHyperlinkButton( - text: String, - onClick: () -> Unit, - modifier: Modifier = Modifier, - enabled: Boolean = true, - size: PrezelButtonSize = PrezelButtonSize.XSMALL, -) { - PrezelButton( - text = text, - onClick = onClick, - enabled = enabled, - modifier = modifier, - style = PrezelButtonStyle( - buttonType = PrezelButtonType.GHOST, - buttonHierarchy = PrezelButtonHierarchy.SECONDARY, - buttonSize = size, - showUnderline = true, - ), - ) -} - -@ThemePreview -@Composable -private fun PrezelHyperlinkButtonPreview() { - PrezelTheme { - PrezelHyperlinkButton( - text = "자세히 보기", - onClick = {}, - modifier = Modifier.padding(16.dp), - ) - } -} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelIconButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelIconButton.kt deleted file mode 100644 index 8fc52ff..0000000 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelIconButton.kt +++ /dev/null @@ -1,64 +0,0 @@ -package com.team.prezel.core.designsystem.component.button - -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import com.team.prezel.core.designsystem.icon.IconSource -import com.team.prezel.core.designsystem.icon.PrezelIcons -import com.team.prezel.core.designsystem.preview.ThemePreview -import com.team.prezel.core.designsystem.theme.PrezelTheme - -@Composable -fun PrezelIconButton( - icon: IconSource, - onClick: () -> Unit, - modifier: Modifier = Modifier, - enabled: Boolean = true, - style: PrezelButtonStyle = PrezelButtonStyle(), -) { - PrezelButton( - icon = icon, - onClick = onClick, - modifier = modifier, - enabled = enabled, - style = style, - ) -} - -@ThemePreview -@Composable -private fun PrezelIconButtonPreviewFilled() { - PrezelTheme { - PrezelButtonPreviewByType(type = PrezelButtonType.FILLED, content = ::PrezelIconButtonPreviewItem, isIconOnly = true) - } -} - -@ThemePreview -@Composable -private fun PrezelIconButtonPreviewOutlined() { - PrezelTheme { - PrezelButtonPreviewByType(type = PrezelButtonType.OUTLINED, content = ::PrezelIconButtonPreviewItem, isIconOnly = true) - } -} - -@ThemePreview -@Composable -private fun PrezelIconButtonPreviewGhost() { - PrezelTheme { - PrezelButtonPreviewByType(type = PrezelButtonType.GHOST, content = ::PrezelIconButtonPreviewItem, isIconOnly = true) - } -} - -@Composable -private fun PrezelIconButtonPreviewItem( - style: PrezelButtonStyle, - enabled: Boolean, - modifier: Modifier = Modifier, -) { - PrezelIconButton( - icon = IconSource(resId = PrezelIcons.Blank), - onClick = {}, - enabled = enabled, - style = style, - modifier = modifier, - ) -} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelTextButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelTextButton.kt deleted file mode 100644 index 0c60503..0000000 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelTextButton.kt +++ /dev/null @@ -1,62 +0,0 @@ -package com.team.prezel.core.designsystem.component.button - -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import com.team.prezel.core.designsystem.preview.ThemePreview -import com.team.prezel.core.designsystem.theme.PrezelTheme - -@Composable -fun PrezelTextButton( - text: String, - onClick: () -> Unit, - modifier: Modifier = Modifier, - enabled: Boolean = true, - style: PrezelButtonStyle = PrezelButtonStyle(), -) { - PrezelButton( - text = text, - onClick = onClick, - modifier = modifier, - enabled = enabled, - style = style, - ) -} - -@ThemePreview -@Composable -private fun PrezelTextButtonPreviewFilled() { - PrezelTheme { - PrezelButtonPreviewByType(type = PrezelButtonType.FILLED, content = ::PrezelTextButtonPreviewItem) - } -} - -@ThemePreview -@Composable -private fun PrezelTextButtonPreviewOutlined() { - PrezelTheme { - PrezelButtonPreviewByType(type = PrezelButtonType.OUTLINED, content = ::PrezelTextButtonPreviewItem) - } -} - -@ThemePreview -@Composable -private fun PrezelTextButtonPreviewGhost() { - PrezelTheme { - PrezelButtonPreviewByType(type = PrezelButtonType.GHOST, content = ::PrezelTextButtonPreviewItem) - } -} - -@Composable -private fun PrezelTextButtonPreviewItem( - style: PrezelButtonStyle, - enabled: Boolean, - modifier: Modifier = Modifier, -) { - PrezelTextButton( - text = "Label", - onClick = {}, - enabled = enabled, - style = style, - modifier = modifier, - ) -} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/floating/PrezelFloatingButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/floating/PrezelFloatingButton.kt deleted file mode 100644 index 44732ba..0000000 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/floating/PrezelFloatingButton.kt +++ /dev/null @@ -1,79 +0,0 @@ -package com.team.prezel.core.designsystem.component.button.floating - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.material3.FloatingActionButton -import androidx.compose.material3.FloatingActionButtonDefaults -import androidx.compose.material3.Icon -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import com.team.prezel.core.designsystem.icon.IconSource -import com.team.prezel.core.designsystem.icon.PrezelIcons -import com.team.prezel.core.designsystem.preview.ThemePreview -import com.team.prezel.core.designsystem.theme.PrezelTheme - -@Composable -fun PrezelFloatingButton( - iconSource: IconSource, - onClick: () -> Unit, - modifier: Modifier = Modifier, - style: PrezelFloatingButtonStyle = PrezelFloatingButtonStyle(), -) { - FloatingActionButton( - onClick = onClick, - modifier = modifier - .applyPrezelFloatingButtonShadow() - .size(prezelFloatingButtonSize(style.size)), - shape = PrezelTheme.shapes.V1000, - containerColor = prezelFloatingButtonContainerColor(style.hierarchy), - contentColor = prezelFloatingButtonContentColor(style.hierarchy), - elevation = FloatingActionButtonDefaults.bottomAppBarFabElevation(), - ) { - Icon( - painter = iconSource.painter(), - contentDescription = iconSource.contentDescription(), - modifier = Modifier.size(prezelFloatingButtonIconSize(style.size)), - ) - } -} - -@ThemePreview -@Composable -private fun PrezelFloatingButtonPreview() { - PrezelTheme { - Column( - modifier = Modifier - .background(PrezelTheme.colors.bgRegular) - .padding(12.dp), - verticalArrangement = Arrangement.spacedBy(8.dp), - ) { - PrezelFloatingButton( - iconSource = IconSource(resId = PrezelIcons.Blank), - style = PrezelFloatingButtonStyle(hierarchy = PrezelFloatingButtonHierarchy.PRIMARY, size = PrezelFloatingButtonSize.REGULAR), - onClick = {}, - ) - - PrezelFloatingButton( - iconSource = IconSource(resId = PrezelIcons.Blank), - style = PrezelFloatingButtonStyle(hierarchy = PrezelFloatingButtonHierarchy.PRIMARY, size = PrezelFloatingButtonSize.SMALL), - onClick = {}, - ) - - PrezelFloatingButton( - iconSource = IconSource(resId = PrezelIcons.Blank), - style = PrezelFloatingButtonStyle(hierarchy = PrezelFloatingButtonHierarchy.SECONDARY, size = PrezelFloatingButtonSize.REGULAR), - onClick = {}, - ) - - PrezelFloatingButton( - iconSource = IconSource(resId = PrezelIcons.Blank), - style = PrezelFloatingButtonStyle(hierarchy = PrezelFloatingButtonHierarchy.SECONDARY, size = PrezelFloatingButtonSize.SMALL), - onClick = {}, - ) - } - } -} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/floating/PrezelFloatingButtonMenuItem.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/floating/PrezelFloatingButtonMenuItem.kt deleted file mode 100644 index 49c07a4..0000000 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/floating/PrezelFloatingButtonMenuItem.kt +++ /dev/null @@ -1,83 +0,0 @@ -package com.team.prezel.core.designsystem.component.button.floating - -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -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.Text -import androidx.compose.material3.ripple -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.unit.dp -import com.team.prezel.core.designsystem.icon.IconSource -import com.team.prezel.core.designsystem.icon.PrezelIcons -import com.team.prezel.core.designsystem.preview.ThemePreview -import com.team.prezel.core.designsystem.theme.PrezelTheme - -@Composable -fun PrezelFloatingButtonMenuItem( - label: String, - onClick: () -> Unit, - modifier: Modifier = Modifier, - iconSource: IconSource? = null, -) { - Row( - modifier = modifier - .fillMaxWidth() - .clip(PrezelTheme.shapes.V6) - .clickable( - indication = ripple(), - interactionSource = null, - onClick = onClick, - ).padding(prezelFloatingButtonMenuItemPaddingValues()), - verticalAlignment = Alignment.CenterVertically, - ) { - iconSource?.let { source -> PrezelFloatingButtonMenuItemIcon(iconSource = source) } - Text(text = label, style = prezelFloatingButtonMenuItemTextStyle()) - } -} - -@Composable -private fun PrezelFloatingButtonMenuItemIcon(iconSource: IconSource) { - Icon( - painter = iconSource.painter(), - contentDescription = iconSource.contentDescription(), - modifier = Modifier.size(prezelFloatingButtonMenuItemIconSize()), - ) - - Spacer(modifier = Modifier.width(prezelFloatingButtonMenuItemSpaceDp())) -} - -@ThemePreview -@Composable -private fun PrezelFloatingButtonMenuItemPreview() { - PrezelTheme { - Column( - verticalArrangement = Arrangement.spacedBy(8.dp), - horizontalAlignment = Alignment.CenterHorizontally, - modifier = Modifier - .background(PrezelTheme.colors.bgRegular) - .padding(16.dp), - ) { - PrezelFloatingButtonMenuItem( - label = "Label", - onClick = {}, - iconSource = IconSource(resId = PrezelIcons.Blank), - ) - - PrezelFloatingButtonMenuItem( - label = "Label", - onClick = {}, - ) - } - } -} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/floating/PrezelFloatingButtonMenuItemStyle.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/floating/PrezelFloatingButtonMenuItemStyle.kt deleted file mode 100644 index 8371677..0000000 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/floating/PrezelFloatingButtonMenuItemStyle.kt +++ /dev/null @@ -1,64 +0,0 @@ -package com.team.prezel.core.designsystem.component.button.floating - -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.runtime.Composable -import androidx.compose.runtime.compositionLocalOf -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp -import com.team.prezel.core.designsystem.foundation.number.PrezelSpacing -import com.team.prezel.core.designsystem.foundation.typography.PrezelTypography -import com.team.prezel.core.designsystem.theme.PrezelTheme - -enum class PrezelFloatingButtonMenuItemSize { - SMALL, - REGULAR, - ; - - companion object { - fun buttonMenuItemSize(size: PrezelFloatingButtonSize): PrezelFloatingButtonMenuItemSize = - when (size) { - PrezelFloatingButtonSize.SMALL -> SMALL - PrezelFloatingButtonSize.REGULAR -> REGULAR - } - } -} - -internal val LocalPrezelFloatingButtonMenuItemSize = compositionLocalOf { PrezelFloatingButtonMenuItemSize.REGULAR } - -@Composable -internal fun prezelFloatingButtonMenuItemTextStyle( - size: PrezelFloatingButtonMenuItemSize = LocalPrezelFloatingButtonMenuItemSize.current, - typography: PrezelTypography = PrezelTheme.typography, -): TextStyle = - when (size) { - PrezelFloatingButtonMenuItemSize.SMALL -> typography.body3Regular - PrezelFloatingButtonMenuItemSize.REGULAR -> typography.body2Regular - } - -@Composable -internal fun prezelFloatingButtonMenuItemPaddingValues( - size: PrezelFloatingButtonMenuItemSize = LocalPrezelFloatingButtonMenuItemSize.current, - spacing: PrezelSpacing = PrezelTheme.spacing, -): PaddingValues = - when (size) { - PrezelFloatingButtonMenuItemSize.SMALL -> spacing.V8 to spacing.V4 - PrezelFloatingButtonMenuItemSize.REGULAR -> spacing.V12 to spacing.V8 - }.let { (horizontal, vertical) -> PaddingValues(horizontal = horizontal, vertical = vertical) } - -@Composable -internal fun prezelFloatingButtonMenuItemIconSize(size: PrezelFloatingButtonMenuItemSize = LocalPrezelFloatingButtonMenuItemSize.current): Dp = - when (size) { - PrezelFloatingButtonMenuItemSize.SMALL -> 16.dp - PrezelFloatingButtonMenuItemSize.REGULAR -> 20.dp - } - -@Composable -internal fun prezelFloatingButtonMenuItemSpaceDp( - size: PrezelFloatingButtonMenuItemSize = LocalPrezelFloatingButtonMenuItemSize.current, - spacing: PrezelSpacing = PrezelTheme.spacing, -): Dp = - when (size) { - PrezelFloatingButtonMenuItemSize.SMALL -> spacing.V4 - PrezelFloatingButtonMenuItemSize.REGULAR -> spacing.V8 - } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/floating/PrezelFloatingButtonStyle.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/floating/PrezelFloatingButtonStyle.kt deleted file mode 100644 index d9774d4..0000000 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/floating/PrezelFloatingButtonStyle.kt +++ /dev/null @@ -1,101 +0,0 @@ -package com.team.prezel.core.designsystem.component.button.floating - -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.runtime.Composable -import androidx.compose.runtime.Immutable -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp -import com.team.prezel.core.designsystem.foundation.color.PrezelColors -import com.team.prezel.core.designsystem.foundation.number.PrezelSpacing -import com.team.prezel.core.designsystem.theme.PrezelColorScheme -import com.team.prezel.core.designsystem.theme.PrezelTheme -import com.team.prezel.core.designsystem.util.dropShadowCache - -enum class PrezelFloatingButtonHierarchy { - PRIMARY, - SECONDARY, -} - -enum class PrezelFloatingButtonSize { - SMALL, - REGULAR, -} - -@Immutable -data class PrezelFloatingButtonStyle( - val hierarchy: PrezelFloatingButtonHierarchy = PrezelFloatingButtonHierarchy.PRIMARY, - val size: PrezelFloatingButtonSize = PrezelFloatingButtonSize.REGULAR, -) - -internal fun prezelFloatingButtonSize(size: PrezelFloatingButtonSize): Dp = - when (size) { - PrezelFloatingButtonSize.SMALL -> 36.dp - PrezelFloatingButtonSize.REGULAR -> 48.dp - } - -internal fun prezelFloatingButtonIconSize(size: PrezelFloatingButtonSize): Dp = - when (size) { - PrezelFloatingButtonSize.SMALL -> 16.dp - PrezelFloatingButtonSize.REGULAR -> 20.dp - } - -@Composable -internal fun Modifier.applyPrezelFloatingButtonShadow(): Modifier = - this.dropShadowCache( - color = Color(0x1F000713), - shape = PrezelTheme.shapes.V1000, - offsetY = 2.dp, - blurRadius = 4.dp, - ) - -@Composable -internal fun prezelFloatingButtonContentColor( - hierarchy: PrezelFloatingButtonHierarchy, - colors: PrezelColors = PrezelTheme.colors, -): Color = - when (hierarchy) { - PrezelFloatingButtonHierarchy.PRIMARY -> colors.solidWhite - PrezelFloatingButtonHierarchy.SECONDARY -> colors.iconRegular - } - -@Composable -internal fun prezelFloatingButtonContainerColor( - hierarchy: PrezelFloatingButtonHierarchy, - colors: PrezelColors = PrezelTheme.colors, -): Color = - when (hierarchy) { - PrezelFloatingButtonHierarchy.PRIMARY -> colors.interactiveRegular - PrezelFloatingButtonHierarchy.SECONDARY -> colors.bgLarge - } - -@Composable -internal fun prezelFloatingMenuButtonContentColor( - hierarchy: PrezelFloatingButtonHierarchy, - colors: PrezelColors = PrezelTheme.colors, -): Color = - when (hierarchy) { - PrezelFloatingButtonHierarchy.PRIMARY -> PrezelColorScheme.Light.textMedium - PrezelFloatingButtonHierarchy.SECONDARY -> colors.textMedium - } - -@Composable -internal fun prezelFloatingMenuButtonContainerColor( - hierarchy: PrezelFloatingButtonHierarchy, - colors: PrezelColors = PrezelTheme.colors, -): Color = - when (hierarchy) { - PrezelFloatingButtonHierarchy.PRIMARY -> colors.solidWhite - PrezelFloatingButtonHierarchy.SECONDARY -> colors.bgRegular - } - -@Composable -internal fun prezelFloatingMenuButtonPaddingValues( - size: PrezelFloatingButtonSize, - spacing: PrezelSpacing = PrezelTheme.spacing, -): PaddingValues = - when (size) { - PrezelFloatingButtonSize.SMALL -> spacing.V4 - PrezelFloatingButtonSize.REGULAR -> spacing.V6 - }.let { padding -> PaddingValues(padding) } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/floating/PrezelFloatingMenuButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/floating/PrezelFloatingMenuButton.kt deleted file mode 100644 index a94cff5..0000000 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/floating/PrezelFloatingMenuButton.kt +++ /dev/null @@ -1,234 +0,0 @@ -package com.team.prezel.core.designsystem.component.button.floating - -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.ColumnScope -import androidx.compose.foundation.layout.IntrinsicSize -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.requiredHeightIn -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.layout.wrapContentHeight -import androidx.compose.material3.LocalContentColor -import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider -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.unit.dp -import com.team.prezel.core.designsystem.R -import com.team.prezel.core.designsystem.icon.IconSource -import com.team.prezel.core.designsystem.icon.PrezelIcons -import com.team.prezel.core.designsystem.preview.ThemePreview -import com.team.prezel.core.designsystem.theme.PrezelTheme - -@Composable -fun PrezelFloatingMenuButton( - iconSource: IconSource, - isExpanded: Boolean, - onClick: () -> Unit, - modifier: Modifier = Modifier, - style: PrezelFloatingButtonStyle = PrezelFloatingButtonStyle(), - content: @Composable (ColumnScope.() -> Unit), -) { - CompositionLocalProvider( - LocalContentColor provides prezelFloatingMenuButtonContentColor(style.hierarchy), - ) { - Column( - modifier = modifier, - horizontalAlignment = Alignment.End, - verticalArrangement = Arrangement.spacedBy(PrezelTheme.spacing.V16), - ) { - PrezelFloatingButtonMenu( - isExpanded = isExpanded, - style = style, - content = content, - ) - - PrezelMainFloatingButton( - iconSource = iconSource, - style = style, - isExpanded = isExpanded, - onClick = onClick, - ) - } - } -} - -@Composable -private fun PrezelMainFloatingButton( - iconSource: IconSource, - style: PrezelFloatingButtonStyle, - isExpanded: Boolean, - onClick: () -> Unit, - modifier: Modifier = Modifier, -) { - val currentIconSource = - if (isExpanded) { - IconSource( - resId = PrezelIcons.Cancel, - contentDescResId = R.string.core_designsystem_close_floating_btn_content_desc, - ) - } else { - iconSource - } - - PrezelFloatingButton( - iconSource = currentIconSource, - onClick = onClick, - modifier = modifier, - style = style, - ) -} - -@Composable -private fun PrezelFloatingButtonMenu( - isExpanded: Boolean, - modifier: Modifier = Modifier, - style: PrezelFloatingButtonStyle, - content: @Composable ColumnScope.() -> Unit, -) { - AnimatedVisibility( - visible = isExpanded, - enter = fadeIn(), - exit = fadeOut(), - ) { - Column( - modifier = modifier - .width(IntrinsicSize.Max) - .background( - shape = PrezelTheme.shapes.V12, - color = prezelFloatingMenuButtonContainerColor(style.hierarchy), - ).padding(prezelFloatingMenuButtonPaddingValues(style.size)), - horizontalAlignment = Alignment.Start, - verticalArrangement = Arrangement.spacedBy(PrezelTheme.spacing.V4), - ) { - CompositionLocalProvider( - LocalPrezelFloatingButtonMenuItemSize provides PrezelFloatingButtonMenuItemSize.buttonMenuItemSize(style.size), - ) { - content() - } - } - } -} - -@ThemePreview -@Composable -private fun PrimaryPrezelFloatingMenuButtonPreview() { - PrezelTheme { - Row( - modifier = Modifier - .wrapContentHeight() - .requiredHeightIn(200.dp) - .background(PrezelTheme.colors.bgScrim) - .padding(12.dp), - verticalAlignment = Alignment.Bottom, - horizontalArrangement = Arrangement.spacedBy(12.dp), - ) { - PreviewFloatingMenuButton( - initialExpanded = false, - style = PrezelFloatingButtonStyle(hierarchy = PrezelFloatingButtonHierarchy.PRIMARY, size = PrezelFloatingButtonSize.REGULAR), - ) - PreviewFloatingMenuButton( - initialExpanded = true, - style = PrezelFloatingButtonStyle(hierarchy = PrezelFloatingButtonHierarchy.PRIMARY, size = PrezelFloatingButtonSize.REGULAR), - ) - PreviewFloatingMenuButton( - initialExpanded = false, - style = PrezelFloatingButtonStyle(hierarchy = PrezelFloatingButtonHierarchy.PRIMARY, size = PrezelFloatingButtonSize.SMALL), - ) - PreviewFloatingMenuButton( - initialExpanded = true, - style = PrezelFloatingButtonStyle(hierarchy = PrezelFloatingButtonHierarchy.PRIMARY, size = PrezelFloatingButtonSize.SMALL), - ) - } - } -} - -@ThemePreview -@Composable -private fun SecondaryPrezelFloatingMenuButtonPreview() { - PrezelTheme { - Row( - modifier = Modifier - .wrapContentHeight() - .requiredHeightIn(200.dp) - .background(PrezelTheme.colors.bgScrim) - .padding(12.dp), - verticalAlignment = Alignment.Bottom, - horizontalArrangement = Arrangement.spacedBy(12.dp), - ) { - PreviewFloatingMenuButton( - initialExpanded = false, - style = PrezelFloatingButtonStyle(hierarchy = PrezelFloatingButtonHierarchy.SECONDARY, size = PrezelFloatingButtonSize.REGULAR), - ) - PreviewFloatingMenuButton( - initialExpanded = true, - style = PrezelFloatingButtonStyle(hierarchy = PrezelFloatingButtonHierarchy.SECONDARY, size = PrezelFloatingButtonSize.REGULAR), - ) - PreviewFloatingMenuButton( - initialExpanded = false, - style = PrezelFloatingButtonStyle(hierarchy = PrezelFloatingButtonHierarchy.SECONDARY, size = PrezelFloatingButtonSize.SMALL), - ) - PreviewFloatingMenuButton( - initialExpanded = true, - style = PrezelFloatingButtonStyle(hierarchy = PrezelFloatingButtonHierarchy.SECONDARY, size = PrezelFloatingButtonSize.SMALL), - ) - } - } -} - -@Composable -private fun PreviewFloatingMenuButton( - initialExpanded: Boolean, - style: PrezelFloatingButtonStyle, -) { - var isExpanded by remember { mutableStateOf(initialExpanded) } - - PrezelFloatingMenuButton( - iconSource = IconSource(resId = PrezelIcons.Blank), - isExpanded = isExpanded, - onClick = { isExpanded = !isExpanded }, - style = style, - ) { - PrezelFloatingButtonMenuItem(label = "LongLabel", onClick = {}) - PrezelFloatingButtonMenuItem(label = "Label", onClick = {}) - PrezelFloatingButtonMenuItem(label = "Label", onClick = {}) - } -} - -@ThemePreview -@Composable -private fun PrezelFloatingMenuButtonPreview() { - PrezelTheme { - Row { - PreviewFloatingMenuButton(true) - PreviewFloatingMenuButton(false) - } - } -} - -@Composable -private fun PreviewFloatingMenuButton(isShowIcon: Boolean) { - val iconSource = if (isShowIcon) IconSource(resId = PrezelIcons.Blank) else null - - PrezelFloatingMenuButton( - modifier = Modifier - .background(PrezelTheme.colors.bgScrim) - .padding(16.dp), - iconSource = IconSource(resId = PrezelIcons.Blank), - isExpanded = true, - onClick = {}, - ) { - PrezelFloatingButtonMenuItem(label = "LongLabel", onClick = {}, iconSource = iconSource) - PrezelFloatingButtonMenuItem(label = "Label", onClick = {}, iconSource = iconSource) - PrezelFloatingButtonMenuItem(label = "Label", onClick = {}, iconSource = iconSource) - } -} From e81f5dff760a9c2e3346b90a234774e4b8ff19d2 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Tue, 24 Mar 2026 20:58:34 +0900 Subject: [PATCH 18/42] =?UTF-8?q?refactor:=20=EB=B2=84=ED=8A=BC=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20?= =?UTF-8?q?=ED=8C=A8=ED=82=A4=EC=A7=80=20=EA=B5=AC=EC=A1=B0=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20=EB=B0=8F=20API=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../designsystem/component/PrezelAccordion.kt | 2 +- .../component/datepicker/PrezelDatePicker.kt | 15 +++++++-------- .../component/snackbar/PrezelSnackbar.kt | 10 +++++----- .../component/textfield/PrezelTextArea.kt | 2 +- .../component/textfield/PrezelTextField.kt | 2 +- .../team/prezel/feature/login/impl/LoginScreen.kt | 2 +- 6 files changed, 16 insertions(+), 17 deletions(-) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelAccordion.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelAccordion.kt index 9f7f5dc..1662a63 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelAccordion.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelAccordion.kt @@ -32,7 +32,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.R -import com.team.prezel.core.designsystem.component.button.PrezelHyperlinkButton +import com.team.prezel.core.designsystem.component.actions.button.PrezelHyperlinkButton import com.team.prezel.core.designsystem.component.list.PrezelList import com.team.prezel.core.designsystem.component.list.PrezelListSize import com.team.prezel.core.designsystem.foundation.typography.PrezelTextStyles diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/PrezelDatePicker.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/PrezelDatePicker.kt index 51730dc..a547835 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/PrezelDatePicker.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/PrezelDatePicker.kt @@ -29,8 +29,7 @@ import com.team.prezel.core.designsystem.R import com.team.prezel.core.designsystem.component.PrezelDividerType import com.team.prezel.core.designsystem.component.PrezelHorizontalDivider import com.team.prezel.core.designsystem.component.PrezelTopAppBar -import com.team.prezel.core.designsystem.component.button.ButtonAreaButtonSpec -import com.team.prezel.core.designsystem.component.button.PrezelButtonArea +import com.team.prezel.core.designsystem.component.actions.area.PrezelButtonArea import com.team.prezel.core.designsystem.icon.PrezelIcons import com.team.prezel.core.designsystem.theme.PrezelTheme import kotlinx.datetime.DateTimeUnit @@ -113,15 +112,15 @@ private fun DatePickerFooter( onConfirm: (LocalDate) -> Unit, ) { PrezelButtonArea( - mainButton = ButtonAreaButtonSpec( + isVertical = false, + showBackground = true, + ) { + MainButton( label = stringResource(R.string.core_designsystem_date_picker_confirm_btn), enabled = selectedDate != null, onClick = { selectedDate?.let(onConfirm) }, - ), - subButton = null, - isVertical = false, - showBackground = true, - ) + ) + } } @Composable diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/snackbar/PrezelSnackbar.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/snackbar/PrezelSnackbar.kt index 5fbb216..46d7c1c 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/snackbar/PrezelSnackbar.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/snackbar/PrezelSnackbar.kt @@ -18,10 +18,9 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import com.team.prezel.core.designsystem.component.button.PrezelButton -import com.team.prezel.core.designsystem.component.button.PrezelButtonSize -import com.team.prezel.core.designsystem.component.button.PrezelButtonStyle -import com.team.prezel.core.designsystem.component.button.PrezelButtonType +import com.team.prezel.core.designsystem.component.actions.button.PrezelButton +import com.team.prezel.core.designsystem.component.actions.button.config.ButtonSize +import com.team.prezel.core.designsystem.component.actions.button.config.ButtonType import com.team.prezel.core.designsystem.foundation.typography.PrezelTextStyles import com.team.prezel.core.designsystem.icon.IconSource import com.team.prezel.core.designsystem.icon.PrezelIcons @@ -65,8 +64,9 @@ fun PrezelSnackbar( Spacer(Modifier.width(PrezelTheme.spacing.V16)) PrezelButton( text = visuals.actionLabel, + type = ButtonType.GHOST, + size = ButtonSize.SMALL, onClick = { data.performAction() }, - style = PrezelButtonStyle(buttonType = PrezelButtonType.GHOST, buttonSize = PrezelButtonSize.SMALL), ) } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextArea.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextArea.kt index b8c84d0..379b0f1 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextArea.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextArea.kt @@ -24,7 +24,7 @@ import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp -import com.team.prezel.core.designsystem.component.button.PrezelButton +import com.team.prezel.core.designsystem.component.actions.button.PrezelButton import com.team.prezel.core.designsystem.component.textfield.component.PrezelTextFieldLabel import com.team.prezel.core.designsystem.component.textfield.component.PrezelTextFieldPlaceholder import com.team.prezel.core.designsystem.component.textfield.component.PrezelTextFieldSupportingText diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt index e754dbc..7f4beca 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt @@ -31,7 +31,7 @@ import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp -import com.team.prezel.core.designsystem.component.button.PrezelButton +import com.team.prezel.core.designsystem.component.actions.button.PrezelButton import com.team.prezel.core.designsystem.component.textfield.component.PrezelTextFieldLabel import com.team.prezel.core.designsystem.component.textfield.component.PrezelTextFieldPlaceholder import com.team.prezel.core.designsystem.component.textfield.component.PrezelTextFieldSupportingText diff --git a/Prezel/feature/login/impl/src/main/java/com/team/prezel/feature/login/impl/LoginScreen.kt b/Prezel/feature/login/impl/src/main/java/com/team/prezel/feature/login/impl/LoginScreen.kt index 0050393..42ba412 100644 --- a/Prezel/feature/login/impl/src/main/java/com/team/prezel/feature/login/impl/LoginScreen.kt +++ b/Prezel/feature/login/impl/src/main/java/com/team/prezel/feature/login/impl/LoginScreen.kt @@ -24,7 +24,7 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.team.prezel.core.designsystem.component.button.PrezelButton +import com.team.prezel.core.designsystem.component.actions.button.PrezelButton import com.team.prezel.core.designsystem.preview.ThemePreview import com.team.prezel.core.designsystem.theme.PrezelTheme import com.team.prezel.feature.login.api.AUTH_LOGO_SHARED_ELEMENT_KEY From d112d558c9bc7dd2927df5ba676ffbf24ae3e8f2 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Tue, 24 Mar 2026 21:00:02 +0900 Subject: [PATCH 19/42] =?UTF-8?q?chore:=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20DropShadowCache=20=EC=9C=A0?= =?UTF-8?q?=ED=8B=B8=EB=A6=AC=ED=8B=B0=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 더 이상 사용되지 않는 `dropShadowCache` 확장 함수 및 관련 파일(`DropShadowCache.kt`)을 삭제하였습니다. 해당 함수는 `Modifier`에 그림자 효과를 적용하기 위해 `drawWithCache`와 `BlurMaskFilter`를 사용하던 로직을 포함하고 있었습니다. --- .../core/designsystem/util/DropShadowCache.kt | 46 ------------------- 1 file changed, 46 deletions(-) delete mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/util/DropShadowCache.kt diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/util/DropShadowCache.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/util/DropShadowCache.kt deleted file mode 100644 index dd5a61f..0000000 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/util/DropShadowCache.kt +++ /dev/null @@ -1,46 +0,0 @@ -package com.team.prezel.core.designsystem.util - -import android.graphics.BlurMaskFilter -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.drawWithCache -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.Paint -import androidx.compose.ui.graphics.Path -import androidx.compose.ui.graphics.Shape -import androidx.compose.ui.graphics.addOutline -import androidx.compose.ui.graphics.drawscope.drawIntoCanvas -import androidx.compose.ui.graphics.toArgb -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp - -fun Modifier.dropShadowCache( - color: Color = Color.Black, - offsetX: Dp = 0.dp, - offsetY: Dp = 0.dp, - blurRadius: Dp = 0.dp, - shape: Shape, - blurStyle: BlurMaskFilter.Blur = BlurMaskFilter.Blur.NORMAL, -): Modifier = - drawWithCache { - val paint = Paint() - val frameworkPaint = paint.asFrameworkPaint() - if (blurRadius != 0.dp) { - frameworkPaint.maskFilter = (BlurMaskFilter(blurRadius.toPx(), blurStyle)) - } - frameworkPaint.color = color.toArgb() - - val leftPixel = offsetX.toPx() - val topPixel = offsetY.toPx() - - val path = Path().apply { - addOutline(shape.createOutline(size, layoutDirection, this@drawWithCache)) - } - - onDrawBehind { - drawIntoCanvas { canvas -> - canvas.translate(leftPixel, topPixel) - canvas.drawPath(path, paint) - canvas.translate(-leftPixel, -topPixel) - } - } - } From 7276c342f7a0b95411765445f2d8a3ba88417ff1 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Tue, 24 Mar 2026 22:12:12 +0900 Subject: [PATCH 20/42] =?UTF-8?q?feat:=20PrezelDropShadow=20=EC=84=B1?= =?UTF-8?q?=EB=8A=A5=20=EC=B5=9C=EC=A0=81=ED=99=94=20=EB=B0=8F=20PrezelFlo?= =?UTF-8?q?atingButton=20=EA=B7=B8=EB=A6=BC=EC=9E=90=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../button/floating/PrezelFloatingButton.kt | 8 +- .../component/base/PrezelDropShadow.kt | 375 ++++++++++++------ 2 files changed, 261 insertions(+), 122 deletions(-) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingButton.kt index a1fb2c5..4349b1c 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingButton.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingButton.kt @@ -15,6 +15,8 @@ import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.component.actions.button.PrezelIconButton import com.team.prezel.core.designsystem.component.actions.button.config.ButtonHierarchy import com.team.prezel.core.designsystem.component.actions.button.config.ButtonSize +import com.team.prezel.core.designsystem.component.base.PrezelDropShadowDefaults +import com.team.prezel.core.designsystem.component.base.prezelDropShadow import com.team.prezel.core.designsystem.icon.PrezelIcons import com.team.prezel.core.designsystem.preview.ThemePreview import com.team.prezel.core.designsystem.theme.PrezelTheme @@ -34,7 +36,11 @@ fun PrezelFloatingButton( size = size, hierarchy = hierarchy, isRounded = true, - modifier = modifier, + modifier = modifier.prezelDropShadow( + style = PrezelDropShadowDefaults.Regular( + borderRadius = PrezelTheme.radius.V1000, + ), + ), onClick = { onChangeExpanded(!isExpanded) }, ) } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelDropShadow.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelDropShadow.kt index d944846..b39accd 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelDropShadow.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelDropShadow.kt @@ -5,20 +5,30 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.FlowRow +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Surface +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.drawBehind +import androidx.compose.ui.draw.drawWithCache +import androidx.compose.ui.geometry.RoundRect +import androidx.compose.ui.geometry.Size +import androidx.compose.ui.graphics.Canvas import androidx.compose.ui.graphics.ClipOp import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Paint import androidx.compose.ui.graphics.Path +import androidx.compose.ui.graphics.drawscope.DrawScope import androidx.compose.ui.graphics.drawscope.drawIntoCanvas import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.preview.ThemePreview @@ -39,108 +49,225 @@ fun Modifier.prezelDropShadow(style: PrezelDropShadowDefaults.PrezelShadowStyle) ) } +/** + * 여러 개의 shadow 토큰을 기반으로 컴포넌트 외곽에 그림자를 그립니다. + */ private fun Modifier.dropShadow( shadows: List, - borderRadius: Dp = 0.dp, + borderRadius: Dp, isBackgroundTransparent: Boolean = false, -) = this.then( - Modifier.drawBehind { - // Early return으로 불필요한 연산 방지 - if (shadows.isEmpty()) return@drawBehind - - // BlurMaskFilter 캐시 - dropShadow 함수 내부에서만 사용 - val blurMaskFilterCache = mutableMapOf() - - this.drawIntoCanvas { canvas -> - val paint = Paint() - val frameworkPaint = paint.asFrameworkPaint() - - // transparent 배경인 경우를 위한 Path - 재사용 가능하도록 미리 생성 - var clipPath: Path? = null - val borderRadiusPx = borderRadius.toPx() - - if (isBackgroundTransparent && borderRadiusPx > 0f) { - clipPath = Path().apply { - addRoundRect( - androidx.compose.ui.geometry.RoundRect( - left = 0f, - top = 0f, - right = size.width, - bottom = size.height, - radiusX = borderRadiusPx, - radiusY = borderRadiusPx, - ), - ) - } - } +): Modifier = + drawWithCache { + if (shadows.isEmpty()) { + return@drawWithCache onDrawBehind {} + } - // shadow를 뒤에서부터 그려서 올바른 layering 구현 - for (i in shadows.size - 1 downTo 0) { - val shadow = shadows[i] - - // 색상 설정 - frameworkPaint.color = shadow.color.toArgb() - - // BlurMaskFilter 캐싱 및 재사용 - 같은 drawBehind 호출 내에서만 캐싱 - val blurRadiusPx = shadow.blurRadius.toPx() - if (blurRadiusPx > 0f) { - frameworkPaint.maskFilter = blurMaskFilterCache.getOrPut(blurRadiusPx) { - BlurMaskFilter(blurRadiusPx, BlurMaskFilter.Blur.NORMAL) - } - } else { - frameworkPaint.maskFilter = null - } + val borderRadiusPx = borderRadius.toPx() + val paint = Paint() + val frameworkPaint = paint.asFrameworkPaint() + val clipPath = createShadowClipPath( + isBackgroundTransparent = isBackgroundTransparent, + borderRadiusPx = borderRadiusPx, + width = size.width, + height = size.height, + ) + val resolvedShadows = toResolvedShadows(shadows = shadows, size = size) - // 그리기 영역 계산 - 변수 재사용으로 메모리 할당 최소화 - val spreadPixel = shadow.spreadRadius.toPx() - val offsetXPx = shadow.offsetX.toPx() - val offsetYPx = shadow.offsetY.toPx() - - val left = -spreadPixel + offsetXPx - val top = -spreadPixel + offsetYPx - val right = size.width + spreadPixel + offsetXPx - val bottom = size.height + spreadPixel + offsetYPx - - // Clipping 처리 최적화 - var needsRestore = false - if (isBackgroundTransparent) { - canvas.save() - needsRestore = true - - // 미리 생성된 clipPath 재사용 - clipPath?.let { path -> - canvas.clipPath(path, ClipOp.Difference) - } - } + onDrawBehind { + drawShadows( + shadows = resolvedShadows, + paint = paint, + frameworkPaint = frameworkPaint, + clipPath = clipPath, + borderRadiusPx = borderRadiusPx, + isBackgroundTransparent = isBackgroundTransparent, + ) + } + } - // 그리기 - 조건부 radius 최적화 - if (borderRadiusPx > 0f) { - canvas.drawRoundRect( - left = left, - top = top, - right = right, - bottom = bottom, - radiusX = borderRadiusPx, - radiusY = borderRadiusPx, - paint = paint, - ) - } else { - // radius가 0이면 더 빠른 drawRect 사용 - canvas.drawRect( - left = left, - top = top, - right = right, - bottom = bottom, - paint = paint, - ) - } +/** + * 투명 배경에서 내부 영역을 제외하기 위한 clip path를 생성합니다. + */ +private fun createShadowClipPath( + isBackgroundTransparent: Boolean, + borderRadiusPx: Float, + width: Float, + height: Float, +): Path? { + if (!isBackgroundTransparent || borderRadiusPx <= 0f) return null - if (needsRestore) { - canvas.restore() - } + return Path().apply { + addRoundRect( + roundRect = RoundRect( + left = 0f, + top = 0f, + right = width, + bottom = height, + radiusX = borderRadiusPx, + radiusY = borderRadiusPx, + ), + ) + } +} + +/** + * shadow 토큰 목록을 실제 draw에 사용할 값으로 변환합니다. + */ +private fun Density.toResolvedShadows( + shadows: List, + size: Size, +): List { + val maskFiltersByBlurRadius = mapBlurMaskFilters(shadows) + + return shadows.map { shadow -> + val spreadRadiusPx = shadow.spreadRadius.toPx() + val offsetXPx = shadow.offsetX.toPx() + val offsetYPx = shadow.offsetY.toPx() + val blurRadiusPx = shadow.blurRadius.toPx() + + ResolvedShadow( + color = shadow.color.toArgb(), + left = -spreadRadiusPx + offsetXPx, + top = -spreadRadiusPx + offsetYPx, + right = size.width + spreadRadiusPx + offsetXPx, + bottom = size.height + spreadRadiusPx + offsetYPx, + maskFilter = maskFiltersByBlurRadius.getValue(blurRadiusPx), + ) + } +} + +/** + * blur 반경별로 재사용 가능한 mask filter를 생성합니다. + */ +private fun Density.mapBlurMaskFilters(shadows: List): Map = + shadows + .map { it.blurRadius.toPx() } + .distinct() + .associateWith { blurRadiusPx -> + if (blurRadiusPx <= 0f) { + null + } else { + BlurMaskFilter(blurRadiusPx, BlurMaskFilter.Blur.NORMAL) } } - }, + +/** + * 준비된 shadow 목록을 뒤쪽 레이어부터 순서대로 그립니다. + */ +private fun DrawScope.drawShadows( + shadows: List, + paint: Paint, + frameworkPaint: android.graphics.Paint, + clipPath: Path?, + borderRadiusPx: Float, + isBackgroundTransparent: Boolean, +) { + drawIntoCanvas { drawCanvas -> + for (index in shadows.indices.reversed()) { + val shadow = shadows[index] + frameworkPaint.color = shadow.color + frameworkPaint.maskFilter = shadow.maskFilter + + drawCanvas.drawShadowLayer( + shadow = shadow, + paint = paint, + clipPath = clipPath, + borderRadiusPx = borderRadiusPx, + width = size.width, + height = size.height, + isBackgroundTransparent = isBackgroundTransparent, + ) + } + + frameworkPaint.maskFilter = null + } +} + +/** + * 단일 shadow 레이어를 그리기 전에 clip을 적용하고 실제 도형을 렌더링합니다. + */ +private fun Canvas.drawShadowLayer( + shadow: ResolvedShadow, + paint: Paint, + clipPath: Path?, + borderRadiusPx: Float, + width: Float, + height: Float, + isBackgroundTransparent: Boolean, +) { + applyTransparentClip( + clipPath = clipPath, + borderRadiusPx = borderRadiusPx, + width = width, + height = height, + isBackgroundTransparent = isBackgroundTransparent, + ) + + if (borderRadiusPx > 0f) { + drawRoundRect( + left = shadow.left, + top = shadow.top, + right = shadow.right, + bottom = shadow.bottom, + radiusX = borderRadiusPx, + radiusY = borderRadiusPx, + paint = paint, + ) + } else { + drawRect( + left = shadow.left, + top = shadow.top, + right = shadow.right, + bottom = shadow.bottom, + paint = paint, + ) + } + + if (isBackgroundTransparent) { + restore() + } +} + +/** + * 투명 배경인 경우 내부 영역을 제외하도록 clip을 적용합니다. + */ +private fun Canvas.applyTransparentClip( + clipPath: Path?, + borderRadiusPx: Float, + width: Float, + height: Float, + isBackgroundTransparent: Boolean, +) { + if (!isBackgroundTransparent) return + + save() + + if (borderRadiusPx > 0f) { + clipPath?.let { path -> + clipPath(path, ClipOp.Difference) + } + return + } + + clipRect( + left = 0f, + top = 0f, + right = width, + bottom = height, + clipOp = ClipOp.Difference, + ) +} + +/** + * shadow 하나를 draw 가능한 좌표와 paint 정보로 보관합니다. + */ +private data class ResolvedShadow( + val color: Int, + val left: Float, + val top: Float, + val right: Float, + val bottom: Float, + val maskFilter: BlurMaskFilter?, ) object PrezelDropShadowDefaults { @@ -158,8 +285,8 @@ object PrezelDropShadowDefaults { override fun getShadow(): List = emptyList() } - data class Default( - override val borderRadius: Dp, + data class Regular( + override val borderRadius: Dp = 0.dp, override val backgroundColor: Color = Color.Transparent, ) : PrezelShadowStyle(borderRadius, backgroundColor) { private val shadowList by lazy { @@ -200,31 +327,37 @@ object PrezelDropShadowDefaults { @ThemePreview @Composable -private fun WantedDropShadowPreview() { +private fun PrezelDropShadowPreview() { + val styles = listOf( + PrezelDropShadowDefaults.None, + PrezelDropShadowDefaults.Regular(), + ) + PrezelTheme { - Surface { - Column( - modifier = Modifier - .background(PrezelTheme.colors.bgRegular) - .padding(20.dp), - verticalArrangement = Arrangement.spacedBy(20.dp), - ) { - Box( - Modifier - .size(100.dp) - .background(color = Color.Green, shape = RoundedCornerShape(10.dp)) - .prezelDropShadow(style = PrezelDropShadowDefaults.None), - ) - Box( - Modifier - .size(100.dp) - .prezelDropShadow( - style = PrezelDropShadowDefaults.Default( - borderRadius = 10.dp, - backgroundColor = Color.Green, - ), - ), - ) + FlowRow( + modifier = Modifier + .fillMaxWidth() + .background(Color.White) + .padding(16.dp), + verticalArrangement = Arrangement.spacedBy(16.dp), + horizontalArrangement = Arrangement.spacedBy(16.dp), + ) { + Text( + text = "PrezelDropShadow", + style = PrezelTheme.typography.body1Bold, + modifier = Modifier.fillMaxWidth(), + ) + styles.forEach { style -> + Column(horizontalAlignment = Alignment.CenterHorizontally) { + Box( + modifier = Modifier + .size(80.dp) + .prezelDropShadow(style = style), + ) + Spacer(modifier = Modifier.height(4.dp)) + + Text(text = style.javaClass.simpleName) + } } } } From 39e5071e042c97743354671fcbba73f7d89c359b Mon Sep 17 00:00:00 2001 From: moondev03 Date: Tue, 24 Mar 2026 22:12:26 +0900 Subject: [PATCH 21/42] =?UTF-8?q?build:=20detekt=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=EB=B0=8F=20=EB=A3=B0=20=EC=B5=9C=EC=A0=81=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Prezel/detekt-config.yml | 46 +++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/Prezel/detekt-config.yml b/Prezel/detekt-config.yml index b7597b2..b45f3e8 100644 --- a/Prezel/detekt-config.yml +++ b/Prezel/detekt-config.yml @@ -3,61 +3,53 @@ build: config: validation: true - warningsAsErrors: false - checkExhaustiveness: false - -processors: - active: true style: - active: true + ReturnCount: + active: false MaxLineLength: active: true maxLineLength: 150 MagicNumber: active: false - ReturnCount: - active: true - max: 3 UnusedPrivateMember: - active: true ignoreAnnotated: - Preview - ThemePreview - WildcardImport: - active: true - DestructuringDeclarationWithTooManyEntries: - active: false complexity: - active: true LongMethod: - active: true threshold: 50 ignoreAnnotated: - Preview - ThemePreview + NestedBlockDepth: + threshold: 4 LongParameterList: - active: false - CyclomaticComplexMethod: active: true - threshold: 15 - NestedBlockDepth: + functionThreshold: 10 + constructorThreshold: 10 + ignoreAnnotated: + - Composable + + TooManyFunctions: active: true - threshold: 4 + thresholdInFiles: 20 + thresholdInClasses: 15 + thresholdInInterfaces: 12 + thresholdInObjects: 20 + thresholdInEnums: 10 + ignoreAnnotatedFunctions: + - Preview naming: - active: true - MatchingDeclarationName: - active: false FunctionNaming: active: true ignoreAnnotated: - Composable - Preview - -potential-bugs: - active: true + MatchingDeclarationName: + active: false exceptions: active: true From 05bbe35cc6e7c71a9041e2df7f830eedcc3424b6 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Tue, 24 Mar 2026 23:43:35 +0900 Subject: [PATCH 22/42] =?UTF-8?q?docs:=20=EB=94=94=EC=9E=90=EC=9D=B8=20?= =?UTF-8?q?=EC=8B=9C=EC=8A=A4=ED=85=9C=20=EC=A3=BC=EC=9A=94=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20KDoc=20=EC=A3=BC=EC=84=9D=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Prezel/.editorconfig | 1 + .../component/actions/area/ButtonAreaScope.kt | 8 +++++++ .../actions/area/PrezelButtonArea.kt | 6 +++++ .../actions/area/PrezelButtonAreaDefaults.kt | 9 ++++++++ .../component/actions/button/PrezelButton.kt | 3 +++ .../actions/button/PrezelHyperlinkButton.kt | 3 +++ .../actions/button/PrezelIconButton.kt | 3 +++ .../actions/button/PrezelTextButton.kt | 3 +++ .../actions/button/config/PrezelButtonBase.kt | 3 +++ .../button/config/PrezelButtonDefaults.kt | 11 ++++++++++ .../button/floating/PrezelFloatingButton.kt | 3 +++ .../button/floating/PrezelFloatingMenu.kt | 3 +++ .../button/floating/menu/PrezelMenu.kt | 3 +++ .../floating/menu/PrezelMenuDefaults.kt | 10 +++++++++ .../button/floating/menu/PrezelMenuItem.kt | 3 +++ .../floating/menu/PrezelMenuItemDefaults.kt | 10 +++++++++ .../button/floating/menu/PrezelMenuScope.kt | 4 ++++ .../component/base/PrezelDropShadow.kt | 22 ++++++++++--------- .../component/base/PrezelTouchArea.kt | 5 +++++ 19 files changed, 103 insertions(+), 10 deletions(-) diff --git a/Prezel/.editorconfig b/Prezel/.editorconfig index e31becf..8f5a7cb 100644 --- a/Prezel/.editorconfig +++ b/Prezel/.editorconfig @@ -12,6 +12,7 @@ trim_trailing_whitespace = true ij_kotlin_allow_trailing_comma = true ij_kotlin_allow_trailing_comma_on_call_site = true ktlint_function_naming_ignore_when_annotated_with = Composable +ktlint_standard_backing-property-naming = disabled ktlint_standard_multiline-expression-wrapping = disabled ktlint_standard_function-signature = enabled ktlint_function_signature_rule_force_multiline_when_parameter_count_greater_or_equal_than = 2 diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/ButtonAreaScope.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/ButtonAreaScope.kt index 2844a41..ab4b9fa 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/ButtonAreaScope.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/ButtonAreaScope.kt @@ -9,9 +9,15 @@ import com.team.prezel.core.designsystem.component.actions.button.config.ButtonH import com.team.prezel.core.designsystem.component.actions.button.config.ButtonType import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefault +/** + * [PrezelButtonArea] 안에서 액션 버튼을 선언할 때 사용하는 scope입니다. + * + * `MainButton`을 먼저 선언하고 이어서 보조 버튼 하나를 추가하는 구성을 전제로 합니다. + */ @LayoutScopeMarker @Suppress("FunctionName") interface ButtonAreaScope { + /** 주요 액션 버튼을 추가합니다. */ fun MainButton( @DrawableRes iconResId: Int? = null, label: String, @@ -19,6 +25,7 @@ interface ButtonAreaScope { onClick: () -> Unit, ) + /** 보조 액션 버튼을 추가합니다. */ fun SubButton( @DrawableRes iconResId: Int? = null, label: String, @@ -26,6 +33,7 @@ interface ButtonAreaScope { onClick: () -> Unit, ) + /** 버튼 프리셋을 직접 지정해 커스텀 액션 버튼을 추가합니다. */ fun CustomButton( @DrawableRes iconResId: Int? = null, label: String, diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonArea.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonArea.kt index 3d062f7..ea85449 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonArea.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonArea.kt @@ -29,6 +29,12 @@ import com.team.prezel.core.designsystem.preview.PreviewScaffold import com.team.prezel.core.designsystem.preview.SectionTitle import com.team.prezel.core.designsystem.theme.PrezelTheme +/** + * 하단 액션 영역에 주요 버튼과 보조 버튼을 함께 배치합니다. + * + * `content`에서는 `MainButton`을 먼저 선언하고 이어서 보조 버튼 하나를 추가합니다. + * `isVertical`과 `showBackground` 조합에 따라 배치와 기본 스타일이 함께 달라집니다. + */ @Composable fun PrezelButtonArea( modifier: Modifier = Modifier, diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonAreaDefaults.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonAreaDefaults.kt index c6091a7..e6f9c9e 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonAreaDefaults.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonAreaDefaults.kt @@ -6,6 +6,9 @@ import androidx.compose.runtime.Immutable import androidx.compose.ui.graphics.Color import com.team.prezel.core.designsystem.theme.PrezelTheme +/** + * 버튼 영역의 배경, 구분선, 내부 여백을 묶은 스타일 값입니다. + */ @Immutable data class PrezelButtonAreaDefault( val backgroundColor: Color, @@ -13,7 +16,13 @@ data class PrezelButtonAreaDefault( val contentPadding: PaddingValues, ) +/** + * [PrezelButtonArea]의 기본 스타일 값을 계산합니다. + */ object PrezelButtonAreaDefaults { + /** + * 배경 노출 여부와 중첩 여부에 맞는 기본 스타일을 반환합니다. + */ @Composable fun getDefault( showBackground: Boolean = false, diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButton.kt index fb98e3a..6370c2c 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButton.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelButton.kt @@ -14,6 +14,9 @@ import com.team.prezel.core.designsystem.component.actions.button.config.PrezelB import com.team.prezel.core.designsystem.component.actions.button.config.previewGhostBorder import com.team.prezel.core.designsystem.icon.PrezelIcons +/** + * 아이콘과 텍스트를 함께 표시할 수 있는 기본 버튼입니다. + */ @Composable fun PrezelButton( text: String, diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelHyperlinkButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelHyperlinkButton.kt index dd46c1e..c3fc673 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelHyperlinkButton.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelHyperlinkButton.kt @@ -17,6 +17,9 @@ import com.team.prezel.core.designsystem.component.actions.button.config.PrezelB import com.team.prezel.core.designsystem.preview.ThemePreview import com.team.prezel.core.designsystem.theme.PrezelTheme +/** + * 텍스트 링크처럼 보이는 보조 액션 버튼입니다. + */ @Composable fun PrezelHyperlinkButton( text: String, diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelIconButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelIconButton.kt index 89402f1..8ff33b7 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelIconButton.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelIconButton.kt @@ -14,6 +14,9 @@ import com.team.prezel.core.designsystem.component.actions.button.config.PrezelB import com.team.prezel.core.designsystem.component.actions.button.config.previewGhostBorder import com.team.prezel.core.designsystem.icon.PrezelIcons +/** + * 아이콘만 노출하는 액션 버튼입니다. + */ @Composable fun PrezelIconButton( @DrawableRes iconResId: Int, diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelTextButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelTextButton.kt index a99d0d4..6aa3113 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelTextButton.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelTextButton.kt @@ -12,6 +12,9 @@ import com.team.prezel.core.designsystem.component.actions.button.config.PrezelB import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonPreviewContent import com.team.prezel.core.designsystem.component.actions.button.config.previewGhostBorder +/** + * 텍스트만 표시하는 버튼입니다. + */ @Composable fun PrezelTextButton( text: String, diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonBase.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonBase.kt index 2730d7e..a352d05 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonBase.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonBase.kt @@ -21,6 +21,9 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import com.team.prezel.core.designsystem.component.base.PrezelTouchArea +/** + * 버튼 계열 컴포넌트가 공통으로 사용하는 실제 렌더링 구현입니다. + */ @Composable internal fun PrezelButtonBase( text: String?, diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonDefaults.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonDefaults.kt index e3851fb..391a549 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonDefaults.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonDefaults.kt @@ -11,6 +11,9 @@ import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.theme.PrezelColorScheme import com.team.prezel.core.designsystem.theme.PrezelTheme +/** + * 버튼 컴포넌트가 공통으로 사용하는 시각 속성 묶음입니다. + */ @Immutable data class PrezelButtonDefault( private val contentColor: Color, @@ -35,7 +38,15 @@ data class PrezelButtonDefault( fun borderColor(enabled: Boolean): Color = if (enabled) borderColor else disabledBorderColor } +/** + * 버튼 타입과 크기에 맞는 기본 스타일 값을 제공합니다. + */ object PrezelButtonDefaults { + /** + * 버튼 종류와 사용 형태에 맞는 기본 스타일을 계산합니다. + * + * 커스텀 `config`를 만들 때 기준값으로 사용할 수 있습니다. + */ @Composable fun getDefault( isIconOnly: Boolean, diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingButton.kt index 4349b1c..78bf583 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingButton.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingButton.kt @@ -21,6 +21,9 @@ import com.team.prezel.core.designsystem.icon.PrezelIcons import com.team.prezel.core.designsystem.preview.ThemePreview import com.team.prezel.core.designsystem.theme.PrezelTheme +/** + * 확장 상태에 따라 아이콘이 바뀌는 플로팅 액션 버튼입니다. + */ @Composable fun PrezelFloatingButton( isExpanded: Boolean, diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingMenu.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingMenu.kt index 5d691c9..2b2ea11 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingMenu.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingMenu.kt @@ -26,6 +26,9 @@ import com.team.prezel.core.designsystem.icon.PrezelIcons import com.team.prezel.core.designsystem.preview.ThemePreview import com.team.prezel.core.designsystem.theme.PrezelTheme +/** + * 확장 가능한 메뉴와 토글 버튼을 함께 배치하는 플로팅 액션 메뉴입니다. + */ @Composable fun PrezelFloatingMenu( isExpanded: Boolean, diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenu.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenu.kt index 63cf6f0..2ce5580 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenu.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenu.kt @@ -15,6 +15,9 @@ import com.team.prezel.core.designsystem.icon.PrezelIcons import com.team.prezel.core.designsystem.preview.ThemePreview import com.team.prezel.core.designsystem.theme.PrezelTheme +/** + * 플로팅 액션 메뉴 항목을 세로로 배치하는 컨테이너입니다. + */ @Composable fun PrezelMenu( modifier: Modifier = Modifier, diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuDefaults.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuDefaults.kt index b7087ba..22cbcf1 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuDefaults.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuDefaults.kt @@ -8,11 +8,17 @@ import androidx.compose.runtime.Immutable import androidx.compose.ui.graphics.Color import com.team.prezel.core.designsystem.theme.PrezelTheme +/** + * [PrezelMenu]의 크기 프리셋입니다. + */ enum class MenuSize { SMALL, REGULAR, } +/** + * 메뉴 컨테이너의 패딩, 배경, shape를 묶은 스타일 값입니다. + */ @Immutable data class PrezelMenuDefault( val contentPadding: PaddingValues, @@ -21,7 +27,11 @@ data class PrezelMenuDefault( val shape: RoundedCornerShape, ) +/** + * [PrezelMenu]의 기본 스타일 값을 제공합니다. + */ object PrezelMenuDefaults { + /** 메뉴 크기에 맞는 기본 컨테이너 스타일을 반환합니다. */ @Composable fun getDefault(size: MenuSize): PrezelMenuDefault = PrezelMenuDefault( diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuItem.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuItem.kt index a1f281f..aaa69ac 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuItem.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuItem.kt @@ -20,6 +20,9 @@ import com.team.prezel.core.designsystem.preview.ThemePreview import com.team.prezel.core.designsystem.theme.PrezelTheme import com.team.prezel.core.designsystem.util.drawDashBorder +/** + * 메뉴 scope가 실제로 그리는 클릭 가능한 단일 메뉴 아이템입니다. + */ @Composable internal fun PrezelMenuItem( label: String, diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuItemDefaults.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuItemDefaults.kt index 9ed44f5..b16f488 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuItemDefaults.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuItemDefaults.kt @@ -10,11 +10,17 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.theme.PrezelTheme +/** + * [PrezelMenuItem]의 크기 프리셋입니다. + */ enum class MenuItemSize { SMALL, REGULAR, } +/** + * 메뉴 아이템의 아이콘 크기, 간격, 타이포그래피를 묶은 스타일 값입니다. + */ @Immutable data class PrezelMenuItemDefault( val iconSize: Dp, @@ -25,7 +31,11 @@ data class PrezelMenuItemDefault( val shape: RoundedCornerShape, ) +/** + * 메뉴 아이템 크기에 맞는 기본 스타일 값을 제공합니다. + */ object PrezelMenuItemDefaults { + /** 메뉴 아이템 크기에 맞는 기본 스타일을 반환합니다. */ @Composable fun getDefault(size: MenuItemSize): PrezelMenuItemDefault = PrezelMenuItemDefault( diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuScope.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuScope.kt index 94277a0..76b9f13 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuScope.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuScope.kt @@ -4,11 +4,15 @@ import androidx.annotation.DrawableRes import androidx.compose.foundation.layout.LayoutScopeMarker import androidx.compose.runtime.Composable +/** + * [PrezelMenu] 안에서 메뉴 항목을 선언할 때 사용하는 scope입니다. + */ @LayoutScopeMarker interface PrezelMenuScope { val menuSize: MenuSize val itemSize: MenuItemSize + /** 현재 메뉴 크기에 맞는 기본 메뉴 아이템을 추가합니다. */ @Composable fun MenuItem( label: String, diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelDropShadow.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelDropShadow.kt index b39accd..9529674 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelDropShadow.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelDropShadow.kt @@ -34,6 +34,9 @@ import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.preview.ThemePreview import com.team.prezel.core.designsystem.theme.PrezelTheme +/** + * 디자인 시스템 그림자 토큰을 적용하고 같은 모서리 반경의 배경을 함께 그립니다. + */ @Composable fun Modifier.prezelDropShadow(style: PrezelDropShadowDefaults.PrezelShadowStyle): Modifier { val cachedShadows = remember(style) { style.getShadow() } @@ -270,7 +273,13 @@ private data class ResolvedShadow( val maskFilter: BlurMaskFilter?, ) +/** + * [prezelDropShadow]에 전달할 그림자 스타일 프리셋을 제공합니다. + */ object PrezelDropShadowDefaults { + /** + * 그림자 레이어와 배경 처리를 함께 정의하는 스타일 계약입니다. + */ sealed class PrezelShadowStyle( open val borderRadius: Dp, open val backgroundColor: Color, @@ -278,6 +287,7 @@ object PrezelDropShadowDefaults { abstract fun getShadow(): List } + /** 그림자를 그리지 않는 스타일입니다. */ data object None : PrezelShadowStyle( borderRadius = 0.dp, backgroundColor = Color.Transparent, @@ -285,6 +295,7 @@ object PrezelDropShadowDefaults { override fun getShadow(): List = emptyList() } + /** 기본 elevation 느낌의 단일 그림자를 적용하는 스타일입니다. */ data class Regular( override val borderRadius: Dp = 0.dp, override val backgroundColor: Color = Color.Transparent, @@ -305,16 +316,7 @@ object PrezelDropShadowDefaults { } /** - * data class PrezelShadowToken - * - * Shadow의 개별 속성을 정의하는 데이터 클래스입니다. - * Shadow의 위치, 크기, 색상 등을 설정할 수 있습니다. - * - * @param offsetX Dp: Shadow의 수평 오프셋입니다. - * @param offsetY Dp: Shadow의 수직 오프셋입니다. - * @param blurRadius Dp: Shadow의 블러 반경입니다. - * @param spreadRadius Dp: Shadow의 확산 반경입니다. - * @param color Color: Shadow의 색상입니다. + * 개별 그림자 레이어의 오프셋, blur, spread, 색상을 정의합니다. */ data class PrezelShadowToken( val offsetX: Dp, diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelTouchArea.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelTouchArea.kt index da327cb..4845b99 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelTouchArea.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelTouchArea.kt @@ -21,6 +21,11 @@ import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.preview.ThemePreview import com.team.prezel.core.designsystem.theme.PrezelTheme +/** + * 시각 크기보다 넓은 터치 여유 영역을 줄 수 있는 클릭 컨테이너입니다. + * + * `extraTouchPadding`으로 터치 영역을 확보하고 필요할 때 ripple 표시를 끌 수 있습니다. + */ @Composable fun PrezelTouchArea( modifier: Modifier = Modifier, From 20f7b8a6d04bdda78ad7a8e5f72451155f077711 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Wed, 25 Mar 2026 00:05:48 +0900 Subject: [PATCH 23/42] =?UTF-8?q?refactor:=20=EB=94=94=EC=9E=90=EC=9D=B8?= =?UTF-8?q?=20=EC=8B=9C=EC=8A=A4=ED=85=9C=20=EB=82=B4=20`IconSource`=20?= =?UTF-8?q?=EB=B0=8F=20`PrezelImageSource`=20=EC=A0=9C=EA=B1=B0=20?= =?UTF-8?q?=EB=B0=8F=20=EB=A6=AC=EC=86=8C=EC=8A=A4=20=EC=B0=B8=EC=A1=B0=20?= =?UTF-8?q?=EB=B0=A9=EC=8B=9D=20=EB=8B=A8=EC=88=9C=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/team/prezel/ui/PrezelApp.kt | 5 ++- .../component/PrezelNavigationBar.kt | 29 +++++++-------- .../designsystem/component/chip/PrezelChip.kt | 25 ++++++------- .../component/chip/PrezelCustomChipPreview.kt | 13 ++++--- .../component/chip/PrezelIconChip.kt | 8 ++--- .../component/image/PrezelImage.kt | 2 +- .../component/image/PrezelImageSource.kt | 16 --------- .../component/snackbar/PrezelSnackbar.kt | 19 +++++----- .../component/snackbar/SnackbarHost.kt | 8 ++--- .../core/designsystem/icon/IconSource.kt | 35 ------------------- 10 files changed, 52 insertions(+), 108 deletions(-) delete mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/image/PrezelImageSource.kt delete mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/icon/IconSource.kt diff --git a/Prezel/app/src/main/java/com/team/prezel/ui/PrezelApp.kt b/Prezel/app/src/main/java/com/team/prezel/ui/PrezelApp.kt index a957215..1e67f93 100644 --- a/Prezel/app/src/main/java/com/team/prezel/ui/PrezelApp.kt +++ b/Prezel/app/src/main/java/com/team/prezel/ui/PrezelApp.kt @@ -17,7 +17,6 @@ import androidx.navigation3.runtime.NavKey import androidx.navigation3.runtime.entryProvider import androidx.navigation3.ui.NavDisplay import com.team.prezel.core.designsystem.component.PrezelNavigationScaffold -import com.team.prezel.core.designsystem.icon.IconSource import com.team.prezel.core.navigation.LocalNavigator import com.team.prezel.core.navigation.Navigator import com.team.prezel.core.navigation.ProvideSharedTransitionScope @@ -68,11 +67,11 @@ private fun PrezelAppContent( snackbarHostState = snackbarHostState, navigationItems = { MAIN_NAV_ITEMS.forEach { (key, item) -> - item( + Item( selected = key == appState.navigationState.currentTopLevelKey, onClick = { navigator.navigate(key) }, label = stringResource(item.titleTextId), - icon = IconSource(item.iconRes), + iconResId = item.iconRes, ) } }, diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelNavigationBar.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelNavigationBar.kt index 76dd971..db2e3f1 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelNavigationBar.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelNavigationBar.kt @@ -1,5 +1,6 @@ package com.team.prezel.core.designsystem.component +import androidx.annotation.DrawableRes import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -24,9 +25,9 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.component.snackbar.PrezelSnackbarHost -import com.team.prezel.core.designsystem.icon.IconSource import com.team.prezel.core.designsystem.icon.PrezelIcons import com.team.prezel.core.designsystem.preview.ThemePreview import com.team.prezel.core.designsystem.theme.PrezelTheme @@ -56,7 +57,7 @@ fun PrezelNavigationBar( fun RowScope.PrezelNavigationBarItem( selected: Boolean, onClick: () -> Unit, - icon: IconSource, + @DrawableRes iconResId: Int, label: String, modifier: Modifier = Modifier, enabled: Boolean = true, @@ -67,8 +68,8 @@ fun RowScope.PrezelNavigationBarItem( onClick = onClick, icon = { Icon( - painter = icon.painter(), - contentDescription = icon.contentDescription(), + painter = painterResource(id = iconResId), + contentDescription = null, ) }, modifier = modifier, @@ -123,9 +124,9 @@ class PrezelNavigationScope internal constructor( private val rowScope: RowScope, ) { @Composable - fun item( + fun Item( selected: Boolean, - icon: IconSource, + @DrawableRes iconResId: Int, label: String, onClick: () -> Unit, modifier: Modifier = Modifier, @@ -135,7 +136,7 @@ class PrezelNavigationScope internal constructor( rowScope.PrezelNavigationBarItem( selected = selected, onClick = onClick, - icon = icon, + iconResId = iconResId, label = label, modifier = modifier, enabled = enabled, @@ -150,22 +151,16 @@ private fun PrezelNavigationScaffoldPreview() { var selectedIndex by rememberSaveable { mutableIntStateOf(0) } val snackbarHostState = remember { SnackbarHostState() } - val items = listOf( - Triple(IconSource(resId = PrezelIcons.Blank), "Label", 0), - Triple(IconSource(resId = PrezelIcons.Blank), "Label", 1), - Triple(IconSource(resId = PrezelIcons.Blank), "Label", 2), - ) - PrezelTheme { PrezelNavigationScaffold( snackbarHostState = snackbarHostState, navigationItems = { - items.forEach { (icon, label, index) -> - item( + repeat(3) { index -> + Item( selected = selectedIndex == index, onClick = { selectedIndex = index }, - icon = icon, - label = label, + iconResId = PrezelIcons.Blank, + label = "Tab $index", ) } }, diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelChip.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelChip.kt index 9669037..60867d5 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelChip.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelChip.kt @@ -1,5 +1,6 @@ package com.team.prezel.core.designsystem.component.chip +import androidx.annotation.DrawableRes import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -16,7 +17,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import com.team.prezel.core.designsystem.icon.IconSource +import androidx.compose.ui.res.painterResource import com.team.prezel.core.designsystem.icon.PrezelIcons import com.team.prezel.core.designsystem.preview.PreviewScaffold import com.team.prezel.core.designsystem.preview.ThemePreview @@ -26,11 +27,11 @@ import com.team.prezel.core.designsystem.theme.PrezelTheme fun PrezelChip( modifier: Modifier = Modifier, text: String? = null, - icon: IconSource? = null, + @DrawableRes iconResId: Int? = null, style: PrezelChipStyle = PrezelChipStyle(), ) { val hasText = text != null - val hasIcon = icon != null + val hasIcon = iconResId != null val iconOnly = hasIcon && !hasText require(hasText || hasIcon) { "Chip은 text 또는 icon 중 하나는 반드시 필요합니다." } @@ -49,7 +50,9 @@ fun PrezelChip( horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically, ) { - PrezelChipIcon(icon = icon, style = style) + iconResId?.let { resId -> + PrezelChipIcon(iconResId = resId, style = style) + } if (hasText) { if (hasIcon) { @@ -66,7 +69,7 @@ fun PrezelChip( fun PrezelChip( modifier: Modifier = Modifier, text: String? = null, - icon: IconSource? = null, + @DrawableRes iconResId: Int? = null, style: PrezelChipStyle = PrezelChipStyle(), customColors: PrezelChipColors = LocalPrezelChipColors.current, ) { @@ -76,7 +79,7 @@ fun PrezelChip( PrezelChip( modifier = modifier, text = text, - icon = icon, + iconResId = iconResId, style = style, ) } @@ -84,15 +87,13 @@ fun PrezelChip( @Composable private fun PrezelChipIcon( - icon: IconSource?, + @DrawableRes iconResId: Int, style: PrezelChipStyle, modifier: Modifier = Modifier, ) { - if (icon == null) return - Icon( - painter = icon.painter(), - contentDescription = icon.contentDescription(), + painter = painterResource(id = iconResId), + contentDescription = null, modifier = modifier.size(style.iconSize()), ) } @@ -119,7 +120,7 @@ private fun PrezelChipPreview() { private fun PrezelChipPreviewItem(style: PrezelChipStyle) { PrezelChip( text = "Label", - icon = IconSource(resId = PrezelIcons.Blank), + iconResId = PrezelIcons.Blank, style = style, ) } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelCustomChipPreview.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelCustomChipPreview.kt index 1ab5648..2546284 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelCustomChipPreview.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelCustomChipPreview.kt @@ -11,7 +11,6 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp -import com.team.prezel.core.designsystem.icon.IconSource import com.team.prezel.core.designsystem.icon.PrezelIcons import com.team.prezel.core.designsystem.preview.PreviewScaffold import com.team.prezel.core.designsystem.preview.ThemePreview @@ -71,7 +70,7 @@ private fun CustomChipIconOnlySection() { private fun CustomYellowLabelChip() { PrezelChip( text = "느려요", - icon = IconSource(resId = PrezelIcons.Blank), + iconResId = PrezelIcons.Blank, style = PrezelChipStyle( type = PrezelChipType.FILLED, size = PrezelChipSize.REGULAR, @@ -89,7 +88,7 @@ private fun CustomYellowLabelChip() { private fun CustomRedLabelChip() { PrezelChip( text = "빨라요", - icon = null, + iconResId = null, style = PrezelChipStyle( type = PrezelChipType.OUTLINED, size = PrezelChipSize.REGULAR, @@ -107,7 +106,7 @@ private fun CustomRedLabelChip() { private fun CustomGreenLabelChip() { PrezelChip( text = "적당해요", - icon = null, + iconResId = null, style = PrezelChipStyle( type = PrezelChipType.FILLED, size = PrezelChipSize.SMALL, @@ -125,7 +124,7 @@ private fun CustomGreenLabelChip() { private fun CustomYellowIconChip() { PrezelChip( text = null, - icon = IconSource(resId = PrezelIcons.Blank), + iconResId = PrezelIcons.Blank, style = PrezelChipStyle( type = PrezelChipType.FILLED, size = PrezelChipSize.REGULAR, @@ -143,7 +142,7 @@ private fun CustomYellowIconChip() { private fun CustomRedIconChip() { PrezelChip( text = null, - icon = IconSource(resId = PrezelIcons.Blank), + iconResId = PrezelIcons.Blank, style = PrezelChipStyle( type = PrezelChipType.OUTLINED, size = PrezelChipSize.REGULAR, @@ -161,7 +160,7 @@ private fun CustomRedIconChip() { private fun CustomGreenIconChip() { PrezelChip( text = null, - icon = IconSource(resId = PrezelIcons.Blank), + iconResId = PrezelIcons.Blank, style = PrezelChipStyle( type = PrezelChipType.FILLED, size = PrezelChipSize.SMALL, diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelIconChip.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelIconChip.kt index 4d78326..a62a71a 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelIconChip.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelIconChip.kt @@ -1,9 +1,9 @@ package com.team.prezel.core.designsystem.component.chip +import androidx.annotation.DrawableRes import androidx.compose.material3.HorizontalDivider import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import com.team.prezel.core.designsystem.icon.IconSource import com.team.prezel.core.designsystem.icon.PrezelIcons import com.team.prezel.core.designsystem.preview.PreviewScaffold import com.team.prezel.core.designsystem.preview.ThemePreview @@ -11,13 +11,13 @@ import com.team.prezel.core.designsystem.theme.PrezelTheme @Composable fun PrezelIconChip( - icon: IconSource, + @DrawableRes iconResId: Int, modifier: Modifier = Modifier, style: PrezelChipStyle = PrezelChipStyle(), ) { PrezelChip( modifier = modifier, - icon = icon, + iconResId = iconResId, style = style, ) } @@ -43,7 +43,7 @@ private fun PrezelIconChipPreview() { @Composable private fun PrezelIconChipPreviewItem(style: PrezelChipStyle) { PrezelIconChip( - icon = IconSource(resId = PrezelIcons.Blank), + iconResId = PrezelIcons.Blank, style = style, ) } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/image/PrezelImage.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/image/PrezelImage.kt index 3c7c10f..4baf62c 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/image/PrezelImage.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/image/PrezelImage.kt @@ -130,7 +130,7 @@ private fun PrezelImagePreviewItem( ) { Text(text = label) PrezelImage( - resId = PrezelIcons.Calendar, + resId = PrezelIcons.Blank, contentDescription = label, modifier = Modifier.size(100.dp), rounded = rounded, diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/image/PrezelImageSource.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/image/PrezelImageSource.kt deleted file mode 100644 index 59700c7..0000000 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/image/PrezelImageSource.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.team.prezel.core.designsystem.component.image - -import androidx.compose.runtime.Immutable - -@Immutable -sealed interface PrezelImageSource { - @Immutable - data class Url( - val value: String, - ) : PrezelImageSource - - @Immutable - data class Drawable( - val resId: Int, - ) : PrezelImageSource -} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/snackbar/PrezelSnackbar.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/snackbar/PrezelSnackbar.kt index 46d7c1c..ccedaeb 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/snackbar/PrezelSnackbar.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/snackbar/PrezelSnackbar.kt @@ -1,5 +1,6 @@ package com.team.prezel.core.designsystem.component.snackbar +import androidx.annotation.DrawableRes import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -17,12 +18,12 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.component.actions.button.PrezelButton import com.team.prezel.core.designsystem.component.actions.button.config.ButtonSize import com.team.prezel.core.designsystem.component.actions.button.config.ButtonType import com.team.prezel.core.designsystem.foundation.typography.PrezelTextStyles -import com.team.prezel.core.designsystem.icon.IconSource import com.team.prezel.core.designsystem.icon.PrezelIcons import com.team.prezel.core.designsystem.preview.ThemePreview import com.team.prezel.core.designsystem.theme.PrezelColorScheme @@ -48,8 +49,8 @@ fun PrezelSnackbar( modifier = Modifier.padding(start = PrezelTheme.spacing.V16, end = PrezelTheme.spacing.V8), verticalAlignment = Alignment.CenterVertically, ) { - visuals.leadingIcon?.let { leadingIcon -> - PrezelSnackbarLeadingIcon(icon = leadingIcon) + visuals.leadingIconResId?.let { resId -> + PrezelSnackbarLeadingIcon(iconResId = resId) Spacer(Modifier.width(PrezelTheme.spacing.V8)) } @@ -74,12 +75,12 @@ fun PrezelSnackbar( @Composable private fun PrezelSnackbarLeadingIcon( - icon: IconSource, + @DrawableRes iconResId: Int, modifier: Modifier = Modifier, ) { Icon( - painter = icon.painter(), - contentDescription = icon.contentDescription(), + painter = painterResource(id = iconResId), + contentDescription = null, modifier = modifier.size(20.dp), tint = PrezelColorScheme.Dark.iconLarge, ) @@ -91,7 +92,7 @@ private fun PrezelSnackBarPreview_Cases() { PrezelTheme { Column { PrezelSnackbar( - data = previewData(message = "Message", actionLabel = "Action", leadingIcon = IconSource(PrezelIcons.Blank)), + data = previewData(message = "Message", actionLabel = "Action", iconResId = PrezelIcons.Blank), ) PrezelSnackbar( @@ -105,7 +106,7 @@ private fun PrezelSnackBarPreview_Cases() { private fun previewData( message: String, actionLabel: String, - leadingIcon: IconSource? = null, + @DrawableRes iconResId: Int? = null, ): SnackbarData = PreviewSnackbarData( visuals = PrezelSnackbarVisuals( @@ -113,7 +114,7 @@ private fun previewData( actionLabel = actionLabel, withDismissAction = false, duration = SnackbarDuration.Short, - leadingIcon = leadingIcon, + leadingIconResId = iconResId, offsetY = 0.dp, ), ) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/snackbar/SnackbarHost.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/snackbar/SnackbarHost.kt index 1947601..9d2fe2e 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/snackbar/SnackbarHost.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/snackbar/SnackbarHost.kt @@ -1,5 +1,6 @@ package com.team.prezel.core.designsystem.component.snackbar +import androidx.annotation.DrawableRes import androidx.compose.material3.SnackbarDuration import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState @@ -9,7 +10,6 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import com.team.prezel.core.designsystem.icon.IconSource internal data class PrezelSnackbarVisuals( override val message: String, @@ -17,7 +17,7 @@ internal data class PrezelSnackbarVisuals( override val withDismissAction: Boolean = false, override val duration: SnackbarDuration, val id: String? = null, - val leadingIcon: IconSource?, + @param:DrawableRes val leadingIconResId: Int?, val offsetY: Dp, ) : SnackbarVisuals @@ -25,7 +25,7 @@ suspend fun SnackbarHostState.showPrezelSnackbar( message: String, actionLabel: String, onAction: () -> Unit, - leadingIcon: IconSource? = null, + @DrawableRes leadingIconResId: Int? = null, duration: SnackbarDuration = SnackbarDuration.Short, id: String? = null, onDismiss: (() -> Unit)? = null, @@ -37,7 +37,7 @@ suspend fun SnackbarHostState.showPrezelSnackbar( actionLabel = actionLabel, duration = duration, id = id, - leadingIcon = leadingIcon, + leadingIconResId = leadingIconResId, offsetY = offsetY, ), ) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/icon/IconSource.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/icon/IconSource.kt deleted file mode 100644 index 74230d2..0000000 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/icon/IconSource.kt +++ /dev/null @@ -1,35 +0,0 @@ -package com.team.prezel.core.designsystem.icon - -import androidx.annotation.DrawableRes -import androidx.annotation.StringRes -import androidx.compose.runtime.Composable -import androidx.compose.runtime.Stable -import androidx.compose.ui.graphics.painter.Painter -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource - -@Stable -class IconSource private constructor( - private val painterProvider: @Composable () -> Painter, - private val contentDescProvider: @Composable () -> String?, -) { - @Composable - fun painter(): Painter = painterProvider() - - @Composable - fun contentDescription(): String? = contentDescProvider() - - constructor(painter: Painter, contentDescription: String? = null) : this( - painterProvider = { painter }, - contentDescProvider = { contentDescription }, - ) - - constructor( - @DrawableRes resId: Int, - @StringRes contentDescResId: Int? = null, - vararg args: String, - ) : this( - painterProvider = { painterResource(resId) }, - contentDescProvider = { contentDescResId?.let { stringResource(it, *args) } }, - ) -} From 0d403c1f311f9786f48b4271cb81cc05ebdde43f Mon Sep 17 00:00:00 2001 From: moondev03 Date: Wed, 25 Mar 2026 00:41:27 +0900 Subject: [PATCH 24/42] =?UTF-8?q?refactor:=20=EB=94=94=EC=9E=90=EC=9D=B8?= =?UTF-8?q?=20=EC=8B=9C=EC=8A=A4=ED=85=9C=20Preview=20=EC=9C=A0=ED=8B=B8?= =?UTF-8?q?=EB=A6=AC=ED=8B=B0=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0=20=EB=B0=8F=20=EA=B5=AC=EC=A1=B0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/designsystem/preview/BasicPreview.kt | 114 ++++++++ .../designsystem/preview/PreviewComponent.kt | 244 +++++++++++++----- .../core/designsystem/preview/ThemePreview.kt | 16 -- 3 files changed, 297 insertions(+), 77 deletions(-) create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/BasicPreview.kt delete mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/ThemePreview.kt diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/BasicPreview.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/BasicPreview.kt new file mode 100644 index 0000000..a807d33 --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/BasicPreview.kt @@ -0,0 +1,114 @@ +package com.team.prezel.core.designsystem.preview + +import android.content.res.Configuration +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +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.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +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 androidx.compose.ui.unit.dp +import com.team.prezel.core.designsystem.theme.PrezelTheme +import kotlinx.collections.immutable.ImmutableList + +@Preview( + showBackground = true, + backgroundColor = 0xFFFFFF, + uiMode = Configuration.UI_MODE_NIGHT_NO, +) +annotation class BasicPreview + +@Composable +internal fun PreviewScreen( + verticalArrangement: Arrangement.Vertical = Arrangement.spacedBy(16.dp), + content: @Composable () -> Unit, +) { + Scaffold( + containerColor = PrezelTheme.colors.bgRegular, + contentColor = PrezelTheme.colors.textLarge, + ) { innerPadding -> + Column( + modifier = Modifier + .padding(innerPadding) + .fillMaxSize() + .verticalScroll(rememberScrollState()) + .padding(16.dp), + verticalArrangement = verticalArrangement, + ) { + content() + } + } +} + +@Composable +internal fun PreviewTitle(title: String) { + Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { + Text(text = title, style = PrezelTheme.typography.title2Bold, color = PrezelTheme.colors.textLarge) + HorizontalDivider(color = PrezelTheme.colors.borderRegular) + } +} + +@Composable +internal fun PreviewTokenItems( + items: ImmutableList>, + preview: @Composable (Dp) -> Unit, +) { + Column(verticalArrangement = Arrangement.spacedBy(10.dp)) { + items.forEach { (name, value) -> + PreviewTokenItem( + name = name, + valueLabel = "${value.value}dp", + preview = { preview(value) }, + ) + } + } +} + +@Composable +internal fun PreviewTokenItem( + name: String, + valueLabel: String, + preview: @Composable () -> Unit, +) { + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(12.dp), + ) { + Text( + text = name, + style = PrezelTheme.typography.body3Medium, + color = PrezelTheme.colors.textMedium, + modifier = Modifier.width(120.dp), + ) + Text( + text = valueLabel, + style = PrezelTheme.typography.body3Regular, + color = PrezelTheme.colors.textSmall, + modifier = Modifier.weight(1f), + ) + Spacer(modifier = Modifier.weight(1f)) + Box( + modifier = Modifier + .background(Color.Transparent) + .padding(4.dp), + ) { + preview() + } + } +} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/PreviewComponent.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/PreviewComponent.kt index f91eaf8..6475fcd 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/PreviewComponent.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/PreviewComponent.kt @@ -3,103 +3,225 @@ package com.team.prezel.core.designsystem.preview import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.BoxScope import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.verticalScroll -import androidx.compose.material3.HorizontalDivider +import androidx.compose.foundation.layout.safeDrawing +import androidx.compose.foundation.lazy.grid.GridCells +import androidx.compose.foundation.lazy.grid.LazyVerticalGrid +import androidx.compose.foundation.lazy.grid.items import androidx.compose.material3.Scaffold +import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.Immutable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.theme.PrezelTheme -import kotlinx.collections.immutable.ImmutableList +/** + * Preview 공통 레이아웃 설정입니다. + */ +@Immutable +internal data class PreviewDefaults( + val screenPadding: PaddingValues = PaddingValues(16.dp), + val sectionSpacing: Dp = 24.dp, + val itemSpacing: Dp = 12.dp, +) + +/** + * 디자인시스템 Preview의 기본 배경, 패딩, 테마를 제공합니다. + * + * 대부분의 Preview는 이 컴포넌트로 감싸는 것을 권장합니다. + */ @Composable -internal fun PreviewScaffold( - verticalArrangement: Arrangement.Vertical = Arrangement.spacedBy(16.dp), - content: @Composable () -> Unit, +internal fun PreviewSurface( + modifier: Modifier = Modifier, + defaults: PreviewDefaults = PreviewDefaults(), + useSystemInsets: Boolean = false, + contentAlignment: Alignment = Alignment.TopStart, + content: @Composable BoxScope.() -> Unit, ) { - Scaffold( - containerColor = PrezelTheme.colors.bgRegular, - contentColor = PrezelTheme.colors.textLarge, - ) { innerPadding -> - Column( - modifier = Modifier - .padding(innerPadding) - .fillMaxSize() - .verticalScroll(rememberScrollState()) - .padding(16.dp), - verticalArrangement = verticalArrangement, + PrezelTheme { + Surface( + modifier = modifier.fillMaxSize(), + color = PrezelTheme.colors.bgRegular, ) { - content() + val containerModifier = Modifier + .fillMaxSize() + .background(PrezelTheme.colors.bgRegular) + .then( + if (useSystemInsets) { + Modifier.padding(WindowInsets.safeDrawing.asPaddingValues()) + } else { + Modifier + }, + ).padding(defaults.screenPadding) + + Box( + modifier = containerModifier, + contentAlignment = contentAlignment, + content = content, + ) } } } +/** + * Preview에서 여러 상태를 세로로 나열할 때 사용하는 공통 레이아웃입니다. + */ @Composable -internal fun SectionTitle(title: String) { - Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { - Text(text = title, style = PrezelTheme.typography.title2Bold, color = PrezelTheme.colors.textLarge) - HorizontalDivider(color = PrezelTheme.colors.borderRegular) - } +internal fun PreviewColumn( + modifier: Modifier = Modifier, + defaults: PreviewDefaults = PreviewDefaults(), + horizontalAlignment: Alignment.Horizontal = Alignment.Start, + content: @Composable ColumnScope.() -> Unit, +) { + Column( + modifier = modifier.fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(defaults.itemSpacing), + horizontalAlignment = horizontalAlignment, + content = content, + ) } +/** + * Preview에서 작은 컴포넌트를 가로로 비교할 때 사용하는 공통 레이아웃입니다. + */ @Composable -internal fun TokenList( - items: ImmutableList>, - preview: @Composable (Dp) -> Unit, +internal fun PreviewRow( + modifier: Modifier = Modifier, + defaults: PreviewDefaults = PreviewDefaults(), + verticalAlignment: Alignment.Vertical = Alignment.CenterVertically, + content: @Composable RowScope.() -> Unit, ) { - Column(verticalArrangement = Arrangement.spacedBy(10.dp)) { - items.forEach { (name, value) -> - TokenRow( - name = name, - valueLabel = "${value.value}dp", - preview = { preview(value) }, - ) + Row( + modifier = modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(defaults.itemSpacing), + verticalAlignment = verticalAlignment, + content = content, + ) +} + +/** + * Preview에서 반복 가능한 작은 컴포넌트를 그리드 형태로 보여줍니다. + * + * 칩, 아이콘 버튼, 배지처럼 여러 변형을 한 번에 확인할 때 유용합니다. + */ +@Composable +internal fun PreviewGrid( + items: List, + modifier: Modifier = Modifier, + columns: Int = 2, + defaults: PreviewDefaults = PreviewDefaults(), + key: ((T) -> Any)? = null, + itemContent: @Composable (T) -> Unit, +) { + require(columns > 0) { + "columns는 1 이상이어야 합니다." + } + + LazyVerticalGrid( + columns = GridCells.Fixed(columns), + modifier = modifier + .fillMaxWidth() + .fillMaxSize(), + horizontalArrangement = Arrangement.spacedBy(defaults.itemSpacing), + verticalArrangement = Arrangement.spacedBy(defaults.itemSpacing), + userScrollEnabled = true, + ) { + if (key == null) { + items(items) { item -> + itemContent(item) + } + return@LazyVerticalGrid + } + + items( + items = items, + key = key, + ) { item -> + itemContent(item) } } } +/** + * Preview 내에서 상태 그룹을 제목과 함께 구분해 보여줍니다. + */ @Composable -internal fun TokenRow( - name: String, - valueLabel: String, - preview: @Composable () -> Unit, +internal fun PreviewSection( + title: String, + modifier: Modifier = Modifier, + defaults: PreviewDefaults = PreviewDefaults(), + description: String? = null, + content: @Composable ColumnScope.() -> Unit, ) { - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(12.dp), + Column( + modifier = modifier.fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(defaults.itemSpacing), ) { Text( - text = name, - style = PrezelTheme.typography.body3Medium, - color = PrezelTheme.colors.textMedium, - modifier = Modifier.width(120.dp), + text = title, + style = PrezelTheme.typography.title2Medium, + color = PrezelTheme.colors.textLarge, ) - Text( - text = valueLabel, - style = PrezelTheme.typography.body3Regular, - color = PrezelTheme.colors.textSmall, - modifier = Modifier.weight(1f), + + description?.let { value -> + Text( + text = value, + style = PrezelTheme.typography.body3Regular, + color = PrezelTheme.colors.textRegular, + ) + } + + PreviewColumn( + defaults = defaults, + content = content, ) - Spacer(modifier = Modifier.weight(1f)) - Box( - modifier = Modifier - .background(Color.Transparent) - .padding(4.dp), - ) { - preview() + } +} + +/** + * TopBar, BottomBar, Snackbar 등 Scaffold 문맥이 필요한 Preview를 위한 래퍼입니다. + */ +@Composable +internal fun PreviewScaffold( + modifier: Modifier = Modifier, + defaults: PreviewDefaults = PreviewDefaults(), + topBar: @Composable () -> Unit = {}, + bottomBar: @Composable () -> Unit = {}, + floatingActionButton: @Composable () -> Unit = {}, + snackbarHost: @Composable () -> Unit = {}, + content: @Composable (PaddingValues) -> Unit, +) { + PrezelTheme { + Scaffold( + modifier = modifier.fillMaxSize(), + topBar = topBar, + bottomBar = bottomBar, + floatingActionButton = floatingActionButton, + snackbarHost = snackbarHost, + containerColor = PrezelTheme.colors.bgRegular, + ) { innerPadding -> + Box( + modifier = Modifier + .fillMaxSize() + .padding(innerPadding) + .padding(defaults.screenPadding), + ) { + content(innerPadding) + } } } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/ThemePreview.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/ThemePreview.kt deleted file mode 100644 index cf6a59e..0000000 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/ThemePreview.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.team.prezel.core.designsystem.preview - -import android.content.res.Configuration -import androidx.compose.ui.tooling.preview.Preview - -@Preview( - name = "LightTheme", - showBackground = true, - uiMode = Configuration.UI_MODE_NIGHT_NO, -) -// @Preview( -// name = "DarkTheme", -// showBackground = true, -// uiMode = Configuration.UI_MODE_NIGHT_YES, -// ) -annotation class ThemePreview From 6632e5447c465ec4e78639f797b7869a20b2796e Mon Sep 17 00:00:00 2001 From: moondev03 Date: Wed, 25 Mar 2026 00:56:12 +0900 Subject: [PATCH 25/42] =?UTF-8?q?refactor:=20=ED=94=84=EB=A6=AC=EB=B7=B0?= =?UTF-8?q?=20=EC=9C=A0=ED=8B=B8=EB=A6=AC=ED=8B=B0=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=ED=86=B5=ED=95=A9=20=EB=B0=8F=20=EA=B3=A0?= =?UTF-8?q?=EB=8F=84=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/designsystem/preview/BasicPreview.kt | 103 ------------------ .../designsystem/preview/PreviewComponent.kt | 64 ++++++++++- 2 files changed, 62 insertions(+), 105 deletions(-) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/BasicPreview.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/BasicPreview.kt index a807d33..8c47826 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/BasicPreview.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/BasicPreview.kt @@ -1,30 +1,7 @@ package com.team.prezel.core.designsystem.preview import android.content.res.Configuration -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement -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.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.verticalScroll -import androidx.compose.material3.HorizontalDivider -import androidx.compose.material3.Scaffold -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -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 androidx.compose.ui.unit.dp -import com.team.prezel.core.designsystem.theme.PrezelTheme -import kotlinx.collections.immutable.ImmutableList @Preview( showBackground = true, @@ -32,83 +9,3 @@ import kotlinx.collections.immutable.ImmutableList uiMode = Configuration.UI_MODE_NIGHT_NO, ) annotation class BasicPreview - -@Composable -internal fun PreviewScreen( - verticalArrangement: Arrangement.Vertical = Arrangement.spacedBy(16.dp), - content: @Composable () -> Unit, -) { - Scaffold( - containerColor = PrezelTheme.colors.bgRegular, - contentColor = PrezelTheme.colors.textLarge, - ) { innerPadding -> - Column( - modifier = Modifier - .padding(innerPadding) - .fillMaxSize() - .verticalScroll(rememberScrollState()) - .padding(16.dp), - verticalArrangement = verticalArrangement, - ) { - content() - } - } -} - -@Composable -internal fun PreviewTitle(title: String) { - Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { - Text(text = title, style = PrezelTheme.typography.title2Bold, color = PrezelTheme.colors.textLarge) - HorizontalDivider(color = PrezelTheme.colors.borderRegular) - } -} - -@Composable -internal fun PreviewTokenItems( - items: ImmutableList>, - preview: @Composable (Dp) -> Unit, -) { - Column(verticalArrangement = Arrangement.spacedBy(10.dp)) { - items.forEach { (name, value) -> - PreviewTokenItem( - name = name, - valueLabel = "${value.value}dp", - preview = { preview(value) }, - ) - } - } -} - -@Composable -internal fun PreviewTokenItem( - name: String, - valueLabel: String, - preview: @Composable () -> Unit, -) { - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.spacedBy(12.dp), - ) { - Text( - text = name, - style = PrezelTheme.typography.body3Medium, - color = PrezelTheme.colors.textMedium, - modifier = Modifier.width(120.dp), - ) - Text( - text = valueLabel, - style = PrezelTheme.typography.body3Regular, - color = PrezelTheme.colors.textSmall, - modifier = Modifier.weight(1f), - ) - Spacer(modifier = Modifier.weight(1f)) - Box( - modifier = Modifier - .background(Color.Transparent) - .padding(4.dp), - ) { - preview() - } - } -} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/PreviewComponent.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/PreviewComponent.kt index 6475fcd..5ec7f4a 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/PreviewComponent.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/PreviewComponent.kt @@ -9,15 +9,20 @@ import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.safeDrawing +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.foundation.lazy.grid.LazyVerticalGrid import androidx.compose.foundation.lazy.grid.items +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Scaffold import androidx.compose.material3.Surface import androidx.compose.material3.Text @@ -84,12 +89,23 @@ internal fun PreviewSurface( internal fun PreviewColumn( modifier: Modifier = Modifier, defaults: PreviewDefaults = PreviewDefaults(), + scrollable: Boolean = false, + verticalArrangement: Arrangement.Vertical = Arrangement.spacedBy(defaults.itemSpacing), horizontalAlignment: Alignment.Horizontal = Alignment.Start, content: @Composable ColumnScope.() -> Unit, ) { + val scrollModifier = + if (scrollable) { + Modifier.verticalScroll(rememberScrollState()) + } else { + Modifier + } + Column( - modifier = modifier.fillMaxWidth(), - verticalArrangement = Arrangement.spacedBy(defaults.itemSpacing), + modifier = modifier + .fillMaxWidth() + .then(scrollModifier), + verticalArrangement = verticalArrangement, horizontalAlignment = horizontalAlignment, content = content, ) @@ -165,6 +181,7 @@ internal fun PreviewSection( modifier: Modifier = Modifier, defaults: PreviewDefaults = PreviewDefaults(), description: String? = null, + showDivider: Boolean = false, content: @Composable ColumnScope.() -> Unit, ) { Column( @@ -177,6 +194,10 @@ internal fun PreviewSection( color = PrezelTheme.colors.textLarge, ) + if (showDivider) { + HorizontalDivider(color = PrezelTheme.colors.borderRegular) + } + description?.let { value -> Text( text = value, @@ -192,6 +213,45 @@ internal fun PreviewSection( } } +/** + * Preview에서 토큰처럼 이름, 값, 샘플 UI를 한 줄에 보여줄 때 사용하는 행 레이아웃입니다. + */ +@Composable +internal fun PreviewValueRow( + name: String, + valueLabel: String, + modifier: Modifier = Modifier, + nameWidth: Dp = 120.dp, + preview: @Composable () -> Unit, +) { + Row( + modifier = modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(12.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + text = name, + style = PrezelTheme.typography.body3Medium, + color = PrezelTheme.colors.textMedium, + modifier = Modifier.width(nameWidth), + ) + Text( + text = valueLabel, + style = PrezelTheme.typography.body3Regular, + color = PrezelTheme.colors.textSmall, + modifier = Modifier.weight(1f), + ) + Spacer(modifier = Modifier.weight(1f)) + Box( + modifier = Modifier + .background(PrezelTheme.colors.bgRegular) + .padding(4.dp), + ) { + preview() + } + } +} + /** * TopBar, BottomBar, Snackbar 등 Scaffold 문맥이 필요한 Preview를 위한 래퍼입니다. */ From a46acc3b5e6ed3794dfad2d36b5488aed0dc74f2 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Wed, 25 Mar 2026 00:56:29 +0900 Subject: [PATCH 26/42] =?UTF-8?q?refactor:=20=EB=94=94=EC=9E=90=EC=9D=B8?= =?UTF-8?q?=20=EC=8B=9C=EC=8A=A4=ED=85=9C=20Preview=20=EC=8B=9C=EC=8A=A4?= =?UTF-8?q?=ED=85=9C=20=EA=B0=9C=ED=8E=B8=20=EB=B0=8F=20=EA=B4=80=EB=A0=A8?= =?UTF-8?q?=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EB=A6=AC=ED=8C=A9?= =?UTF-8?q?=ED=84=B0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../designsystem/component/PrezelAccordion.kt | 11 +- .../designsystem/component/PrezelAvatar.kt | 6 +- .../designsystem/component/PrezelCheckbox.kt | 6 +- .../designsystem/component/PrezelDivider.kt | 44 ++-- .../component/PrezelNavigationBar.kt | 4 +- .../designsystem/component/PrezelRadio.kt | 52 ++-- .../core/designsystem/component/PrezelTabs.kt | 6 +- .../core/designsystem/component/TopAppBar.kt | 10 +- .../actions/area/PrezelButtonArea.kt | 39 ++- .../actions/button/PrezelHyperlinkButton.kt | 4 +- .../button/config/PrezelButtonPreview.kt | 51 ++-- .../button/floating/PrezelFloatingButton.kt | 4 +- .../button/floating/PrezelFloatingMenu.kt | 4 +- .../button/floating/menu/PrezelMenu.kt | 4 +- .../button/floating/menu/PrezelMenuItem.kt | 4 +- .../component/base/PrezelDropShadow.kt | 4 +- .../component/base/PrezelTouchArea.kt | 4 +- .../designsystem/component/chip/PrezelChip.kt | 12 +- .../component/chip/PrezelCustomChipPreview.kt | 30 ++- .../component/chip/PrezelIconChip.kt | 12 +- .../datepicker/DatePickerDayCellView.kt | 4 +- .../component/datepicker/MonthGrid.kt | 4 +- .../component/datepicker/MonthSection.kt | 4 +- .../component/image/PrezelImage.kt | 4 +- .../designsystem/component/list/PrezelList.kt | 60 ++--- .../component/snackbar/PrezelSnackbar.kt | 4 +- .../component/textfield/PrezelTextArea.kt | 20 +- .../component/textfield/PrezelTextField.kt | 20 +- .../component/PrezelTextFieldLabel.kt | 4 +- .../component/PrezelTextFieldPlaceholder.kt | 4 +- .../PrezelTextFieldSupportingText.kt | 4 +- .../foundation/number/PrezelRadius.kt | 61 +++-- .../foundation/number/PrezelShapes.kt | 64 ++--- .../foundation/number/PrezelSpacing.kt | 49 ++-- .../foundation/number/PrezelStroke.kt | 53 ++-- .../designsystem/theme/PrezelColorScheme.kt | 236 ++++++++---------- .../theme/PrezelTypographyScheme.kt | 95 +++---- .../core/designsystem/util/DrawDashBorder.kt | 4 +- .../prezel/feature/login/impl/LoginScreen.kt | 4 +- .../feature/splash/impl/SplashScreen.kt | 4 +- 40 files changed, 511 insertions(+), 502 deletions(-) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelAccordion.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelAccordion.kt index 1662a63..1a2f799 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelAccordion.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelAccordion.kt @@ -37,8 +37,9 @@ import com.team.prezel.core.designsystem.component.list.PrezelList import com.team.prezel.core.designsystem.component.list.PrezelListSize 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.preview.BasicPreview +import com.team.prezel.core.designsystem.preview.PreviewColumn +import com.team.prezel.core.designsystem.preview.PreviewSurface import com.team.prezel.core.designsystem.theme.PrezelTheme import com.team.prezel.core.designsystem.util.drawDashBorder @@ -129,11 +130,11 @@ private fun PrezelAccordionContent( } } -@ThemePreview +@BasicPreview @Composable private fun PrezelAccordionPreview() { - PrezelTheme { - PreviewScaffold { + PreviewSurface { + PreviewColumn(scrollable = true) { Column(verticalArrangement = Arrangement.spacedBy(40.dp)) { PrezelAccordion( title = "Collapsed Accordion", diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelAvatar.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelAvatar.kt index 1a7f12e..1503983 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelAvatar.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelAvatar.kt @@ -24,7 +24,7 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.R import com.team.prezel.core.designsystem.foundation.number.PrezelStroke -import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.preview.BasicPreview import com.team.prezel.core.designsystem.theme.PrezelTheme @Composable @@ -109,7 +109,7 @@ private fun DefaultAvatarIcon( ) } -@ThemePreview +@BasicPreview @Composable private fun PrezelAvatarSizePreview() { PrezelTheme { @@ -133,7 +133,7 @@ private fun PrezelAvatarSizePreview() { } } -@ThemePreview +@BasicPreview @Composable private fun PrezelAvatarTypePreview() { PrezelTheme { diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelCheckbox.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelCheckbox.kt index 926a7ab..09b6346 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelCheckbox.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelCheckbox.kt @@ -25,7 +25,7 @@ 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.ThemePreview +import com.team.prezel.core.designsystem.preview.BasicPreview import com.team.prezel.core.designsystem.theme.PrezelTheme import com.team.prezel.core.designsystem.util.drawDashBorder @@ -81,7 +81,7 @@ fun PrezelCheckbox( } } -@ThemePreview +@BasicPreview @Composable private fun PrezelRegularCheckboxPreview() { PrezelTheme { @@ -111,7 +111,7 @@ private fun PrezelRegularCheckboxPreview() { } } -@ThemePreview +@BasicPreview @Composable private fun PrezelLargeCheckboxPreview() { PrezelTheme { diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelDivider.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelDivider.kt index 094c069..eec8830 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelDivider.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelDivider.kt @@ -1,6 +1,5 @@ package com.team.prezel.core.designsystem.component -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.height import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Text @@ -10,9 +9,10 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import com.team.prezel.core.designsystem.preview.PreviewScaffold -import com.team.prezel.core.designsystem.preview.SectionTitle -import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.preview.BasicPreview +import com.team.prezel.core.designsystem.preview.PreviewColumn +import com.team.prezel.core.designsystem.preview.PreviewSection +import com.team.prezel.core.designsystem.preview.PreviewSurface import com.team.prezel.core.designsystem.theme.PrezelTheme enum class PrezelDividerType( @@ -59,24 +59,30 @@ private fun PrezelDivider( } } -@ThemePreview +@BasicPreview @Composable private fun PrezelDividerPreview() { - PrezelTheme { - PreviewScaffold { - SectionTitle(title = "PrezelDivider - Horizontal") - Text("PrezelDividerType.DEFAULT") - PrezelHorizontalDivider(type = PrezelDividerType.DEFAULT) - Text("PrezelDividerType.THICK") - PrezelHorizontalDivider(type = PrezelDividerType.THICK) + PreviewSurface { + PreviewColumn(scrollable = true) { + PreviewSection( + title = "PrezelDivider - Horizontal", + showDivider = true, + ) { + Text("PrezelDividerType.DEFAULT") + PrezelHorizontalDivider(type = PrezelDividerType.DEFAULT) + Text("PrezelDividerType.THICK") + PrezelHorizontalDivider(type = PrezelDividerType.THICK) + } - Spacer(modifier = Modifier.height(20.dp)) - - SectionTitle(title = "PrezelDivider - Vertical") - Text("PrezelDividerType.DEFAULT") - PrezelVerticalDivider(type = PrezelDividerType.DEFAULT, modifier = Modifier.height(100.dp)) - Text("PrezelDividerType.THICK") - PrezelVerticalDivider(type = PrezelDividerType.THICK, modifier = Modifier.height(100.dp)) + PreviewSection( + title = "PrezelDivider - Vertical", + showDivider = true, + ) { + Text("PrezelDividerType.DEFAULT") + PrezelVerticalDivider(type = PrezelDividerType.DEFAULT, modifier = Modifier.height(100.dp)) + Text("PrezelDividerType.THICK") + PrezelVerticalDivider(type = PrezelDividerType.THICK, modifier = Modifier.height(100.dp)) + } } } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelNavigationBar.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelNavigationBar.kt index db2e3f1..ab3fafc 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelNavigationBar.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelNavigationBar.kt @@ -29,7 +29,7 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.component.snackbar.PrezelSnackbarHost import com.team.prezel.core.designsystem.icon.PrezelIcons -import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.preview.BasicPreview import com.team.prezel.core.designsystem.theme.PrezelTheme @Composable @@ -145,7 +145,7 @@ class PrezelNavigationScope internal constructor( } } -@ThemePreview +@BasicPreview @Composable private fun PrezelNavigationScaffoldPreview() { var selectedIndex by rememberSaveable { mutableIntStateOf(0) } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelRadio.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelRadio.kt index c46b7e4..819338e 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelRadio.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelRadio.kt @@ -3,7 +3,6 @@ package com.team.prezel.core.designsystem.component import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width @@ -26,9 +25,10 @@ import androidx.compose.ui.text.TextStyle import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.icon.PrezelIcons -import com.team.prezel.core.designsystem.preview.PreviewScaffold -import com.team.prezel.core.designsystem.preview.SectionTitle -import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.preview.BasicPreview +import com.team.prezel.core.designsystem.preview.PreviewColumn +import com.team.prezel.core.designsystem.preview.PreviewSection +import com.team.prezel.core.designsystem.preview.PreviewSurface import com.team.prezel.core.designsystem.theme.PrezelTheme /** @@ -128,30 +128,36 @@ private fun PrezelRadioIcon( ) } -@ThemePreview +@BasicPreview @Composable private fun PrezelRadioPreview() { var checked by remember { mutableStateOf(false) } - PrezelTheme { - PreviewScaffold { - SectionTitle("PrezelRadioSize.REGULAR") - Text("Checked: true") - PrezelRadio(checked = true, onCheckedChange = {}, size = PrezelRadioSize.REGULAR) - Text("Checked: false") - PrezelRadio(checked = false, onCheckedChange = {}, size = PrezelRadioSize.REGULAR) - Text("PrezelRadio with text") - PrezelRadio(checked = checked, onCheckedChange = { checked = it }, text = "텍스트", size = PrezelRadioSize.REGULAR) + PreviewSurface { + PreviewColumn(scrollable = true) { + PreviewSection( + title = "PrezelRadioSize.REGULAR", + showDivider = true, + ) { + Text("Checked: true") + PrezelRadio(checked = true, onCheckedChange = {}, size = PrezelRadioSize.REGULAR) + Text("Checked: false") + PrezelRadio(checked = false, onCheckedChange = {}, size = PrezelRadioSize.REGULAR) + Text("PrezelRadio with text") + PrezelRadio(checked = checked, onCheckedChange = { checked = it }, text = "텍스트", size = PrezelRadioSize.REGULAR) + } - Spacer(modifier = Modifier.height(20.dp)) - - SectionTitle("PrezelRadioSize.LARGE") - Text("Checked: true") - PrezelRadio(checked = true, onCheckedChange = {}, size = PrezelRadioSize.LARGE) - Text("Checked: false") - PrezelRadio(checked = false, onCheckedChange = {}, size = PrezelRadioSize.LARGE) - Text("PrezelRadio with text") - PrezelRadio(checked = checked, onCheckedChange = { checked = it }, text = "텍스트", size = PrezelRadioSize.LARGE) + PreviewSection( + title = "PrezelRadioSize.LARGE", + showDivider = true, + ) { + Text("Checked: true") + PrezelRadio(checked = true, onCheckedChange = {}, size = PrezelRadioSize.LARGE) + Text("Checked: false") + PrezelRadio(checked = false, onCheckedChange = {}, size = PrezelRadioSize.LARGE) + Text("PrezelRadio with text") + PrezelRadio(checked = checked, onCheckedChange = { checked = it }, text = "텍스트", size = PrezelRadioSize.LARGE) + } } } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelTabs.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelTabs.kt index 649d409..0551a29 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelTabs.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelTabs.kt @@ -20,7 +20,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.foundation.typography.PrezelTextStyles -import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.preview.BasicPreview import com.team.prezel.core.designsystem.theme.PrezelTheme import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf @@ -150,7 +150,7 @@ private fun handleTabClick( } } -@ThemePreview +@BasicPreview @Composable private fun PrezelMediumTabPreview() { val tabs = persistentListOf("Label1", "Label2", "Label3") @@ -179,7 +179,7 @@ private fun PrezelMediumTabPreview() { } } -@ThemePreview +@BasicPreview @Composable private fun PrezelSmallTabPreview() { val tabs = persistentListOf("Label1", "Label2") diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/TopAppBar.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/TopAppBar.kt index b21c07f..8b2eba2 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/TopAppBar.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/TopAppBar.kt @@ -22,7 +22,7 @@ import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.icon.PrezelIcons -import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.preview.BasicPreview import com.team.prezel.core.designsystem.theme.PrezelTheme @OptIn(ExperimentalMaterial3Api::class) @@ -60,7 +60,7 @@ private fun prezelTopAppBarColors() = ) @OptIn(ExperimentalMaterial3Api::class) -@ThemePreview +@BasicPreview @Composable private fun PrezelTopAppBarTitleOnlyPreview() { PrezelTheme { @@ -71,7 +71,7 @@ private fun PrezelTopAppBarTitleOnlyPreview() { } @OptIn(ExperimentalMaterial3Api::class) -@ThemePreview +@BasicPreview @Composable private fun PrezelTopAppBarWithLeadingPreview() { PrezelTheme { @@ -92,7 +92,7 @@ private fun PrezelTopAppBarWithLeadingPreview() { } @OptIn(ExperimentalMaterial3Api::class) -@ThemePreview +@BasicPreview @Composable private fun PrezelTopAppBarWithAllIconsPreview() { PrezelTheme { @@ -127,7 +127,7 @@ private fun PrezelTopAppBarWithAllIconsPreview() { } @OptIn(ExperimentalMaterial3Api::class) -@ThemePreview +@BasicPreview @Composable private fun PrezelTopAppBarScrollTestPreview() { PrezelTheme { diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonArea.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonArea.kt index ea85449..1619c65 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonArea.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonArea.kt @@ -18,15 +18,15 @@ 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.Color import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.component.PrezelDividerType import com.team.prezel.core.designsystem.component.PrezelHorizontalDivider import com.team.prezel.core.designsystem.icon.PrezelIcons -import com.team.prezel.core.designsystem.preview.PreviewScaffold -import com.team.prezel.core.designsystem.preview.SectionTitle +import com.team.prezel.core.designsystem.preview.PreviewColumn +import com.team.prezel.core.designsystem.preview.PreviewSection +import com.team.prezel.core.designsystem.preview.PreviewSurface import com.team.prezel.core.designsystem.theme.PrezelTheme /** @@ -130,21 +130,16 @@ private val buttonAreaPreviewStates = @Preview(device = "spec:width=1080dp,height=1800dp") @Composable private fun PrezelButtonAreaPreview() { - PrezelTheme { - PreviewScaffold { - SectionTitle(title = "Button Area") - Text( - text = "행은 버튼 상태, 열은 배경 여부입니다. 각 섹션은 배치 방향과 강도 옵션을 구분합니다.", - style = PrezelTheme.typography.body3Regular, - color = PrezelTheme.colors.textMedium, - modifier = Modifier - .fillMaxWidth() - .background(Color.LightGray.copy(alpha = 0.4f)) - .padding(8.dp), - ) - - buttonAreaPreviewVariants.forEach { variant -> - ButtonAreaPreviewSection(variant = variant) + PreviewSurface { + PreviewColumn(scrollable = true) { + PreviewSection( + title = "Button Area", + description = "행은 버튼 상태, 열은 배경 여부입니다. 각 섹션은 배치 방향과 강도 옵션을 구분합니다.", + showDivider = true, + ) { + buttonAreaPreviewVariants.forEach { variant -> + ButtonAreaPreviewSection(variant = variant) + } } } } @@ -152,13 +147,7 @@ private fun PrezelButtonAreaPreview() { @Composable private fun ButtonAreaPreviewSection(variant: ButtonAreaPreviewVariant) { - Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { - Text( - text = variant.title, - style = PrezelTheme.typography.body3Bold, - color = PrezelTheme.colors.textLarge, - ) - + PreviewSection(title = variant.title) { Column( modifier = Modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(0.dp), diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelHyperlinkButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelHyperlinkButton.kt index c3fc673..9a25efc 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelHyperlinkButton.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelHyperlinkButton.kt @@ -14,7 +14,7 @@ import com.team.prezel.core.designsystem.component.actions.button.config.ButtonT import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonBase import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefault import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefaults -import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.preview.BasicPreview import com.team.prezel.core.designsystem.theme.PrezelTheme /** @@ -62,7 +62,7 @@ private fun Modifier.prezelButtonUnderline(): Modifier { } } -@ThemePreview +@BasicPreview @Composable private fun PrezelHyperlinkButtonPreview() { PrezelTheme { diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonPreview.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonPreview.kt index 1738870..f76d896 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonPreview.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonPreview.kt @@ -15,15 +15,15 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp -import com.team.prezel.core.designsystem.preview.PreviewScaffold -import com.team.prezel.core.designsystem.preview.SectionTitle +import com.team.prezel.core.designsystem.preview.PreviewColumn +import com.team.prezel.core.designsystem.preview.PreviewSection +import com.team.prezel.core.designsystem.preview.PreviewSurface import com.team.prezel.core.designsystem.theme.PrezelTheme import com.team.prezel.core.designsystem.util.drawDashBorder -private data class PreviewSection( +private data class ButtonPreviewGroup( val title: String, val enabled: Boolean, val isRounded: Boolean, @@ -31,10 +31,10 @@ private data class PreviewSection( private val previewSections = listOf( - PreviewSection(title = "Enabled / Default", enabled = true, isRounded = false), - PreviewSection(title = "Enabled / Rounded", enabled = true, isRounded = true), - PreviewSection(title = "Disabled / Default", enabled = false, isRounded = false), - PreviewSection(title = "Disabled / Rounded", enabled = false, isRounded = true), + ButtonPreviewGroup(title = "Enabled / Default", enabled = true, isRounded = false), + ButtonPreviewGroup(title = "Enabled / Rounded", enabled = true, isRounded = true), + ButtonPreviewGroup(title = "Disabled / Default", enabled = false, isRounded = false), + ButtonPreviewGroup(title = "Disabled / Rounded", enabled = false, isRounded = true), ) @Composable @@ -42,26 +42,21 @@ internal fun PrezelButtonPreviewContent( title: String, content: @Composable (ButtonType, ButtonHierarchy, ButtonSize, Boolean, Boolean) -> Unit, ) { - PrezelTheme { - PreviewScaffold { - SectionTitle(title = title) - Text( - text = "행은 Size, 열은 Type과 Hierarchy 조합입니다. 각 섹션은 Enabled와 Rounded 상태를 구분합니다.", - style = PrezelTheme.typography.body3Regular, - color = PrezelTheme.colors.textMedium, - modifier = Modifier - .fillMaxWidth() - .background(Color.LightGray.copy(alpha = 0.4f)) - .padding(8.dp), - ) - - previewSections.forEach { section -> - ButtonPreviewSection( - title = section.title, - enabled = section.enabled, - isRounded = section.isRounded, - content = content, - ) + PreviewSurface { + PreviewColumn(scrollable = true) { + PreviewSection( + title = title, + description = "행은 Size, 열은 Type과 Hierarchy 조합입니다. 각 섹션은 Enabled와 Rounded 상태를 구분합니다.", + showDivider = true, + ) { + previewSections.forEach { section -> + ButtonPreviewSection( + title = section.title, + enabled = section.enabled, + isRounded = section.isRounded, + content = content, + ) + } } } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingButton.kt index 78bf583..cdd864b 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingButton.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingButton.kt @@ -18,7 +18,7 @@ import com.team.prezel.core.designsystem.component.actions.button.config.ButtonS import com.team.prezel.core.designsystem.component.base.PrezelDropShadowDefaults import com.team.prezel.core.designsystem.component.base.prezelDropShadow import com.team.prezel.core.designsystem.icon.PrezelIcons -import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.preview.BasicPreview import com.team.prezel.core.designsystem.theme.PrezelTheme /** @@ -48,7 +48,7 @@ fun PrezelFloatingButton( ) } -@ThemePreview +@BasicPreview @Composable private fun PrezelFloatingButtonPreview() { var expanded by remember { mutableStateOf(false) } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingMenu.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingMenu.kt index 2b2ea11..d84afab 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingMenu.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingMenu.kt @@ -23,7 +23,7 @@ import com.team.prezel.core.designsystem.component.actions.button.floating.menu. import com.team.prezel.core.designsystem.component.actions.button.floating.menu.PrezelMenu import com.team.prezel.core.designsystem.component.actions.button.floating.menu.PrezelMenuScope import com.team.prezel.core.designsystem.icon.PrezelIcons -import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.preview.BasicPreview import com.team.prezel.core.designsystem.theme.PrezelTheme /** @@ -68,7 +68,7 @@ fun PrezelFloatingMenu( } } -@ThemePreview +@BasicPreview @Composable private fun PrezelFloatingMenuPreview() { var expanded by remember { mutableStateOf(true) } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenu.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenu.kt index 2ce5580..f91b995 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenu.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenu.kt @@ -12,7 +12,7 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.icon.PrezelIcons -import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.preview.BasicPreview import com.team.prezel.core.designsystem.theme.PrezelTheme /** @@ -38,7 +38,7 @@ fun PrezelMenu( } } -@ThemePreview +@BasicPreview @Composable private fun PrezelMenuPreview() { PrezelTheme { diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuItem.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuItem.kt index aaa69ac..e206d5e 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuItem.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuItem.kt @@ -16,7 +16,7 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.component.base.PrezelTouchArea import com.team.prezel.core.designsystem.icon.PrezelIcons -import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.preview.BasicPreview import com.team.prezel.core.designsystem.theme.PrezelTheme import com.team.prezel.core.designsystem.util.drawDashBorder @@ -74,7 +74,7 @@ private fun PrezelMenuItemLayout( } } -@ThemePreview +@BasicPreview @Composable private fun PrezelMenuMenuItemPreview() { PrezelTheme { diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelDropShadow.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelDropShadow.kt index 9529674..81cd136 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelDropShadow.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelDropShadow.kt @@ -31,7 +31,7 @@ import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.preview.BasicPreview import com.team.prezel.core.designsystem.theme.PrezelTheme /** @@ -327,7 +327,7 @@ object PrezelDropShadowDefaults { ) } -@ThemePreview +@BasicPreview @Composable private fun PrezelDropShadowPreview() { val styles = listOf( diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelTouchArea.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelTouchArea.kt index 4845b99..825bfa4 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelTouchArea.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelTouchArea.kt @@ -18,7 +18,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.RectangleShape import androidx.compose.ui.graphics.Shape import androidx.compose.ui.unit.dp -import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.preview.BasicPreview import com.team.prezel.core.designsystem.theme.PrezelTheme /** @@ -53,7 +53,7 @@ fun PrezelTouchArea( } } -@ThemePreview +@BasicPreview @Composable private fun PrezelTouchAreaPreview() { PrezelTheme { diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelChip.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelChip.kt index 60867d5..4437aa0 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelChip.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelChip.kt @@ -19,9 +19,9 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource 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 +import com.team.prezel.core.designsystem.preview.BasicPreview +import com.team.prezel.core.designsystem.preview.PreviewColumn +import com.team.prezel.core.designsystem.preview.PreviewSurface @Composable fun PrezelChip( @@ -98,11 +98,11 @@ private fun PrezelChipIcon( ) } -@ThemePreview +@BasicPreview @Composable private fun PrezelChipPreview() { - PrezelTheme { - PreviewScaffold { + PreviewSurface { + PreviewColumn(scrollable = true) { PrezelChipPreviewByType( type = PrezelChipType.FILLED, ) { style -> PrezelChipPreviewItem(style) } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelCustomChipPreview.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelCustomChipPreview.kt index 2546284..9c1cc68 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelCustomChipPreview.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelCustomChipPreview.kt @@ -12,30 +12,28 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp 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.preview.BasicPreview +import com.team.prezel.core.designsystem.preview.PreviewColumn +import com.team.prezel.core.designsystem.preview.PreviewSection +import com.team.prezel.core.designsystem.preview.PreviewSurface import com.team.prezel.core.designsystem.theme.PrezelTheme -@ThemePreview +@BasicPreview @Composable private fun PrezelChip_CustomColors_Preview() { - PrezelTheme { - PreviewScaffold { - CustomChipHeader() - CustomChipLabelSection() - CustomChipIconOnlySection() + PreviewSurface { + PreviewColumn(scrollable = true) { + PreviewSection( + title = "Custom Chip", + showDivider = true, + ) { + CustomChipLabelSection() + CustomChipIconOnlySection() + } } } } -@Composable -private fun CustomChipHeader() { - Text( - text = "Custom Chip", - style = PrezelTheme.typography.title2Medium, - ) -} - @Composable private fun CustomChipLabelSection() { FlowRow( diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelIconChip.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelIconChip.kt index a62a71a..080b5f1 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelIconChip.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelIconChip.kt @@ -5,9 +5,9 @@ import androidx.compose.material3.HorizontalDivider import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier 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 +import com.team.prezel.core.designsystem.preview.BasicPreview +import com.team.prezel.core.designsystem.preview.PreviewColumn +import com.team.prezel.core.designsystem.preview.PreviewSurface @Composable fun PrezelIconChip( @@ -22,11 +22,11 @@ fun PrezelIconChip( ) } -@ThemePreview +@BasicPreview @Composable private fun PrezelIconChipPreview() { - PrezelTheme { - PreviewScaffold { + PreviewSurface { + PreviewColumn(scrollable = true) { PrezelChipPreviewByType( type = PrezelChipType.FILLED, ) { style -> PrezelIconChipPreviewItem(style) } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/DatePickerDayCellView.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/DatePickerDayCellView.kt index 3aa2aaf..1f35b47 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/DatePickerDayCellView.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/DatePickerDayCellView.kt @@ -17,7 +17,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp -import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.preview.BasicPreview import com.team.prezel.core.designsystem.theme.PrezelTheme import kotlinx.datetime.LocalDate @@ -61,7 +61,7 @@ internal fun RowScope.DayCellView( } } -@ThemePreview +@BasicPreview @Composable private fun DayCellViewPreview() { PrezelTheme { diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/MonthGrid.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/MonthGrid.kt index 0d70efe..f060372 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/MonthGrid.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/MonthGrid.kt @@ -7,7 +7,7 @@ import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Modifier -import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.preview.BasicPreview import com.team.prezel.core.designsystem.theme.PrezelTheme import kotlinx.collections.immutable.ImmutableList import kotlinx.datetime.DayOfWeek @@ -68,7 +68,7 @@ private fun WeekRow( } } -@ThemePreview +@BasicPreview @Composable private fun MonthGridPreview() { PrezelTheme { diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/MonthSection.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/MonthSection.kt index 12a57bb..7485f31 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/MonthSection.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/MonthSection.kt @@ -7,7 +7,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import com.team.prezel.core.designsystem.R -import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.preview.BasicPreview import com.team.prezel.core.designsystem.theme.PrezelTheme import kotlinx.datetime.LocalDate import kotlinx.datetime.YearMonth @@ -42,7 +42,7 @@ internal fun MonthSection( } } -@ThemePreview +@BasicPreview @Composable private fun MonthSectionPreview() { PrezelTheme { diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/image/PrezelImage.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/image/PrezelImage.kt index 4baf62c..68482d3 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/image/PrezelImage.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/image/PrezelImage.kt @@ -23,7 +23,7 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.component.PrezelAsyncImage import com.team.prezel.core.designsystem.icon.PrezelIcons -import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.preview.BasicPreview import com.team.prezel.core.designsystem.theme.PrezelTheme @Composable @@ -85,7 +85,7 @@ private fun Modifier.prezelImageContainer( .then(if (borderStroke != null) Modifier.border(borderStroke, shape) else Modifier) } -@ThemePreview +@BasicPreview @Composable private fun PrezelImagePreview() { PrezelTheme { diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/list/PrezelList.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/list/PrezelList.kt index cf2ffc5..cf078ed 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/list/PrezelList.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/list/PrezelList.kt @@ -1,6 +1,5 @@ package com.team.prezel.core.designsystem.component.list -import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.RowScope @@ -15,13 +14,13 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.icon.PrezelIcons -import com.team.prezel.core.designsystem.preview.PreviewScaffold -import com.team.prezel.core.designsystem.preview.SectionTitle -import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.preview.BasicPreview +import com.team.prezel.core.designsystem.preview.PreviewColumn +import com.team.prezel.core.designsystem.preview.PreviewSection +import com.team.prezel.core.designsystem.preview.PreviewSurface import com.team.prezel.core.designsystem.theme.PrezelTheme import com.team.prezel.core.designsystem.util.drawDashBorder @@ -74,21 +73,21 @@ private fun RowScope.PrezelListTitle( ) } -@ThemePreview +@BasicPreview @Composable private fun PrezelListSmallPreview() { - PrezelTheme { - PreviewScaffold { + PreviewSurface { + PreviewColumn(scrollable = true) { PrezelListPreviewBySize(PrezelListSize.SMALL) } } } -@ThemePreview +@BasicPreview @Composable private fun PrezelListRegularPreview() { - PrezelTheme { - PreviewScaffold { + PreviewSurface { + PreviewColumn(scrollable = true) { PrezelListPreviewBySize(PrezelListSize.REGULAR) } } @@ -131,27 +130,22 @@ private fun PrezelListPreviewItem( @Composable private fun PrezelListPreviewBySize(size: PrezelListSize) { - SectionTitle(title = "PrezelList - $size") - Text( - text = "점선 테두리는 컴포넌트 경계를 의미하며,\nnested 상태별 leading/trailing 조합을 확인할 수 있습니다.", - style = PrezelTheme.typography.body3Regular, - color = PrezelTheme.colors.textMedium, - modifier = Modifier - .fillMaxWidth() - .background(Color.LightGray.copy(alpha = 0.5f)) - .padding(8.dp), - ) - - Text(text = "Nested: False", style = PrezelTheme.typography.body2Bold) - PrezelListPreviewItem(size, nested = false, showLeadingContent = true, showTrailingContent = true) - PrezelListPreviewItem(size, nested = false, showLeadingContent = true, showTrailingContent = false) - PrezelListPreviewItem(size, nested = false, showLeadingContent = false, showTrailingContent = true) - PrezelListPreviewItem(size, nested = false, showLeadingContent = false, showTrailingContent = false) + PreviewSection( + title = "PrezelList - $size", + description = "점선 테두리는 컴포넌트 경계를 의미하며,\nnested 상태별 leading/trailing 조합을 확인할 수 있습니다.", + showDivider = true, + ) { + Text(text = "Nested: False", style = PrezelTheme.typography.body2Bold) + PrezelListPreviewItem(size, nested = false, showLeadingContent = true, showTrailingContent = true) + PrezelListPreviewItem(size, nested = false, showLeadingContent = true, showTrailingContent = false) + PrezelListPreviewItem(size, nested = false, showLeadingContent = false, showTrailingContent = true) + PrezelListPreviewItem(size, nested = false, showLeadingContent = false, showTrailingContent = false) - Spacer(modifier = Modifier.height(8.dp)) - Text(text = "Nested: True", style = PrezelTheme.typography.body2Bold) - PrezelListPreviewItem(size, nested = true, showLeadingContent = true, showTrailingContent = true) - PrezelListPreviewItem(size, nested = true, showLeadingContent = true, showTrailingContent = false) - PrezelListPreviewItem(size, nested = true, showLeadingContent = false, showTrailingContent = true) - PrezelListPreviewItem(size, nested = true, showLeadingContent = false, showTrailingContent = false) + Spacer(modifier = Modifier.height(8.dp)) + Text(text = "Nested: True", style = PrezelTheme.typography.body2Bold) + PrezelListPreviewItem(size, nested = true, showLeadingContent = true, showTrailingContent = true) + PrezelListPreviewItem(size, nested = true, showLeadingContent = true, showTrailingContent = false) + PrezelListPreviewItem(size, nested = true, showLeadingContent = false, showTrailingContent = true) + PrezelListPreviewItem(size, nested = true, showLeadingContent = false, showTrailingContent = false) + } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/snackbar/PrezelSnackbar.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/snackbar/PrezelSnackbar.kt index ccedaeb..87a9829 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/snackbar/PrezelSnackbar.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/snackbar/PrezelSnackbar.kt @@ -25,7 +25,7 @@ import com.team.prezel.core.designsystem.component.actions.button.config.ButtonS import com.team.prezel.core.designsystem.component.actions.button.config.ButtonType import com.team.prezel.core.designsystem.foundation.typography.PrezelTextStyles import com.team.prezel.core.designsystem.icon.PrezelIcons -import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.preview.BasicPreview import com.team.prezel.core.designsystem.theme.PrezelColorScheme import com.team.prezel.core.designsystem.theme.PrezelTheme @@ -86,7 +86,7 @@ private fun PrezelSnackbarLeadingIcon( ) } -@ThemePreview +@BasicPreview @Composable private fun PrezelSnackBarPreview_Cases() { PrezelTheme { diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextArea.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextArea.kt index 379b0f1..afeadca 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextArea.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextArea.kt @@ -28,8 +28,9 @@ import com.team.prezel.core.designsystem.component.actions.button.PrezelButton import com.team.prezel.core.designsystem.component.textfield.component.PrezelTextFieldLabel import com.team.prezel.core.designsystem.component.textfield.component.PrezelTextFieldPlaceholder import com.team.prezel.core.designsystem.component.textfield.component.PrezelTextFieldSupportingText -import com.team.prezel.core.designsystem.preview.PreviewScaffold -import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.preview.BasicPreview +import com.team.prezel.core.designsystem.preview.PreviewColumn +import com.team.prezel.core.designsystem.preview.PreviewSurface import com.team.prezel.core.designsystem.theme.PrezelTheme @Composable @@ -188,11 +189,14 @@ private fun PrezelTextAreaDecorationBox( } } -@ThemePreview +@BasicPreview @Composable private fun PrezelTextAreaPrezelPreview() { - PrezelTheme { - PreviewScaffold(verticalArrangement = Arrangement.spacedBy(4.dp)) { + PreviewSurface { + PreviewColumn( + scrollable = true, + verticalArrangement = Arrangement.spacedBy(4.dp), + ) { PrezelTextAreaPreviewItem( label = "Interaction - Default / Feedback - Default", value = "", @@ -246,14 +250,14 @@ private fun PrezelTextAreaPrezelPreview() { } } -@ThemePreview +@BasicPreview @Composable private fun MainPrezelTextAreaPreview() { var value by remember { mutableStateOf("") } val focusManager = LocalFocusManager.current - PrezelTheme { - PreviewScaffold { + PreviewSurface { + PreviewColumn(scrollable = true) { PrezelTextArea( value = value, onValueChange = { newValue -> value = newValue }, diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt index 7f4beca..9060892 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/PrezelTextField.kt @@ -36,8 +36,9 @@ import com.team.prezel.core.designsystem.component.textfield.component.PrezelTex import com.team.prezel.core.designsystem.component.textfield.component.PrezelTextFieldPlaceholder import com.team.prezel.core.designsystem.component.textfield.component.PrezelTextFieldSupportingText 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.preview.BasicPreview +import com.team.prezel.core.designsystem.preview.PreviewColumn +import com.team.prezel.core.designsystem.preview.PreviewSurface import com.team.prezel.core.designsystem.theme.PrezelTheme @Composable @@ -179,11 +180,14 @@ private fun PrezelTextFieldDecorationBox( } } -@ThemePreview +@BasicPreview @Composable private fun PrezelTextFieldPreview() { - PrezelTheme { - PreviewScaffold(verticalArrangement = Arrangement.spacedBy(8.dp)) { + PreviewSurface { + PreviewColumn( + scrollable = true, + verticalArrangement = Arrangement.spacedBy(8.dp), + ) { PreviewTextFieldItem( label = "Interaction - Default / Feedback - Default", value = "", @@ -238,14 +242,14 @@ private fun PrezelTextFieldPreview() { } } -@ThemePreview +@BasicPreview @Composable private fun MainPrezelTextFieldPreview() { var value by remember { mutableStateOf("") } val focusManager = LocalFocusManager.current - PrezelTheme { - PreviewScaffold { + PreviewSurface { + PreviewColumn(scrollable = true) { PrezelTextField( value = value, onValueChange = { newValue -> value = newValue }, diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldLabel.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldLabel.kt index 2d4c46a..6588266 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldLabel.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldLabel.kt @@ -5,7 +5,7 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.preview.BasicPreview import com.team.prezel.core.designsystem.theme.PrezelTheme @Composable @@ -22,7 +22,7 @@ internal fun PrezelTextFieldLabel( ) } -@ThemePreview +@BasicPreview @Composable private fun PrezelTextFieldLabelPreview() { PrezelTheme { diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldPlaceholder.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldPlaceholder.kt index c32ac19..806806d 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldPlaceholder.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldPlaceholder.kt @@ -6,7 +6,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.LineHeightStyle import androidx.compose.ui.unit.dp -import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.preview.BasicPreview import com.team.prezel.core.designsystem.theme.PrezelTheme @Composable @@ -28,7 +28,7 @@ internal fun PrezelTextFieldPlaceholder( ) } -@ThemePreview +@BasicPreview @Composable private fun PrezelTextFieldPlaceholderPreview() { PrezelTheme { diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldSupportingText.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldSupportingText.kt index e953fd6..c42e789 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldSupportingText.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldSupportingText.kt @@ -10,7 +10,7 @@ import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.component.textfield.PrezelTextFieldFeedback import com.team.prezel.core.designsystem.component.textfield.PrezelTextFieldInteraction import com.team.prezel.core.designsystem.component.textfield.PrezelTextFieldState -import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.preview.BasicPreview import com.team.prezel.core.designsystem.theme.PrezelTheme @Composable @@ -27,7 +27,7 @@ internal fun PrezelTextFieldSupportingText( ) } -@ThemePreview +@BasicPreview @Composable private fun PrezelTextFieldSupportingTextPreview() { PrezelTheme { diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelRadius.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelRadius.kt index b042611..a731c53 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelRadius.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelRadius.kt @@ -9,10 +9,11 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.unit.dp -import com.team.prezel.core.designsystem.preview.PreviewScaffold -import com.team.prezel.core.designsystem.preview.SectionTitle -import com.team.prezel.core.designsystem.preview.ThemePreview -import com.team.prezel.core.designsystem.preview.TokenList +import com.team.prezel.core.designsystem.preview.BasicPreview +import com.team.prezel.core.designsystem.preview.PreviewColumn +import com.team.prezel.core.designsystem.preview.PreviewSection +import com.team.prezel.core.designsystem.preview.PreviewSurface +import com.team.prezel.core.designsystem.preview.PreviewValueRow import com.team.prezel.core.designsystem.theme.PrezelTheme import kotlinx.collections.immutable.persistentListOf @@ -26,19 +27,23 @@ object PrezelRadius { val V1000 = 1000.dp } -@ThemePreview +@BasicPreview @Composable private fun RadiusTokensPreview() { - PrezelTheme { - PreviewScaffold { RadiusSection() } + PreviewSurface { + PreviewColumn(scrollable = true) { + RadiusSection() + } } } @Composable private fun RadiusSection() { - SectionTitle(title = "Radius") - TokenList( - items = persistentListOf( + PreviewSection( + title = "Radius", + showDivider = true, + ) { + persistentListOf( "V2" to PrezelRadius.V2, "V4" to PrezelRadius.V4, "V6" to PrezelRadius.V6, @@ -46,20 +51,24 @@ private fun RadiusSection() { "V12" to PrezelRadius.V12, "V16" to PrezelRadius.V16, "V1000" to PrezelRadius.V1000, - ), - preview = { radius -> - val shape = RoundedCornerShape(radius) - Box( - modifier = Modifier - .size(40.dp) - .clip(shape) - .background(PrezelTheme.colors.bgLarge) - .border( - width = PrezelStroke.V1, - color = PrezelTheme.colors.borderRegular, - shape = shape, - ), - ) - }, - ) + ).forEach { (name, radius) -> + PreviewValueRow( + name = name, + valueLabel = "${radius.value}dp", + ) { + val shape = RoundedCornerShape(radius) + Box( + modifier = Modifier + .size(40.dp) + .clip(shape) + .background(PrezelTheme.colors.bgLarge) + .border( + width = PrezelStroke.V1, + color = PrezelTheme.colors.borderRegular, + shape = shape, + ), + ) + } + } + } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelShapes.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelShapes.kt index 15cad58..a9db9bd 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelShapes.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelShapes.kt @@ -11,10 +11,11 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.unit.dp -import com.team.prezel.core.designsystem.preview.PreviewScaffold -import com.team.prezel.core.designsystem.preview.SectionTitle -import com.team.prezel.core.designsystem.preview.ThemePreview -import com.team.prezel.core.designsystem.preview.TokenRow +import com.team.prezel.core.designsystem.preview.BasicPreview +import com.team.prezel.core.designsystem.preview.PreviewColumn +import com.team.prezel.core.designsystem.preview.PreviewSection +import com.team.prezel.core.designsystem.preview.PreviewSurface +import com.team.prezel.core.designsystem.preview.PreviewValueRow import com.team.prezel.core.designsystem.theme.PrezelTheme import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf @@ -29,11 +30,11 @@ object PrezelShapes { val V1000 = RoundedCornerShape(PrezelRadius.V1000) } -@ThemePreview +@BasicPreview @Composable private fun ShapesTokensPreview() { - PrezelTheme { - PreviewScaffold { + PreviewSurface { + PreviewColumn(scrollable = true) { ShapesSection() } } @@ -41,37 +42,40 @@ private fun ShapesTokensPreview() { @Composable private fun ShapesSection() { - SectionTitle(title = "Shapes") - ShapeList( - items = persistentListOf( - "V2" to PrezelShapes.V2, - "V4" to PrezelShapes.V4, - "V6" to PrezelShapes.V6, - "V8" to PrezelShapes.V8, - "V12" to PrezelShapes.V12, - "V16" to PrezelShapes.V16, - "V1000" to PrezelShapes.V1000, - ), - ) + PreviewSection( + title = "Shapes", + showDivider = true, + ) { + ShapeList( + items = persistentListOf( + "V2" to PrezelShapes.V2, + "V4" to PrezelShapes.V4, + "V6" to PrezelShapes.V6, + "V8" to PrezelShapes.V8, + "V12" to PrezelShapes.V12, + "V16" to PrezelShapes.V16, + "V1000" to PrezelShapes.V1000, + ), + ) + } } @Composable private fun ShapeList(items: ImmutableList>) { Column(verticalArrangement = Arrangement.spacedBy(10.dp)) { items.forEach { (name, shape) -> - TokenRow( + PreviewValueRow( name = name, valueLabel = "shape", - preview = { - Box( - modifier = Modifier - .size(40.dp) - .clip(shape) - .background(PrezelTheme.colors.bgLarge) - .border(PrezelStroke.V1, PrezelTheme.colors.borderRegular, shape), - ) - }, - ) + ) { + Box( + modifier = Modifier + .size(40.dp) + .clip(shape) + .background(PrezelTheme.colors.bgLarge) + .border(PrezelStroke.V1, PrezelTheme.colors.borderRegular, shape), + ) + } } } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelSpacing.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelSpacing.kt index 2ec0074..9253018 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelSpacing.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelSpacing.kt @@ -9,10 +9,11 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import com.team.prezel.core.designsystem.preview.PreviewScaffold -import com.team.prezel.core.designsystem.preview.SectionTitle -import com.team.prezel.core.designsystem.preview.ThemePreview -import com.team.prezel.core.designsystem.preview.TokenList +import com.team.prezel.core.designsystem.preview.BasicPreview +import com.team.prezel.core.designsystem.preview.PreviewColumn +import com.team.prezel.core.designsystem.preview.PreviewSection +import com.team.prezel.core.designsystem.preview.PreviewSurface +import com.team.prezel.core.designsystem.preview.PreviewValueRow import com.team.prezel.core.designsystem.theme.PrezelTheme import kotlinx.collections.immutable.persistentListOf @@ -39,11 +40,11 @@ object PrezelSpacing { val V80 = 80.dp } -@ThemePreview +@BasicPreview @Composable private fun SpacingTokensPreview() { - PrezelTheme { - PreviewScaffold { + PreviewSurface { + PreviewColumn(scrollable = true) { SpacingSection() } } @@ -51,9 +52,11 @@ private fun SpacingTokensPreview() { @Composable private fun SpacingSection() { - SectionTitle(title = "Spacing") - TokenList( - items = persistentListOf( + PreviewSection( + title = "Spacing", + showDivider = true, + ) { + persistentListOf( "V0" to PrezelSpacing.V0, "V2" to PrezelSpacing.V2, "V4" to PrezelSpacing.V4, @@ -74,16 +77,20 @@ private fun SpacingSection() { "V64" to PrezelSpacing.V64, "V72" to PrezelSpacing.V72, "V80" to PrezelSpacing.V80, - ), - preview = { spacing -> - Row(verticalAlignment = Alignment.CenterVertically) { - Box( - modifier = Modifier - .height(8.dp) - .width(spacing) - .background(PrezelTheme.colors.interactiveRegular), - ) + ).forEach { (name, spacing) -> + PreviewValueRow( + name = name, + valueLabel = "${spacing.value}dp", + ) { + Row(verticalAlignment = Alignment.CenterVertically) { + Box( + modifier = Modifier + .height(8.dp) + .width(spacing) + .background(PrezelTheme.colors.interactiveRegular), + ) + } } - }, - ) + } + } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelStroke.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelStroke.kt index d621f44..0ef9315 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelStroke.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelStroke.kt @@ -6,10 +6,11 @@ import androidx.compose.foundation.layout.size import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import com.team.prezel.core.designsystem.preview.PreviewScaffold -import com.team.prezel.core.designsystem.preview.SectionTitle -import com.team.prezel.core.designsystem.preview.ThemePreview -import com.team.prezel.core.designsystem.preview.TokenList +import com.team.prezel.core.designsystem.preview.BasicPreview +import com.team.prezel.core.designsystem.preview.PreviewColumn +import com.team.prezel.core.designsystem.preview.PreviewSection +import com.team.prezel.core.designsystem.preview.PreviewSurface +import com.team.prezel.core.designsystem.preview.PreviewValueRow import com.team.prezel.core.designsystem.theme.PrezelTheme import kotlinx.collections.immutable.persistentListOf @@ -19,11 +20,11 @@ object PrezelStroke { val V4 = 4.dp } -@ThemePreview +@BasicPreview @Composable private fun StrokeTokensPreview() { - PrezelTheme { - PreviewScaffold { + PreviewSurface { + PreviewColumn(scrollable = true) { StrokeSection() } } @@ -31,23 +32,29 @@ private fun StrokeTokensPreview() { @Composable private fun StrokeSection() { - SectionTitle(title = "Stroke") - TokenList( - items = persistentListOf( + PreviewSection( + title = "Stroke", + showDivider = true, + ) { + persistentListOf( "V1" to PrezelStroke.V1, "V2" to PrezelStroke.V2, "V4" to PrezelStroke.V4, - ), - preview = { stroke -> - Box( - modifier = Modifier - .size(40.dp) - .border( - width = stroke, - color = PrezelTheme.colors.borderLarge, - shape = PrezelShapes.V8, - ), - ) - }, - ) + ).forEach { (name, stroke) -> + PreviewValueRow( + name = name, + valueLabel = "${stroke.value}dp", + ) { + Box( + modifier = Modifier + .size(40.dp) + .border( + width = stroke, + color = PrezelTheme.colors.borderLarge, + shape = PrezelShapes.V8, + ), + ) + } + } + } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/theme/PrezelColorScheme.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/theme/PrezelColorScheme.kt index bffc31b..53626eb 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/theme/PrezelColorScheme.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/theme/PrezelColorScheme.kt @@ -2,12 +2,9 @@ package com.team.prezel.core.designsystem.theme import androidx.compose.foundation.background import androidx.compose.foundation.border -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -16,10 +13,11 @@ import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.foundation.color.ColorTokens import com.team.prezel.core.designsystem.foundation.color.PrezelColors -import com.team.prezel.core.designsystem.preview.PreviewScaffold -import com.team.prezel.core.designsystem.preview.SectionTitle -import com.team.prezel.core.designsystem.preview.ThemePreview -import com.team.prezel.core.designsystem.preview.TokenRow +import com.team.prezel.core.designsystem.preview.BasicPreview +import com.team.prezel.core.designsystem.preview.PreviewColumn +import com.team.prezel.core.designsystem.preview.PreviewSection +import com.team.prezel.core.designsystem.preview.PreviewSurface +import com.team.prezel.core.designsystem.preview.PreviewValueRow import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import java.util.Locale @@ -104,143 +102,127 @@ internal object PrezelColorScheme { ) } -@ThemePreview +@BasicPreview @Composable private fun PrezelColorSchemeInteractivePreview() { - PrezelTheme { - PrezelColorsPreviewSection( - title = "Interactive", - description = "브랜드 색으로 활성화 상태 및 강조가 필요한 요소에 사용하는 색상입니다.", - items = persistentListOf( - "XSmall" to PrezelTheme.colors.interactiveXSmall, - "Small" to PrezelTheme.colors.interactiveSmall, - "Regular" to PrezelTheme.colors.interactiveRegular, - ), - ) - } + PrezelColorsPreviewSection( + title = "Interactive", + description = "브랜드 색으로 활성화 상태 및 강조가 필요한 요소에 사용하는 색상입니다.", + items = persistentListOf( + "XSmall" to PrezelColorScheme.Light.interactiveXSmall, + "Small" to PrezelColorScheme.Light.interactiveSmall, + "Regular" to PrezelColorScheme.Light.interactiveRegular, + ), + ) } -@ThemePreview +@BasicPreview @Composable private fun PrezelColorSchemeBackgroundPreview() { - PrezelTheme { - PrezelColorsPreviewSection( - title = "Background", - description = "콘텐츠의 구조와 계층을 구분하는 색상입니다.", - items = persistentListOf( - "Regular" to PrezelTheme.colors.bgRegular, - "Medium" to PrezelTheme.colors.bgMedium, - "Large" to PrezelTheme.colors.bgLarge, - "Scrim" to PrezelTheme.colors.bgScrim, - "Disabled" to PrezelTheme.colors.bgDisabled, - ), - ) - } + PrezelColorsPreviewSection( + title = "Background", + description = "콘텐츠의 구조와 계층을 구분하는 색상입니다.", + items = persistentListOf( + "Regular" to PrezelColorScheme.Light.bgRegular, + "Medium" to PrezelColorScheme.Light.bgMedium, + "Large" to PrezelColorScheme.Light.bgLarge, + "Scrim" to PrezelColorScheme.Light.bgScrim, + "Disabled" to PrezelColorScheme.Light.bgDisabled, + ), + ) } -@ThemePreview +@BasicPreview @Composable private fun PrezelColorSchemeTextPreview() { - PrezelTheme { - PrezelColorsPreviewSection( - title = "Text", - description = "정보와 콘텐츠를 명확하게 전달하기 위해 사용하는 색상입니다.", - items = persistentListOf( - "Small" to PrezelTheme.colors.textSmall, - "Regular" to PrezelTheme.colors.textRegular, - "Medium" to PrezelTheme.colors.textMedium, - "Large" to PrezelTheme.colors.textLarge, - "Disabled" to PrezelTheme.colors.textDisabled, - ), - ) - } + PrezelColorsPreviewSection( + title = "Text", + description = "정보와 콘텐츠를 명확하게 전달하기 위해 사용하는 색상입니다.", + items = persistentListOf( + "Small" to PrezelColorScheme.Light.textSmall, + "Regular" to PrezelColorScheme.Light.textRegular, + "Medium" to PrezelColorScheme.Light.textMedium, + "Large" to PrezelColorScheme.Light.textLarge, + "Disabled" to PrezelColorScheme.Light.textDisabled, + ), + ) } -@ThemePreview +@BasicPreview @Composable private fun PrezelColorSchemeIconPreview() { - PrezelTheme { - PrezelColorsPreviewSection( - title = "Icon", - description = "기능적 액션과 시각적 커뮤니케이션을 돕기 위해 사용하는 색상입니다.", - items = persistentListOf( - "Regular" to PrezelTheme.colors.iconRegular, - "Medium" to PrezelTheme.colors.iconMedium, - "Disabled" to PrezelTheme.colors.iconDisabled, - ), - ) - } + PrezelColorsPreviewSection( + title = "Icon", + description = "기능적 액션과 시각적 커뮤니케이션을 돕기 위해 사용하는 색상입니다.", + items = persistentListOf( + "Regular" to PrezelColorScheme.Light.iconRegular, + "Medium" to PrezelColorScheme.Light.iconMedium, + "Disabled" to PrezelColorScheme.Light.iconDisabled, + ), + ) } -@ThemePreview +@BasicPreview @Composable private fun PrezelColorSchemeBorderPreview() { - PrezelTheme { - PrezelColorsPreviewSection( - title = "Border", - description = "콘텐츠의 영역과 구조를 구분하는 색상입니다.", - items = persistentListOf( - "Small" to PrezelTheme.colors.borderSmall, - "Regular" to PrezelTheme.colors.borderRegular, - "Medium" to PrezelTheme.colors.borderMedium, - "Large" to PrezelTheme.colors.borderLarge, - "Disabled" to PrezelTheme.colors.borderDisabled, - ), - ) - } + PrezelColorsPreviewSection( + title = "Border", + description = "콘텐츠의 영역과 구조를 구분하는 색상입니다.", + items = persistentListOf( + "Small" to PrezelColorScheme.Light.borderSmall, + "Regular" to PrezelColorScheme.Light.borderRegular, + "Medium" to PrezelColorScheme.Light.borderMedium, + "Large" to PrezelColorScheme.Light.borderLarge, + "Disabled" to PrezelColorScheme.Light.borderDisabled, + ), + ) } -@ThemePreview +@BasicPreview @Composable private fun PrezelColorSchemeFeedbackPreview() { - PrezelTheme { - PrezelColorsPreviewSection( - title = "Feedback", - description = "성공, 오류, 경고 상황을 명확하게 전달하기 위해 의미별로 정의된 색상입니다.", - items = persistentListOf( - "GoodSmall" to PrezelTheme.colors.feedbackGoodSmall, - "GoodRegular" to PrezelTheme.colors.feedbackGoodRegular, - "BadSmall" to PrezelTheme.colors.feedbackBadSmall, - "BadRegular" to PrezelTheme.colors.feedbackBadRegular, - "WarningSmall" to PrezelTheme.colors.feedbackWarningSmall, - "WarningRegular" to PrezelTheme.colors.feedbackWarningRegular, - ), - ) - } + PrezelColorsPreviewSection( + title = "Feedback", + description = "성공, 오류, 경고 상황을 명확하게 전달하기 위해 의미별로 정의된 색상입니다.", + items = persistentListOf( + "GoodSmall" to PrezelColorScheme.Light.feedbackGoodSmall, + "GoodRegular" to PrezelColorScheme.Light.feedbackGoodRegular, + "BadSmall" to PrezelColorScheme.Light.feedbackBadSmall, + "BadRegular" to PrezelColorScheme.Light.feedbackBadRegular, + "WarningSmall" to PrezelColorScheme.Light.feedbackWarningSmall, + "WarningRegular" to PrezelColorScheme.Light.feedbackWarningRegular, + ), + ) } -@ThemePreview +@BasicPreview @Composable private fun PrezelColorSchemeAccentPreview() { - PrezelTheme { - PrezelColorsPreviewSection( - title = "Accent", - description = "콘텐츠의 주목성과 인지도를 높이기 위해 버튼, 액션, 강조 요소 등에 사용되는 포인트 색상입니다.", - items = persistentListOf( - "PurpleSmall" to PrezelTheme.colors.accentPurpleSmall, - "PurpleRegular" to PrezelTheme.colors.accentPurpleRegular, - "TealSmall" to PrezelTheme.colors.accentTealSmall, - "TealRegular" to PrezelTheme.colors.accentTealRegular, - "MagentaSmall" to PrezelTheme.colors.accentMagentaSmall, - "MagentaRegular" to PrezelTheme.colors.accentMagentaRegular, - ), - ) - } + PrezelColorsPreviewSection( + title = "Accent", + description = "콘텐츠의 주목성과 인지도를 높이기 위해 버튼, 액션, 강조 요소 등에 사용되는 포인트 색상입니다.", + items = persistentListOf( + "PurpleSmall" to PrezelColorScheme.Light.accentPurpleSmall, + "PurpleRegular" to PrezelColorScheme.Light.accentPurpleRegular, + "TealSmall" to PrezelColorScheme.Light.accentTealSmall, + "TealRegular" to PrezelColorScheme.Light.accentTealRegular, + "MagentaSmall" to PrezelColorScheme.Light.accentMagentaSmall, + "MagentaRegular" to PrezelColorScheme.Light.accentMagentaRegular, + ), + ) } -@ThemePreview +@BasicPreview @Composable private fun PrezelColorSchemeSolidPreview() { - PrezelTheme { - PrezelColorsPreviewSection( - title = "Solid", - description = "흰색과 검정색을 제공하여 시각적 대비, 보조, 구분 등에 활용되는 절대값 색상입니다.", - items = persistentListOf( - "White" to PrezelTheme.colors.solidWhite, - "Black" to PrezelTheme.colors.solidBlack, - ), - ) - } + PrezelColorsPreviewSection( + title = "Solid", + description = "흰색과 검정색을 제공하여 시각적 대비, 보조, 구분 등에 활용되는 절대값 색상입니다.", + items = persistentListOf( + "White" to PrezelColorScheme.Light.solidWhite, + "Black" to PrezelColorScheme.Light.solidBlack, + ), + ) } @Composable @@ -250,16 +232,18 @@ private fun PrezelColorsPreviewSection( items: ImmutableList>, colors: PrezelColors = PrezelTheme.colors, ) { - PreviewScaffold { - Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { - SectionTitle(title = title) - Text(text = description, color = colors.textLarge.copy(alpha = 0.7f)) - - items.forEach { (name, color) -> - TokenRow( - name = name, - valueLabel = String.format(Locale.ROOT, "#%08X", color.toArgb()), - preview = { + PreviewSurface { + PreviewColumn(scrollable = true) { + PreviewSection( + title = title, + description = description, + showDivider = true, + ) { + items.forEach { (name, color) -> + PreviewValueRow( + name = name, + valueLabel = String.format(Locale.ROOT, "#%08X", color.toArgb()), + ) { Box( modifier = Modifier .size(32.dp) @@ -267,8 +251,8 @@ private fun PrezelColorsPreviewSection( .background(color) .border(0.3.dp, PrezelTheme.colors.solidBlack, RoundedCornerShape(8.dp)), ) - }, - ) + } + } } } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/theme/PrezelTypographyScheme.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/theme/PrezelTypographyScheme.kt index 6d4b03d..02d3fba 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/theme/PrezelTypographyScheme.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/theme/PrezelTypographyScheme.kt @@ -15,8 +15,9 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.isSpecified import com.team.prezel.core.designsystem.foundation.typography.PrezelTextStyles import com.team.prezel.core.designsystem.foundation.typography.PrezelTypography -import com.team.prezel.core.designsystem.preview.PreviewScaffold -import com.team.prezel.core.designsystem.preview.SectionTitle +import com.team.prezel.core.designsystem.preview.PreviewColumn +import com.team.prezel.core.designsystem.preview.PreviewSection +import com.team.prezel.core.designsystem.preview.PreviewSurface import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf @@ -51,17 +52,16 @@ internal object PrezelTypographyScheme { ) @Composable private fun PrezelTypographyTitlePreview() { - PrezelTheme { - PrezelTypographyPreviewContent( - title = "Title", - items = persistentListOf( - "Title1 Medium" to PrezelTheme.typography.title1Medium, - "Title1 Bold" to PrezelTheme.typography.title1Bold, - "Title2 Medium" to PrezelTheme.typography.title2Medium, - "Title2 Bold" to PrezelTheme.typography.title2Bold, - ), - ) - } + val typography = PrezelTypographyScheme.Default() + PrezelTypographyPreviewContent( + title = "Title", + items = persistentListOf( + "Title1 Medium" to typography.title1Medium, + "Title1 Bold" to typography.title1Bold, + "Title2 Medium" to typography.title2Medium, + "Title2 Bold" to typography.title2Bold, + ), + ) } @Preview( @@ -71,22 +71,21 @@ private fun PrezelTypographyTitlePreview() { ) @Composable private fun PrezelTypographyBodyPreview() { - PrezelTheme { - PrezelTypographyPreviewContent( - title = "Body", - items = persistentListOf( - "Body1 Regular" to PrezelTheme.typography.body1Regular, - "Body1 Medium" to PrezelTheme.typography.body1Medium, - "Body1 Bold" to PrezelTheme.typography.body1Bold, - "Body2 Regular" to PrezelTheme.typography.body2Regular, - "Body2 Medium" to PrezelTheme.typography.body2Medium, - "Body2 Bold" to PrezelTheme.typography.body2Bold, - "Body3 Regular" to PrezelTheme.typography.body3Regular, - "Body3 Medium" to PrezelTheme.typography.body3Medium, - "Body3 Bold" to PrezelTheme.typography.body3Bold, - ), - ) - } + val typography = PrezelTypographyScheme.Default() + PrezelTypographyPreviewContent( + title = "Body", + items = persistentListOf( + "Body1 Regular" to typography.body1Regular, + "Body1 Medium" to typography.body1Medium, + "Body1 Bold" to typography.body1Bold, + "Body2 Regular" to typography.body2Regular, + "Body2 Medium" to typography.body2Medium, + "Body2 Bold" to typography.body2Bold, + "Body3 Regular" to typography.body3Regular, + "Body3 Medium" to typography.body3Medium, + "Body3 Bold" to typography.body3Bold, + ), + ) } @Preview( @@ -96,17 +95,16 @@ private fun PrezelTypographyBodyPreview() { ) @Composable private fun PrezelTypographyCaptionPreview() { - PrezelTheme { - PrezelTypographyPreviewContent( - title = "Caption", - items = persistentListOf( - "Caption1 Regular" to PrezelTheme.typography.caption1Regular, - "Caption1 Medium" to PrezelTheme.typography.caption1Medium, - "Caption2 Regular" to PrezelTheme.typography.caption2Regular, - "Caption2 Medium" to PrezelTheme.typography.caption2Medium, - ), - ) - } + val typography = PrezelTypographyScheme.Default() + PrezelTypographyPreviewContent( + title = "Caption", + items = persistentListOf( + "Caption1 Regular" to typography.caption1Regular, + "Caption1 Medium" to typography.caption1Medium, + "Caption2 Regular" to typography.caption2Regular, + "Caption2 Medium" to typography.caption2Medium, + ), + ) } @Composable @@ -114,13 +112,16 @@ private fun PrezelTypographyPreviewContent( title: String, items: ImmutableList>, ) { - PreviewScaffold { - Column(verticalArrangement = Arrangement.spacedBy(16.dp)) { - SectionTitle(title = title) - - Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { - items.forEach { (name, style) -> - TypographyRow(name = name, style = style) + PreviewSurface { + PreviewColumn(scrollable = true) { + PreviewSection( + title = title, + showDivider = true, + ) { + Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { + items.forEach { (name, style) -> + TypographyRow(name = name, style = style) + } } } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/util/DrawDashBorder.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/util/DrawDashBorder.kt index 2c794cb..afe6109 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/util/DrawDashBorder.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/util/DrawDashBorder.kt @@ -15,7 +15,7 @@ import androidx.compose.ui.graphics.RectangleShape import androidx.compose.ui.graphics.Shape import androidx.compose.ui.graphics.drawscope.Stroke import androidx.compose.ui.unit.dp -import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.preview.BasicPreview import com.team.prezel.core.designsystem.theme.PrezelTheme /** @@ -70,7 +70,7 @@ fun Modifier.drawDashBorder( } } -@ThemePreview +@BasicPreview @Composable private fun DrawDashBorderPreview() { PrezelTheme { diff --git a/Prezel/feature/login/impl/src/main/java/com/team/prezel/feature/login/impl/LoginScreen.kt b/Prezel/feature/login/impl/src/main/java/com/team/prezel/feature/login/impl/LoginScreen.kt index 42ba412..0cdda67 100644 --- a/Prezel/feature/login/impl/src/main/java/com/team/prezel/feature/login/impl/LoginScreen.kt +++ b/Prezel/feature/login/impl/src/main/java/com/team/prezel/feature/login/impl/LoginScreen.kt @@ -25,7 +25,7 @@ import androidx.compose.ui.unit.dp import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.team.prezel.core.designsystem.component.actions.button.PrezelButton -import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.preview.BasicPreview import com.team.prezel.core.designsystem.theme.PrezelTheme import com.team.prezel.feature.login.api.AUTH_LOGO_SHARED_ELEMENT_KEY import com.team.prezel.feature.login.impl.viewModel.LoginUiEffect @@ -145,7 +145,7 @@ private fun LoginFooter( } } -@ThemePreview +@BasicPreview @Composable private fun LoginScreenPreview() { PrezelTheme { diff --git a/Prezel/feature/splash/impl/src/main/java/com/team/prezel/feature/splash/impl/SplashScreen.kt b/Prezel/feature/splash/impl/src/main/java/com/team/prezel/feature/splash/impl/SplashScreen.kt index 347130e..745416d 100644 --- a/Prezel/feature/splash/impl/src/main/java/com/team/prezel/feature/splash/impl/SplashScreen.kt +++ b/Prezel/feature/splash/impl/src/main/java/com/team/prezel/feature/splash/impl/SplashScreen.kt @@ -17,7 +17,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel -import com.team.prezel.core.designsystem.preview.ThemePreview +import com.team.prezel.core.designsystem.preview.BasicPreview import com.team.prezel.core.designsystem.theme.PrezelTheme import com.team.prezel.feature.login.api.AUTH_LOGO_SHARED_ELEMENT_KEY import com.team.prezel.feature.splash.impl.viewModel.SplashUiEffect @@ -72,7 +72,7 @@ private fun SharedTransitionScope.SplashScreen( } } -@ThemePreview +@BasicPreview @Composable private fun SplashScreenPreview() { PrezelTheme { From 96e9eafafe58e27ad69f12eaee7494c66d1e0288 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Wed, 25 Mar 2026 03:56:17 +0900 Subject: [PATCH 27/42] =?UTF-8?q?refactor:=20=EB=94=94=EC=9E=90=EC=9D=B8?= =?UTF-8?q?=20=EC=8B=9C=EC=8A=A4=ED=85=9C=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20Preview=20=EA=B5=AC=EC=A1=B0=20=EA=B0=9C=EC=84=A0?= =?UTF-8?q?=20=EB=B0=8F=20=EC=BD=94=EB=93=9C=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../designsystem/component/PrezelAvatar.kt | 90 ++++---- .../designsystem/component/PrezelCheckbox.kt | 100 ++------- .../designsystem/component/PrezelDivider.kt | 50 ++--- .../designsystem/component/PrezelRadio.kt | 40 ++-- .../core/designsystem/component/PrezelTabs.kt | 65 +++--- .../core/designsystem/component/TopAppBar.kt | 58 +----- .../actions/area/PrezelButtonArea.kt | 68 +++--- .../actions/button/PrezelHyperlinkButton.kt | 20 +- .../button/config/PrezelButtonPreview.kt | 29 +-- .../button/floating/PrezelFloatingButton.kt | 64 ++---- .../button/floating/PrezelFloatingMenu.kt | 8 +- .../button/floating/menu/PrezelMenu.kt | 48 ++--- .../button/floating/menu/PrezelMenuItem.kt | 50 ++--- .../component/base/PrezelDropShadow.kt | 48 ++--- .../component/base/PrezelTouchArea.kt | 37 +++- .../designsystem/component/chip/PrezelChip.kt | 141 +++++++++++-- .../component/chip/PrezelChipPreview.kt | 130 ------------ .../component/chip/PrezelCustomChipPreview.kt | 173 --------------- .../component/chip/PrezelIconChip.kt | 80 +++++-- .../datepicker/DatePickerDayCellView.kt | 12 +- .../component/datepicker/MonthGrid.kt | 6 +- .../component/datepicker/MonthSection.kt | 6 +- .../component/datepicker/PrezelDatePicker.kt | 13 +- .../component/image/PrezelImage.kt | 65 +++--- .../designsystem/component/list/PrezelList.kt | 15 +- .../component/snackbar/PrezelSnackbar.kt | 21 +- .../component/PrezelTextFieldLabel.kt | 8 +- .../component/PrezelTextFieldPlaceholder.kt | 14 +- .../PrezelTextFieldSupportingText.kt | 50 +++-- .../foundation/number/PrezelRadius.kt | 20 +- .../foundation/number/PrezelShapes.kt | 54 ++--- .../foundation/number/PrezelSpacing.kt | 69 +++--- .../foundation/number/PrezelStroke.kt | 17 +- .../designsystem/preview/PreviewComponent.kt | 197 ++++++------------ .../designsystem/theme/PrezelColorScheme.kt | 38 ++-- .../theme/PrezelTypographyScheme.kt | 84 ++------ .../core/designsystem/util/DrawDashBorder.kt | 7 +- 37 files changed, 764 insertions(+), 1231 deletions(-) delete mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelChipPreview.kt delete mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelCustomChipPreview.kt diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelAvatar.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelAvatar.kt index 1503983..5671b6f 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelAvatar.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelAvatar.kt @@ -2,14 +2,10 @@ package com.team.prezel.core.designsystem.component import androidx.compose.foundation.background import androidx.compose.foundation.border -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.material3.Icon -import androidx.compose.material3.Surface import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -25,6 +21,8 @@ import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.R import com.team.prezel.core.designsystem.foundation.number.PrezelStroke import com.team.prezel.core.designsystem.preview.BasicPreview +import com.team.prezel.core.designsystem.preview.PreviewSection +import com.team.prezel.core.designsystem.preview.PreviewValueRow import com.team.prezel.core.designsystem.theme.PrezelTheme @Composable @@ -111,48 +109,50 @@ private fun DefaultAvatarIcon( @BasicPreview @Composable -private fun PrezelAvatarSizePreview() { - PrezelTheme { - Surface(color = PrezelTheme.colors.bgRegular) { - Row( - horizontalArrangement = Arrangement.spacedBy(16.dp), - modifier = Modifier.padding(16.dp), - ) { - PrezelAvatar( - imageUrl = null, - contentDescription = "기본 아바타", - size = PrezelAvatarSize.SMALL, - ) - PrezelAvatar( - imageUrl = null, - contentDescription = "기본 아바타", - size = PrezelAvatarSize.REGULAR, - ) - } +private fun PrezelAvatarPreview() { + PreviewSection( + title = "Avatar", + description = "Avatar는 사용자를 대신하는 그래픽 요소입니다.", + ) { + PreviewValueRow( + name = "Regular", + valueLabel = "기본 아바타", + ) { + PrezelAvatar( + imageUrl = null, + contentDescription = "기본 아바타", + size = PrezelAvatarSize.REGULAR, + ) } - } -} - -@BasicPreview -@Composable -private fun PrezelAvatarTypePreview() { - PrezelTheme { - Surface(color = PrezelTheme.colors.bgRegular) { - Row( - horizontalArrangement = Arrangement.spacedBy(16.dp), - modifier = Modifier.padding(16.dp), - ) { - PrezelAvatar( - imageUrl = null, - contentDescription = "Default Type", - size = PrezelAvatarSize.SMALL, - ) - PrezelAvatar( - imageUrl = "https://picsum.photos/200", - contentDescription = "Image Type", - size = PrezelAvatarSize.SMALL, - ) - } + PreviewValueRow( + name = "Regular", + valueLabel = "이미지", + ) { + PrezelAvatar( + imageUrl = "https://picsum.photos/200", + contentDescription = "기본 아바타", + size = PrezelAvatarSize.REGULAR, + ) + } + PreviewValueRow( + name = "Small", + valueLabel = "기본 아바타", + ) { + PrezelAvatar( + imageUrl = null, + contentDescription = "기본 아바타", + size = PrezelAvatarSize.SMALL, + ) + } + PreviewValueRow( + name = "Small", + valueLabel = "이미지", + ) { + PrezelAvatar( + imageUrl = "https://picsum.photos/200", + contentDescription = "Image Type", + size = PrezelAvatarSize.SMALL, + ) } } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelCheckbox.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelCheckbox.kt index 09b6346..a9b3196 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelCheckbox.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelCheckbox.kt @@ -1,16 +1,10 @@ package com.team.prezel.core.designsystem.component -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.selection.toggleable import androidx.compose.material3.Icon -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -23,9 +17,10 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.semantics.Role 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.BasicPreview +import com.team.prezel.core.designsystem.preview.PreviewSection +import com.team.prezel.core.designsystem.preview.PreviewValueRow import com.team.prezel.core.designsystem.theme.PrezelTheme import com.team.prezel.core.designsystem.util.drawDashBorder @@ -83,79 +78,28 @@ fun PrezelCheckbox( @BasicPreview @Composable -private fun PrezelRegularCheckboxPreview() { - PrezelTheme { - Column( - modifier = Modifier - .background(PrezelTheme.colors.bgRegular) - .padding(16.dp), - ) { - CheckboxRowPreview(title = "Regular Checkbox") { - var checkState by remember { mutableStateOf(true) } +private fun PrezelCheckboxPreview() { + var checkState by remember { mutableStateOf(true) } - PrezelCheckbox( - checked = checkState, - modifier = Modifier.drawDashBorder(), - size = CheckboxSize.REGULAR, - onCheckedChange = { checkState = it }, - ) - - PrezelCheckbox( - checked = !checkState, - modifier = Modifier.drawDashBorder(), - size = CheckboxSize.REGULAR, - onCheckedChange = { checkState = it }, - ) - } + PreviewSection( + title = "Checkbox", + description = "Checkbox는 목록에서 선택할 항목이 여러 개 있을 때 사용됩니다.", + ) { + PreviewValueRow(name = "Regular") { + PrezelCheckbox( + checked = checkState, + modifier = Modifier.drawDashBorder(), + size = CheckboxSize.REGULAR, + onCheckedChange = { checkState = it }, + ) } - } -} - -@BasicPreview -@Composable -private fun PrezelLargeCheckboxPreview() { - PrezelTheme { - Column( - modifier = Modifier - .background(PrezelTheme.colors.bgRegular) - .padding(16.dp), - ) { - CheckboxRowPreview(title = "Large Checkbox") { - var checkState by remember { mutableStateOf(true) } - - PrezelCheckbox( - checked = checkState, - modifier = Modifier.drawDashBorder(), - size = CheckboxSize.LARGE, - onCheckedChange = { checkState = it }, - ) - - PrezelCheckbox( - checked = !checkState, - modifier = Modifier.drawDashBorder(), - size = CheckboxSize.LARGE, - onCheckedChange = { checkState = it }, - ) - } + PreviewValueRow(name = "Large") { + PrezelCheckbox( + checked = !checkState, + modifier = Modifier.drawDashBorder(), + size = CheckboxSize.LARGE, + onCheckedChange = { checkState = it }, + ) } } } - -@Composable -private fun CheckboxRowPreview( - title: String, - content: @Composable RowScope.() -> Unit, -) { - Column(modifier = Modifier.padding(bottom = 16.dp)) { - Text( - text = title, - style = PrezelTextStyles.Caption2Regular.toTextStyle(), - color = PrezelTheme.colors.textLarge, - modifier = Modifier.padding(bottom = 4.dp), - ) - Row( - horizontalArrangement = Arrangement.spacedBy(8.dp), - content = content, - ) - } -} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelDivider.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelDivider.kt index eec8830..da25a4b 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelDivider.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelDivider.kt @@ -2,7 +2,6 @@ package com.team.prezel.core.designsystem.component import androidx.compose.foundation.layout.height import androidx.compose.material3.HorizontalDivider -import androidx.compose.material3.Text import androidx.compose.material3.VerticalDivider import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier @@ -10,9 +9,8 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.preview.BasicPreview -import com.team.prezel.core.designsystem.preview.PreviewColumn import com.team.prezel.core.designsystem.preview.PreviewSection -import com.team.prezel.core.designsystem.preview.PreviewSurface +import com.team.prezel.core.designsystem.preview.PreviewValueRow import com.team.prezel.core.designsystem.theme.PrezelTheme enum class PrezelDividerType( @@ -61,28 +59,32 @@ private fun PrezelDivider( @BasicPreview @Composable -private fun PrezelDividerPreview() { - PreviewSurface { - PreviewColumn(scrollable = true) { - PreviewSection( - title = "PrezelDivider - Horizontal", - showDivider = true, - ) { - Text("PrezelDividerType.DEFAULT") - PrezelHorizontalDivider(type = PrezelDividerType.DEFAULT) - Text("PrezelDividerType.THICK") - PrezelHorizontalDivider(type = PrezelDividerType.THICK) - } +private fun PrezelHorizontalDividerPreview() { + PreviewSection( + title = "PrezelDivider - Horizontal", + description = "Divider는 두 요소 사이를 구분합니다.", + ) { + PreviewValueRow(name = "DEFAULT") { + PrezelHorizontalDivider(type = PrezelDividerType.DEFAULT) + } + PreviewValueRow(name = "THICK") { + PrezelHorizontalDivider(type = PrezelDividerType.THICK) + } + } +} - PreviewSection( - title = "PrezelDivider - Vertical", - showDivider = true, - ) { - Text("PrezelDividerType.DEFAULT") - PrezelVerticalDivider(type = PrezelDividerType.DEFAULT, modifier = Modifier.height(100.dp)) - Text("PrezelDividerType.THICK") - PrezelVerticalDivider(type = PrezelDividerType.THICK, modifier = Modifier.height(100.dp)) - } +@BasicPreview +@Composable +private fun PrezelVerticalDividerPreview() { + PreviewSection( + title = "PrezelDivider - Vertical", + description = "Divider는 두 요소 사이를 구분합니다.", + ) { + PreviewValueRow(name = "DEFAULT", modifier = Modifier.height(100.dp)) { + PrezelVerticalDivider(type = PrezelDividerType.DEFAULT) + } + PreviewValueRow(name = "THICK", modifier = Modifier.height(100.dp)) { + PrezelVerticalDivider(type = PrezelDividerType.THICK) } } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelRadio.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelRadio.kt index 819338e..377b817 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelRadio.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelRadio.kt @@ -26,9 +26,8 @@ import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.icon.PrezelIcons import com.team.prezel.core.designsystem.preview.BasicPreview -import com.team.prezel.core.designsystem.preview.PreviewColumn +import com.team.prezel.core.designsystem.preview.PreviewRow import com.team.prezel.core.designsystem.preview.PreviewSection -import com.team.prezel.core.designsystem.preview.PreviewSurface import com.team.prezel.core.designsystem.theme.PrezelTheme /** @@ -133,31 +132,20 @@ private fun PrezelRadioIcon( private fun PrezelRadioPreview() { var checked by remember { mutableStateOf(false) } - PreviewSurface { - PreviewColumn(scrollable = true) { - PreviewSection( - title = "PrezelRadioSize.REGULAR", - showDivider = true, - ) { - Text("Checked: true") - PrezelRadio(checked = true, onCheckedChange = {}, size = PrezelRadioSize.REGULAR) - Text("Checked: false") - PrezelRadio(checked = false, onCheckedChange = {}, size = PrezelRadioSize.REGULAR) - Text("PrezelRadio with text") - PrezelRadio(checked = checked, onCheckedChange = { checked = it }, text = "텍스트", size = PrezelRadioSize.REGULAR) - } + PreviewSection( + title = "PrezelRadio", + description = "라디오 버튼은 목록에서 선택할 항목이 한 개 있을 때 사용됩니다.", + ) { + PreviewRow { + PrezelRadio(checked = true, onCheckedChange = {}, size = PrezelRadioSize.REGULAR) + PrezelRadio(checked = false, onCheckedChange = {}, size = PrezelRadioSize.REGULAR) + PrezelRadio(checked = checked, onCheckedChange = { checked = it }, text = "Label", size = PrezelRadioSize.REGULAR) + } - PreviewSection( - title = "PrezelRadioSize.LARGE", - showDivider = true, - ) { - Text("Checked: true") - PrezelRadio(checked = true, onCheckedChange = {}, size = PrezelRadioSize.LARGE) - Text("Checked: false") - PrezelRadio(checked = false, onCheckedChange = {}, size = PrezelRadioSize.LARGE) - Text("PrezelRadio with text") - PrezelRadio(checked = checked, onCheckedChange = { checked = it }, text = "텍스트", size = PrezelRadioSize.LARGE) - } + PreviewRow { + PrezelRadio(checked = true, onCheckedChange = {}, size = PrezelRadioSize.LARGE) + PrezelRadio(checked = false, onCheckedChange = {}, size = PrezelRadioSize.LARGE) + PrezelRadio(checked = checked, onCheckedChange = { checked = it }, text = "Label", size = PrezelRadioSize.LARGE) } } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelTabs.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelTabs.kt index 0551a29..1743c7d 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelTabs.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelTabs.kt @@ -3,6 +3,7 @@ package com.team.prezel.core.designsystem.component import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth @@ -21,6 +22,8 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.foundation.typography.PrezelTextStyles import com.team.prezel.core.designsystem.preview.BasicPreview +import com.team.prezel.core.designsystem.preview.PreviewDefaults +import com.team.prezel.core.designsystem.preview.PreviewScaffold import com.team.prezel.core.designsystem.theme.PrezelTheme import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf @@ -156,24 +159,20 @@ private fun PrezelMediumTabPreview() { val tabs = persistentListOf("Label1", "Label2", "Label3") val pagerState = rememberPagerState(initialPage = 0) { tabs.size } - PrezelTheme { - Box( - modifier = Modifier - .fillMaxSize() - .background(PrezelTheme.colors.bgRegular), - ) { - PrezelTabs( - tabs = tabs, - pagerState = pagerState, - size = PrezelTabSize.Regular, - modifier = Modifier, - ) { page -> - Box( - modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.Center, - ) { - Text("Page: $page") - } + PreviewScaffold( + defaults = PreviewDefaults(screenPadding = PaddingValues(0.dp)), + ) { + PrezelTabs( + tabs = tabs, + pagerState = pagerState, + size = PrezelTabSize.Regular, + modifier = Modifier, + ) { page -> + Box( + modifier = Modifier.fillMaxSize(), + contentAlignment = Alignment.Center, + ) { + Text("Page: $page") } } } @@ -185,23 +184,19 @@ private fun PrezelSmallTabPreview() { val tabs = persistentListOf("Label1", "Label2") val pagerState = rememberPagerState(initialPage = 0) { tabs.size } - PrezelTheme { - Box( - modifier = Modifier - .fillMaxSize() - .background(PrezelTheme.colors.bgRegular), - ) { - PrezelTabs( - tabs = tabs, - pagerState = pagerState, - size = PrezelTabSize.Small, - ) { page -> - Box( - modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.Center, - ) { - Text("Page: $page") - } + PreviewScaffold( + defaults = PreviewDefaults(screenPadding = PaddingValues(0.dp)), + ) { + PrezelTabs( + tabs = tabs, + pagerState = pagerState, + size = PrezelTabSize.Small, + ) { page -> + Box( + modifier = Modifier.fillMaxSize(), + contentAlignment = Alignment.Center, + ) { + Text("Page: $page") } } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/TopAppBar.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/TopAppBar.kt index 8b2eba2..402dda4 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/TopAppBar.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/TopAppBar.kt @@ -1,15 +1,10 @@ package com.team.prezel.core.designsystem.component -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.RowScope -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.ProvideTextStyle -import androidx.compose.material3.Scaffold -import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults @@ -17,12 +12,12 @@ import androidx.compose.material3.TopAppBarScrollBehavior import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color -import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource -import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.icon.PrezelIcons import com.team.prezel.core.designsystem.preview.BasicPreview +import com.team.prezel.core.designsystem.preview.PreviewSection +import com.team.prezel.core.designsystem.preview.PreviewSurface import com.team.prezel.core.designsystem.theme.PrezelTheme @OptIn(ExperimentalMaterial3Api::class) @@ -63,8 +58,8 @@ private fun prezelTopAppBarColors() = @BasicPreview @Composable private fun PrezelTopAppBarTitleOnlyPreview() { - PrezelTheme { - Surface(color = PrezelTheme.colors.bgRegular) { + PreviewSurface { + PreviewSection(title = "Title Only") { PrezelTopAppBar(title = { Text(text = "제목") }) } } @@ -74,8 +69,8 @@ private fun PrezelTopAppBarTitleOnlyPreview() { @BasicPreview @Composable private fun PrezelTopAppBarWithLeadingPreview() { - PrezelTheme { - Surface(color = PrezelTheme.colors.bgRegular) { + PreviewSurface { + PreviewSection(title = "With Leading") { PrezelTopAppBar( title = { Text(text = "제목") }, leadingIcon = { @@ -95,8 +90,8 @@ private fun PrezelTopAppBarWithLeadingPreview() { @BasicPreview @Composable private fun PrezelTopAppBarWithAllIconsPreview() { - PrezelTheme { - Surface(color = PrezelTheme.colors.bgRegular) { + PreviewSurface { + PreviewSection(title = "With All Icons") { PrezelTopAppBar( title = { Text(text = "Title") }, leadingIcon = { @@ -125,40 +120,3 @@ private fun PrezelTopAppBarWithAllIconsPreview() { } } } - -@OptIn(ExperimentalMaterial3Api::class) -@BasicPreview -@Composable -private fun PrezelTopAppBarScrollTestPreview() { - PrezelTheme { - val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior() - - Scaffold( - modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection), - containerColor = PrezelTheme.colors.bgRegular, - topBar = { - PrezelTopAppBar( - title = { Text("Title") }, - leadingIcon = { - IconButton(onClick = {}) { - Icon( - painter = painterResource(PrezelIcons.Blank), - contentDescription = "뒤로가기", - ) - } - }, - scrollBehavior = scrollBehavior, - ) - }, - ) { innerPadding -> - LazyColumn( - modifier = Modifier - .padding(innerPadding) - .padding(horizontal = 16.dp), - verticalArrangement = Arrangement.spacedBy(16.dp), - ) { - items(30) { index -> Text(text = "Item $index") } - } - } - } -} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonArea.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonArea.kt index 1619c65..11c0a28 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonArea.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonArea.kt @@ -24,9 +24,7 @@ import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.component.PrezelDividerType import com.team.prezel.core.designsystem.component.PrezelHorizontalDivider import com.team.prezel.core.designsystem.icon.PrezelIcons -import com.team.prezel.core.designsystem.preview.PreviewColumn import com.team.prezel.core.designsystem.preview.PreviewSection -import com.team.prezel.core.designsystem.preview.PreviewSurface import com.team.prezel.core.designsystem.theme.PrezelTheme /** @@ -61,14 +59,14 @@ fun PrezelButtonArea( if (isVertical) { ButtonAreaVertical( mainButton = scope.buttons[0], - subButton = scope.buttons[1], + subButton = scope.buttons.getOrNull(1), modifier = Modifier.padding(config.contentPadding), ) } else { ButtonAreaHorizontal( isStrongStrength = isStrongStrength, mainButton = scope.buttons[0], - subButton = scope.buttons[1], + subButton = scope.buttons.getOrNull(1), modifier = Modifier.padding(config.contentPadding), ) } @@ -109,18 +107,10 @@ private fun ButtonAreaHorizontal( } private data class ButtonAreaPreviewVariant( - val title: String, val isVertical: Boolean, val isStrongStrength: Boolean, ) -private val buttonAreaPreviewVariants = - listOf( - ButtonAreaPreviewVariant(title = "Vertical", isVertical = true, isStrongStrength = true), - ButtonAreaPreviewVariant(title = "Horizontal / Strong Strength", isVertical = false, isStrongStrength = true), - ButtonAreaPreviewVariant(title = "Horizontal / Weak Strength", isVertical = false, isStrongStrength = false), - ) - private val buttonAreaPreviewStates = listOf( true to "Enabled", @@ -129,34 +119,52 @@ private val buttonAreaPreviewStates = @Preview(device = "spec:width=1080dp,height=1800dp") @Composable -private fun PrezelButtonAreaPreview() { - PreviewSurface { - PreviewColumn(scrollable = true) { - PreviewSection( - title = "Button Area", - description = "행은 버튼 상태, 열은 배경 여부입니다. 각 섹션은 배치 방향과 강도 옵션을 구분합니다.", - showDivider = true, - ) { - buttonAreaPreviewVariants.forEach { variant -> - ButtonAreaPreviewSection(variant = variant) - } +private fun PrezelButtonAreaVerticalPreview() { + PreviewSection( + title = "Button Area - Vertical", + description = "행은 버튼 상태, 열은 배경 여부입니다. 각 섹션은 배치 방향과 강도 옵션을 구분합니다.", + ) { + Column { + ButtonAreaPreviewHeaderRow() + + buttonAreaPreviewStates.forEach { (enabled, label) -> + ButtonAreaPreviewRow( + variant = ButtonAreaPreviewVariant( + isVertical = true, + isStrongStrength = false, + ), + enabled = enabled, + label = label, + ) } } } } +@Preview(device = "spec:width=1080dp,height=1800dp") @Composable -private fun ButtonAreaPreviewSection(variant: ButtonAreaPreviewVariant) { - PreviewSection(title = variant.title) { - Column( - modifier = Modifier.fillMaxWidth(), - verticalArrangement = Arrangement.spacedBy(0.dp), - ) { +private fun PrezelButtonAreaHorizontalPreview() { + PreviewSection( + title = "Button Area - Horizontal", + description = "행은 버튼 상태, 열은 배경 여부입니다. 각 섹션은 배치 방향과 강도 옵션을 구분합니다.", + ) { + Column { ButtonAreaPreviewHeaderRow() buttonAreaPreviewStates.forEach { (enabled, label) -> ButtonAreaPreviewRow( - variant = variant, + variant = ButtonAreaPreviewVariant( + isVertical = false, + isStrongStrength = true, + ), + enabled = enabled, + label = label, + ) + ButtonAreaPreviewRow( + variant = ButtonAreaPreviewVariant( + isVertical = false, + isStrongStrength = false, + ), enabled = enabled, label = label, ) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelHyperlinkButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelHyperlinkButton.kt index 9a25efc..2320ca9 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelHyperlinkButton.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelHyperlinkButton.kt @@ -1,7 +1,5 @@ package com.team.prezel.core.designsystem.component.actions.button -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.draw.drawBehind @@ -15,7 +13,9 @@ import com.team.prezel.core.designsystem.component.actions.button.config.PrezelB import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefault import com.team.prezel.core.designsystem.component.actions.button.config.PrezelButtonDefaults import com.team.prezel.core.designsystem.preview.BasicPreview +import com.team.prezel.core.designsystem.preview.PreviewSection import com.team.prezel.core.designsystem.theme.PrezelTheme +import com.team.prezel.core.designsystem.util.drawDashBorder /** * 텍스트 링크처럼 보이는 보조 액션 버튼입니다. @@ -65,12 +65,14 @@ private fun Modifier.prezelButtonUnderline(): Modifier { @BasicPreview @Composable private fun PrezelHyperlinkButtonPreview() { - PrezelTheme { - Box(modifier = Modifier.padding(8.dp)) { - PrezelHyperlinkButton( - text = "자세히 보기", - onClick = {}, - ) - } + PreviewSection( + title = "Hyperlink Button", + description = "텍스트 링크처럼 보이는 보조 액션 버튼입니다.", + ) { + PrezelHyperlinkButton( + text = "자세히 보기", + onClick = {}, + modifier = Modifier.drawDashBorder(), + ) } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonPreview.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonPreview.kt index f76d896..0bc0279 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonPreview.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonPreview.kt @@ -17,9 +17,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp -import com.team.prezel.core.designsystem.preview.PreviewColumn import com.team.prezel.core.designsystem.preview.PreviewSection -import com.team.prezel.core.designsystem.preview.PreviewSurface import com.team.prezel.core.designsystem.theme.PrezelTheme import com.team.prezel.core.designsystem.util.drawDashBorder @@ -42,22 +40,17 @@ internal fun PrezelButtonPreviewContent( title: String, content: @Composable (ButtonType, ButtonHierarchy, ButtonSize, Boolean, Boolean) -> Unit, ) { - PreviewSurface { - PreviewColumn(scrollable = true) { - PreviewSection( - title = title, - description = "행은 Size, 열은 Type과 Hierarchy 조합입니다. 각 섹션은 Enabled와 Rounded 상태를 구분합니다.", - showDivider = true, - ) { - previewSections.forEach { section -> - ButtonPreviewSection( - title = section.title, - enabled = section.enabled, - isRounded = section.isRounded, - content = content, - ) - } - } + PreviewSection( + title = title, + description = "행은 Size, 열은 Type과 Hierarchy 조합입니다. 각 섹션은 Enabled와 Rounded 상태를 구분합니다.", + ) { + previewSections.forEach { section -> + ButtonPreviewSection( + title = section.title, + enabled = section.enabled, + isRounded = section.isRounded, + content = content, + ) } } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingButton.kt index cdd864b..5dcc204 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingButton.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingButton.kt @@ -1,17 +1,12 @@ package com.team.prezel.core.designsystem.component.actions.button.floating import androidx.annotation.DrawableRes -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.padding 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.unit.dp import com.team.prezel.core.designsystem.component.actions.button.PrezelIconButton import com.team.prezel.core.designsystem.component.actions.button.config.ButtonHierarchy import com.team.prezel.core.designsystem.component.actions.button.config.ButtonSize @@ -19,6 +14,8 @@ import com.team.prezel.core.designsystem.component.base.PrezelDropShadowDefaults import com.team.prezel.core.designsystem.component.base.prezelDropShadow import com.team.prezel.core.designsystem.icon.PrezelIcons import com.team.prezel.core.designsystem.preview.BasicPreview +import com.team.prezel.core.designsystem.preview.PreviewSection +import com.team.prezel.core.designsystem.preview.PreviewValueRow import com.team.prezel.core.designsystem.theme.PrezelTheme /** @@ -53,44 +50,25 @@ fun PrezelFloatingButton( private fun PrezelFloatingButtonPreview() { var expanded by remember { mutableStateOf(false) } - PrezelTheme { - Column( - modifier = Modifier - .background(PrezelTheme.colors.bgRegular) - .padding(12.dp), - verticalArrangement = Arrangement.spacedBy(8.dp), - ) { - PrezelFloatingButton( - isExpanded = expanded, - onChangeExpanded = { expanded = it }, - iconResId = PrezelIcons.Blank, - hierarchy = ButtonHierarchy.PRIMARY, - size = ButtonSize.REGULAR, - ) - - PrezelFloatingButton( - isExpanded = expanded, - onChangeExpanded = { expanded = it }, - iconResId = PrezelIcons.Blank, - hierarchy = ButtonHierarchy.SECONDARY, - size = ButtonSize.REGULAR, - ) - - PrezelFloatingButton( - isExpanded = expanded, - onChangeExpanded = { expanded = it }, - iconResId = PrezelIcons.Blank, - hierarchy = ButtonHierarchy.PRIMARY, - size = ButtonSize.SMALL, - ) - - PrezelFloatingButton( - isExpanded = expanded, - onChangeExpanded = { expanded = it }, - iconResId = PrezelIcons.Blank, - hierarchy = ButtonHierarchy.SECONDARY, - size = ButtonSize.SMALL, - ) + PreviewSection( + title = "Floating Button", + description = "Floating Button은 아이콘으로 공통 기능을 안내합니다.", + ) { + ButtonHierarchy.entries.forEach { hierarchy -> + ButtonSize.entries.forEach { size -> + PreviewValueRow( + name = hierarchy.name, + valueLabel = size.name, + ) { + PrezelFloatingButton( + isExpanded = expanded, + onChangeExpanded = { expanded = it }, + iconResId = PrezelIcons.Blank, + hierarchy = hierarchy, + size = size, + ) + } + } } } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingMenu.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingMenu.kt index d84afab..23faa9f 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingMenu.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingMenu.kt @@ -7,7 +7,6 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -24,6 +23,7 @@ import com.team.prezel.core.designsystem.component.actions.button.floating.menu. import com.team.prezel.core.designsystem.component.actions.button.floating.menu.PrezelMenuScope import com.team.prezel.core.designsystem.icon.PrezelIcons import com.team.prezel.core.designsystem.preview.BasicPreview +import com.team.prezel.core.designsystem.preview.PreviewSection import com.team.prezel.core.designsystem.theme.PrezelTheme /** @@ -73,11 +73,13 @@ fun PrezelFloatingMenu( private fun PrezelFloatingMenuPreview() { var expanded by remember { mutableStateOf(true) } - PrezelTheme { + PreviewSection( + title = "Floating Menu", + description = "확장된 메뉴와 토글 버튼의 배치를 확인합니다.", + ) { Box( modifier = Modifier .background(Color.LightGray) - .size(width = 200.dp, height = 300.dp) .padding(8.dp), ) { PrezelFloatingMenu( diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenu.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenu.kt index f91b995..2322869 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenu.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenu.kt @@ -1,9 +1,7 @@ package com.team.prezel.core.designsystem.component.actions.button.floating.menu 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.runtime.Composable import androidx.compose.runtime.remember @@ -13,7 +11,8 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.icon.PrezelIcons import com.team.prezel.core.designsystem.preview.BasicPreview -import com.team.prezel.core.designsystem.theme.PrezelTheme +import com.team.prezel.core.designsystem.preview.PreviewSection +import com.team.prezel.core.designsystem.preview.PreviewValueRow /** * 플로팅 액션 메뉴 항목을 세로로 배치하는 컨테이너입니다. @@ -41,30 +40,25 @@ fun PrezelMenu( @BasicPreview @Composable private fun PrezelMenuPreview() { - PrezelTheme { - Row( - horizontalArrangement = Arrangement.spacedBy(8.dp), - modifier = Modifier - .background(Color.LightGray) - .padding(8.dp), - ) { - PrezelMenu { - repeat(5) { - MenuItem( - label = "Label", - iconResId = PrezelIcons.Blank, - onClick = {}, - ) - } - } - - PrezelMenu(size = MenuSize.SMALL) { - repeat(5) { - MenuItem( - label = "Label", - iconResId = PrezelIcons.Blank, - onClick = {}, - ) + PreviewSection( + title = "Floating Menu Container", + description = "Regular/Small 메뉴 컨테이너의 크기와 간격을 비교합니다.", + ) { + MenuSize.entries.forEach { size -> + PreviewValueRow(name = size.name) { + PrezelMenu( + size = size, + modifier = Modifier + .background(Color.LightGray) + .padding(8.dp), + ) { + repeat(3) { + MenuItem( + label = "Label", + iconResId = PrezelIcons.Blank, + onClick = {}, + ) + } } } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuItem.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuItem.kt index e206d5e..a003e58 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuItem.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/menu/PrezelMenuItem.kt @@ -1,10 +1,8 @@ package com.team.prezel.core.designsystem.component.actions.button.floating.menu import androidx.annotation.DrawableRes -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.material3.Icon @@ -13,11 +11,11 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource -import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.component.base.PrezelTouchArea import com.team.prezel.core.designsystem.icon.PrezelIcons import com.team.prezel.core.designsystem.preview.BasicPreview -import com.team.prezel.core.designsystem.theme.PrezelTheme +import com.team.prezel.core.designsystem.preview.PreviewSection +import com.team.prezel.core.designsystem.preview.PreviewValueRow import com.team.prezel.core.designsystem.util.drawDashBorder /** @@ -77,34 +75,24 @@ private fun PrezelMenuItemLayout( @BasicPreview @Composable private fun PrezelMenuMenuItemPreview() { - PrezelTheme { - Column(modifier = Modifier.padding(8.dp)) { - PrezelMenu( - size = MenuSize.REGULAR, - modifier = Modifier.drawDashBorder( - shape = PrezelMenuDefaults.getDefault(size = MenuSize.REGULAR).shape, - ), - ) { - MenuItem( - label = "Label", - iconResId = PrezelIcons.Blank, - onClick = {}, - ) - } - - PrezelMenu( - size = MenuSize.SMALL, - modifier = Modifier - .padding(top = 8.dp) - .drawDashBorder( - shape = PrezelMenuDefaults.getDefault(size = MenuSize.SMALL).shape, + PreviewSection( + title = "Floating Menu Item", + description = "Floating Menu Item의 크기를 조절합니다.", + ) { + MenuSize.entries.forEach { size -> + PreviewValueRow(name = size.name) { + PrezelMenu( + size = size, + modifier = Modifier.drawDashBorder( + shape = PrezelMenuDefaults.getDefault(size = size).shape, ), - ) { - MenuItem( - label = "Label", - iconResId = PrezelIcons.Blank, - onClick = {}, - ) + ) { + MenuItem( + label = "Label", + iconResId = PrezelIcons.Blank, + onClick = {}, + ) + } } } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelDropShadow.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelDropShadow.kt index 81cd136..b8b24ad 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelDropShadow.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelDropShadow.kt @@ -2,20 +2,11 @@ package com.team.prezel.core.designsystem.component.base import android.graphics.BlurMaskFilter import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.FlowRow -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.drawWithCache import androidx.compose.ui.geometry.RoundRect @@ -32,7 +23,8 @@ import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.preview.BasicPreview -import com.team.prezel.core.designsystem.theme.PrezelTheme +import com.team.prezel.core.designsystem.preview.PreviewSection +import com.team.prezel.core.designsystem.preview.PreviewValueRow /** * 디자인 시스템 그림자 토큰을 적용하고 같은 모서리 반경의 배경을 함께 그립니다. @@ -335,31 +327,17 @@ private fun PrezelDropShadowPreview() { PrezelDropShadowDefaults.Regular(), ) - PrezelTheme { - FlowRow( - modifier = Modifier - .fillMaxWidth() - .background(Color.White) - .padding(16.dp), - verticalArrangement = Arrangement.spacedBy(16.dp), - horizontalArrangement = Arrangement.spacedBy(16.dp), - ) { - Text( - text = "PrezelDropShadow", - style = PrezelTheme.typography.body1Bold, - modifier = Modifier.fillMaxWidth(), - ) - styles.forEach { style -> - Column(horizontalAlignment = Alignment.CenterHorizontally) { - Box( - modifier = Modifier - .size(80.dp) - .prezelDropShadow(style = style), - ) - Spacer(modifier = Modifier.height(4.dp)) - - Text(text = style.javaClass.simpleName) - } + PreviewSection(title = "Drop Shadow") { + styles.forEach { style -> + PreviewValueRow( + name = style.javaClass.simpleName, + valueLabel = "", + ) { + Box( + modifier = Modifier + .size(80.dp) + .prezelDropShadow(style = style), + ) } } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelTouchArea.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelTouchArea.kt index 825bfa4..8ec69b5 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelTouchArea.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/base/PrezelTouchArea.kt @@ -19,7 +19,9 @@ import androidx.compose.ui.graphics.RectangleShape import androidx.compose.ui.graphics.Shape import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.preview.BasicPreview -import com.team.prezel.core.designsystem.theme.PrezelTheme +import com.team.prezel.core.designsystem.preview.PreviewSection +import com.team.prezel.core.designsystem.preview.PreviewValueRow +import com.team.prezel.core.designsystem.util.drawDashBorder /** * 시각 크기보다 넓은 터치 여유 영역을 줄 수 있는 클릭 컨테이너입니다. @@ -56,13 +58,32 @@ fun PrezelTouchArea( @BasicPreview @Composable private fun PrezelTouchAreaPreview() { - PrezelTheme { - PrezelTouchArea(onClick = {}) { - Box( - modifier = Modifier - .size(48.dp) - .background(Color.Cyan), - ) + PreviewSection( + title = "Touch Area", + description = "시각 크기와 별도로 터치 가능한 영역을 확인합니다.", + ) { + PreviewValueRow(name = "Extra Touch Padding (0.dp)") { + PrezelTouchArea(onClick = {}) { + Box( + modifier = Modifier + .size(48.dp) + .background(Color.Cyan), + ) + } + } + + PreviewValueRow(name = "Extra Touch Padding (12.dp)") { + PrezelTouchArea( + onClick = {}, + extraTouchPadding = PaddingValues(12.dp), + modifier = Modifier.drawDashBorder(), + ) { + Box( + modifier = Modifier + .size(48.dp) + .background(Color.Cyan), + ) + } } } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelChip.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelChip.kt index 4437aa0..a047851 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelChip.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelChip.kt @@ -7,7 +7,6 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width -import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.LocalContentColor import androidx.compose.material3.LocalTextStyle @@ -17,11 +16,14 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource import com.team.prezel.core.designsystem.icon.PrezelIcons import com.team.prezel.core.designsystem.preview.BasicPreview -import com.team.prezel.core.designsystem.preview.PreviewColumn -import com.team.prezel.core.designsystem.preview.PreviewSurface +import com.team.prezel.core.designsystem.preview.PreviewRow +import com.team.prezel.core.designsystem.preview.PreviewSection +import com.team.prezel.core.designsystem.preview.PreviewValueRow +import com.team.prezel.core.designsystem.theme.PrezelTheme @Composable fun PrezelChip( @@ -100,27 +102,128 @@ private fun PrezelChipIcon( @BasicPreview @Composable -private fun PrezelChipPreview() { - PreviewSurface { - PreviewColumn(scrollable = true) { - PrezelChipPreviewByType( - type = PrezelChipType.FILLED, - ) { style -> PrezelChipPreviewItem(style) } +private fun PrezelChipSizePreview() { + PreviewSection( + title = "Chip / Size", + description = "Chip의 크기를 조절합니다.", + ) { + PrezelChipType.entries.forEach { type -> + PrezelChipSize.entries.forEach { size -> + PreviewValueRow( + name = type.name, + valueLabel = size.name, + ) { + PrezelChip( + text = "Label", + iconResId = PrezelIcons.Blank, + style = PrezelChipStyle(type = type, size = size), + ) + } + } + } + } +} - HorizontalDivider() +@BasicPreview +@Composable +private fun PrezelChipInteractionPreview() { + PreviewSection( + title = "Chip / Interaction", + description = "Chip의 상호작용 상태를 조절합니다.", + ) { + PrezelChipType.entries.forEach { type -> + PrezelChipInteraction.entries.forEach { interaction -> + PreviewValueRow( + name = type.name, + valueLabel = interaction.name, + ) { + PrezelChip( + text = "Label", + iconResId = PrezelIcons.Blank, + style = PrezelChipStyle(type = type, interaction = interaction), + ) + } + } + } + } +} - PrezelChipPreviewByType( - type = PrezelChipType.OUTLINED, - ) { style -> PrezelChipPreviewItem(style) } +@BasicPreview +@Composable +private fun PrezelChipFeedbackPreview() { + PreviewSection( + title = "Chip / Feedback", + description = "Chip의 피드백 상태를 조절합니다.", + ) { + PrezelChipType.entries.forEach { type -> + PrezelChipFeedback.entries.forEach { feedback -> + PreviewValueRow( + name = type.name, + valueLabel = feedback.name, + ) { + PrezelChip( + text = "Label", + iconResId = PrezelIcons.Blank, + style = PrezelChipStyle(type = type, feedback = feedback), + ) + } + } } } } +@BasicPreview @Composable -private fun PrezelChipPreviewItem(style: PrezelChipStyle) { - PrezelChip( - text = "Label", - iconResId = PrezelIcons.Blank, - style = style, - ) +private fun PrezelChipCustomPreview() { + PreviewSection( + title = "Chip / Custom", + description = "사용자 정의된 색 지정이 가능합니다.", + ) { + PreviewRow { + PrezelChip( + text = "느려요", + iconResId = PrezelIcons.Blank, + style = PrezelChipStyle( + type = PrezelChipType.FILLED, + size = PrezelChipSize.REGULAR, + interaction = PrezelChipInteraction.DISABLED, + feedback = PrezelChipFeedback.BAD, + ), + customColors = PrezelChipColors( + containerColor = PrezelTheme.colors.feedbackWarningSmall, + contentColor = PrezelTheme.colors.feedbackWarningRegular, + ), + ) + + PrezelChip( + text = "빨라요", + iconResId = null, + style = PrezelChipStyle( + type = PrezelChipType.OUTLINED, + size = PrezelChipSize.REGULAR, + interaction = PrezelChipInteraction.DEFAULT, + feedback = PrezelChipFeedback.DEFAULT, + ), + customColors = PrezelChipColors( + containerColor = PrezelTheme.colors.feedbackBadSmall, + contentColor = PrezelTheme.colors.feedbackBadRegular, + ), + ) + + PrezelChip( + text = "적당해요", + iconResId = null, + style = PrezelChipStyle( + type = PrezelChipType.FILLED, + size = PrezelChipSize.SMALL, + interaction = PrezelChipInteraction.ACTIVE, + feedback = PrezelChipFeedback.DEFAULT, + ), + customColors = PrezelChipColors( + containerColor = Color(0xFFDBFFF6), + contentColor = Color(0xFF00A37A), + ), + ) + } + } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelChipPreview.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelChipPreview.kt deleted file mode 100644 index 5c2a74d..0000000 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelChipPreview.kt +++ /dev/null @@ -1,130 +0,0 @@ -package com.team.prezel.core.designsystem.component.chip - -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.material3.HorizontalDivider -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import com.team.prezel.core.designsystem.theme.PrezelTheme -import kotlinx.collections.immutable.persistentListOf - -internal typealias PrezelChipPreviewContent = @Composable (PrezelChipStyle) -> Unit - -private val DefaultInteractionVariants = persistentListOf( - PrezelChipInteraction.DEFAULT, - PrezelChipInteraction.ACTIVE, - PrezelChipInteraction.DISABLED, -) - -private val PreviewSizes = persistentListOf( - PrezelChipSize.SMALL, - PrezelChipSize.REGULAR, -) - -@Composable -internal fun PrezelChipPreviewByType( - type: PrezelChipType, - content: PrezelChipPreviewContent, -) { - Text( - text = type.name, - style = PrezelTheme.typography.title2Medium, - ) - - HorizontalDivider() - - PrezelChipBadSection( - type = type, - content = content, - ) - - HorizontalDivider() - - PrezelChipDefaultSection( - type = type, - content = content, - ) -} - -@Composable -private fun PrezelChipBadSection( - type: PrezelChipType, - content: PrezelChipPreviewContent, - modifier: Modifier = Modifier, -) { - Column( - modifier = modifier, - verticalArrangement = Arrangement.spacedBy(12.dp), - ) { - Text( - text = "Feedback: BAD", - style = PrezelTheme.typography.body2Medium, - ) - - PrezelChipPreviewBlock( - type = type, - feedback = PrezelChipFeedback.BAD, - interaction = PrezelChipInteraction.DEFAULT, - content = content, - ) - } -} - -@Composable -private fun PrezelChipDefaultSection( - type: PrezelChipType, - content: PrezelChipPreviewContent, - modifier: Modifier = Modifier, -) { - Column( - modifier = modifier, - verticalArrangement = Arrangement.spacedBy(12.dp), - ) { - Text( - text = "Feedback: DEFAULT", - style = PrezelTheme.typography.body2Medium, - ) - - DefaultInteractionVariants.forEach { interaction -> - Text( - text = "Interaction: $interaction", - style = PrezelTheme.typography.body3Medium, - ) - - PrezelChipPreviewBlock( - type = type, - feedback = PrezelChipFeedback.DEFAULT, - interaction = interaction, - content = content, - ) - } - } -} - -@Composable -private fun PrezelChipPreviewBlock( - type: PrezelChipType, - interaction: PrezelChipInteraction, - feedback: PrezelChipFeedback, - content: PrezelChipPreviewContent, - modifier: Modifier = Modifier, -) { - Row( - modifier = modifier, - horizontalArrangement = Arrangement.spacedBy(8.dp), - ) { - PreviewSizes.forEach { size -> - content( - PrezelChipStyle( - type = type, - size = size, - interaction = interaction, - feedback = feedback, - ), - ) - } - } -} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelCustomChipPreview.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelCustomChipPreview.kt deleted file mode 100644 index 9c1cc68..0000000 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelCustomChipPreview.kt +++ /dev/null @@ -1,173 +0,0 @@ -package com.team.prezel.core.designsystem.component.chip - -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.FlowRow -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.unit.dp -import com.team.prezel.core.designsystem.icon.PrezelIcons -import com.team.prezel.core.designsystem.preview.BasicPreview -import com.team.prezel.core.designsystem.preview.PreviewColumn -import com.team.prezel.core.designsystem.preview.PreviewSection -import com.team.prezel.core.designsystem.preview.PreviewSurface -import com.team.prezel.core.designsystem.theme.PrezelTheme - -@BasicPreview -@Composable -private fun PrezelChip_CustomColors_Preview() { - PreviewSurface { - PreviewColumn(scrollable = true) { - PreviewSection( - title = "Custom Chip", - showDivider = true, - ) { - CustomChipLabelSection() - CustomChipIconOnlySection() - } - } - } -} - -@Composable -private fun CustomChipLabelSection() { - FlowRow( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(8.dp), - verticalArrangement = Arrangement.spacedBy(8.dp), - maxItemsInEachRow = 3, - ) { - CustomYellowLabelChip() - CustomRedLabelChip() - CustomGreenLabelChip() - } -} - -@Composable -private fun CustomChipIconOnlySection() { - Text( - text = "Icon only", - style = PrezelTheme.typography.body3Medium, - ) - - Spacer(modifier = Modifier.height(8.dp)) - - Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) { - CustomYellowIconChip() - CustomRedIconChip() - CustomGreenIconChip() - } -} - -@Composable -private fun CustomYellowLabelChip() { - PrezelChip( - text = "느려요", - iconResId = PrezelIcons.Blank, - style = PrezelChipStyle( - type = PrezelChipType.FILLED, - size = PrezelChipSize.REGULAR, - interaction = PrezelChipInteraction.DISABLED, - feedback = PrezelChipFeedback.BAD, - ), - customColors = PrezelChipColors( - containerColor = PrezelTheme.colors.feedbackWarningSmall, - contentColor = PrezelTheme.colors.feedbackWarningRegular, - ), - ) -} - -@Composable -private fun CustomRedLabelChip() { - PrezelChip( - text = "빨라요", - iconResId = null, - style = PrezelChipStyle( - type = PrezelChipType.OUTLINED, - size = PrezelChipSize.REGULAR, - interaction = PrezelChipInteraction.DEFAULT, - feedback = PrezelChipFeedback.DEFAULT, - ), - customColors = PrezelChipColors( - containerColor = PrezelTheme.colors.feedbackBadSmall, - contentColor = PrezelTheme.colors.feedbackBadRegular, - ), - ) -} - -@Composable -private fun CustomGreenLabelChip() { - PrezelChip( - text = "적당해요", - iconResId = null, - style = PrezelChipStyle( - type = PrezelChipType.FILLED, - size = PrezelChipSize.SMALL, - interaction = PrezelChipInteraction.ACTIVE, - feedback = PrezelChipFeedback.DEFAULT, - ), - customColors = PrezelChipColors( - containerColor = Color(0xFFDBFFF6), - contentColor = Color(0xFF00A37A), - ), - ) -} - -@Composable -private fun CustomYellowIconChip() { - PrezelChip( - text = null, - iconResId = PrezelIcons.Blank, - style = PrezelChipStyle( - type = PrezelChipType.FILLED, - size = PrezelChipSize.REGULAR, - interaction = PrezelChipInteraction.DISABLED, - feedback = PrezelChipFeedback.BAD, - ), - customColors = PrezelChipColors( - containerColor = PrezelTheme.colors.feedbackWarningSmall, - contentColor = PrezelTheme.colors.feedbackWarningRegular, - ), - ) -} - -@Composable -private fun CustomRedIconChip() { - PrezelChip( - text = null, - iconResId = PrezelIcons.Blank, - style = PrezelChipStyle( - type = PrezelChipType.OUTLINED, - size = PrezelChipSize.REGULAR, - interaction = PrezelChipInteraction.DEFAULT, - feedback = PrezelChipFeedback.DEFAULT, - ), - customColors = PrezelChipColors( - containerColor = PrezelTheme.colors.feedbackBadSmall, - contentColor = PrezelTheme.colors.feedbackBadRegular, - ), - ) -} - -@Composable -private fun CustomGreenIconChip() { - PrezelChip( - text = null, - iconResId = PrezelIcons.Blank, - style = PrezelChipStyle( - type = PrezelChipType.FILLED, - size = PrezelChipSize.SMALL, - interaction = PrezelChipInteraction.ACTIVE, - feedback = PrezelChipFeedback.DEFAULT, - ), - customColors = PrezelChipColors( - containerColor = Color(0xFFDBFFF6), - contentColor = Color(0xFF00A37A), - ), - ) -} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelIconChip.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelIconChip.kt index 080b5f1..3e7e6e1 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelIconChip.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/chip/PrezelIconChip.kt @@ -1,13 +1,12 @@ package com.team.prezel.core.designsystem.component.chip import androidx.annotation.DrawableRes -import androidx.compose.material3.HorizontalDivider import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import com.team.prezel.core.designsystem.icon.PrezelIcons import com.team.prezel.core.designsystem.preview.BasicPreview -import com.team.prezel.core.designsystem.preview.PreviewColumn -import com.team.prezel.core.designsystem.preview.PreviewSurface +import com.team.prezel.core.designsystem.preview.PreviewSection +import com.team.prezel.core.designsystem.preview.PreviewValueRow @Composable fun PrezelIconChip( @@ -24,26 +23,69 @@ fun PrezelIconChip( @BasicPreview @Composable -private fun PrezelIconChipPreview() { - PreviewSurface { - PreviewColumn(scrollable = true) { - PrezelChipPreviewByType( - type = PrezelChipType.FILLED, - ) { style -> PrezelIconChipPreviewItem(style) } - - HorizontalDivider() +private fun PrezelChipSizePreview() { + PreviewSection( + title = "Chip / Size", + description = "Chip의 크기를 조절합니다.", + ) { + PrezelChipType.entries.forEach { type -> + PrezelChipSize.entries.forEach { size -> + PreviewValueRow( + name = type.name, + valueLabel = size.name, + ) { + PrezelIconChip( + iconResId = PrezelIcons.Blank, + style = PrezelChipStyle(type = type, size = size), + ) + } + } + } + } +} - PrezelChipPreviewByType( - type = PrezelChipType.OUTLINED, - ) { style -> PrezelIconChipPreviewItem(style) } +@BasicPreview +@Composable +private fun PrezelChipInteractionPreview() { + PreviewSection( + title = "Chip / Interaction", + description = "Chip의 상호작용 상태를 조절합니다.", + ) { + PrezelChipType.entries.forEach { type -> + PrezelChipInteraction.entries.forEach { interaction -> + PreviewValueRow( + name = type.name, + valueLabel = interaction.name, + ) { + PrezelIconChip( + iconResId = PrezelIcons.Blank, + style = PrezelChipStyle(type = type, interaction = interaction), + ) + } + } } } } +@BasicPreview @Composable -private fun PrezelIconChipPreviewItem(style: PrezelChipStyle) { - PrezelIconChip( - iconResId = PrezelIcons.Blank, - style = style, - ) +private fun PrezelChipFeedbackPreview() { + PreviewSection( + title = "Chip / Feedback", + description = "Chip의 피드백 상태를 조절합니다.", + ) { + PrezelChipType.entries.forEach { type -> + PrezelChipFeedback.entries.forEach { feedback -> + PreviewValueRow( + name = type.name, + valueLabel = feedback.name, + ) { + PrezelIconChip( + iconResId = PrezelIcons.Blank, + style = PrezelChipStyle(type = type, feedback = feedback), + ) + } + } + } + } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/DatePickerDayCellView.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/DatePickerDayCellView.kt index 1f35b47..8685812 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/DatePickerDayCellView.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/DatePickerDayCellView.kt @@ -3,11 +3,9 @@ package com.team.prezel.core.designsystem.component.datepicker import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CircleShape import androidx.compose.material3.Text import androidx.compose.material3.ripple @@ -16,8 +14,9 @@ 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.unit.dp import com.team.prezel.core.designsystem.preview.BasicPreview +import com.team.prezel.core.designsystem.preview.PreviewRow +import com.team.prezel.core.designsystem.preview.PreviewSection import com.team.prezel.core.designsystem.theme.PrezelTheme import kotlinx.datetime.LocalDate @@ -64,8 +63,11 @@ internal fun RowScope.DayCellView( @BasicPreview @Composable private fun DayCellViewPreview() { - PrezelTheme { - Row(modifier = Modifier.width(320.dp)) { + PreviewSection( + title = "DatePicker/Day", + description = "DatePicker에 사용되는 리소스입니다.", + ) { + PreviewRow { DayCellView( uiModel = DayCell( date = LocalDate(2024, 1, 1), diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/MonthGrid.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/MonthGrid.kt index f060372..74241f9 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/MonthGrid.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/MonthGrid.kt @@ -8,6 +8,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import com.team.prezel.core.designsystem.preview.BasicPreview +import com.team.prezel.core.designsystem.preview.PreviewSection import com.team.prezel.core.designsystem.theme.PrezelTheme import kotlinx.collections.immutable.ImmutableList import kotlinx.datetime.DayOfWeek @@ -71,7 +72,10 @@ private fun WeekRow( @BasicPreview @Composable private fun MonthGridPreview() { - PrezelTheme { + PreviewSection( + title = "DatePicker/MonthGrid", + description = "DatePicker에 사용되는 리소스입니다.", + ) { MonthGrid( yearMonth = YearMonth(year = 2026, month = 2), selectedDate = LocalDate(year = 2026, month = 2, day = 26), diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/MonthSection.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/MonthSection.kt index 7485f31..8c55322 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/MonthSection.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/MonthSection.kt @@ -8,6 +8,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import com.team.prezel.core.designsystem.R import com.team.prezel.core.designsystem.preview.BasicPreview +import com.team.prezel.core.designsystem.preview.PreviewSection import com.team.prezel.core.designsystem.theme.PrezelTheme import kotlinx.datetime.LocalDate import kotlinx.datetime.YearMonth @@ -45,7 +46,10 @@ internal fun MonthSection( @BasicPreview @Composable private fun MonthSectionPreview() { - PrezelTheme { + PreviewSection( + title = "Month Section", + description = "DatePicker에 사용되는 리소스입니다.", + ) { MonthSection( yearMonth = YearMonth(year = 2026, month = 2), selectedDate = LocalDate(year = 2026, month = 2, day = 26), diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/PrezelDatePicker.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/PrezelDatePicker.kt index a547835..2693736 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/PrezelDatePicker.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/datepicker/PrezelDatePicker.kt @@ -25,12 +25,15 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringArrayResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.R import com.team.prezel.core.designsystem.component.PrezelDividerType import com.team.prezel.core.designsystem.component.PrezelHorizontalDivider import com.team.prezel.core.designsystem.component.PrezelTopAppBar import com.team.prezel.core.designsystem.component.actions.area.PrezelButtonArea import com.team.prezel.core.designsystem.icon.PrezelIcons +import com.team.prezel.core.designsystem.preview.PreviewDefaults +import com.team.prezel.core.designsystem.preview.PreviewSurface import com.team.prezel.core.designsystem.theme.PrezelTheme import kotlinx.datetime.DateTimeUnit import kotlinx.datetime.LocalDate @@ -153,11 +156,13 @@ private fun WeekdayRow() { @Preview(showBackground = true) @Composable private fun PrezelDatePickerPreview() { - PrezelTheme { - var selected by remember { - mutableStateOf(LocalDate(year = 2026, month = 2, day = 26)) - } + var selected by remember { + mutableStateOf(LocalDate(year = 2026, month = 2, day = 26)) + } + PreviewSurface( + defaults = PreviewDefaults(screenPadding = PaddingValues(0.dp)), + ) { PrezelDatePicker( title = "발표 날짜", today = LocalDate(year = 2026, month = 2, day = 23), diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/image/PrezelImage.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/image/PrezelImage.kt index 68482d3..14176e0 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/image/PrezelImage.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/image/PrezelImage.kt @@ -3,16 +3,11 @@ package com.team.prezel.core.designsystem.component.image import androidx.annotation.DrawableRes import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.Image -import androidx.compose.foundation.background import androidx.compose.foundation.border -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -24,6 +19,8 @@ import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.component.PrezelAsyncImage import com.team.prezel.core.designsystem.icon.PrezelIcons import com.team.prezel.core.designsystem.preview.BasicPreview +import com.team.prezel.core.designsystem.preview.PreviewSection +import com.team.prezel.core.designsystem.preview.PreviewValueRow import com.team.prezel.core.designsystem.theme.PrezelTheme @Composable @@ -88,52 +85,48 @@ private fun Modifier.prezelImageContainer( @BasicPreview @Composable private fun PrezelImagePreview() { - PrezelTheme { - Column( - modifier = Modifier - .background(PrezelTheme.colors.bgRegular) - .padding(16.dp), - verticalArrangement = Arrangement.spacedBy(16.dp), - ) { - PrezelImagePreviewItem( - label = "Drawable / No Round / No Border", + PreviewSection( + title = "Image", + description = "round/border 조합별 이미지 콘텐츠를 보여줍니다.", + ) { + PreviewValueRow(name = "No Round / No Border") { + PrezelImage( + resId = PrezelIcons.Blank, + contentDescription = "", + modifier = Modifier.size(100.dp), rounded = false, border = false, ) + } - PrezelImagePreviewItem( - label = "Drawable / Round / No Border", + PreviewValueRow(name = "Round / No Border") { + PrezelImage( + resId = PrezelIcons.Blank, + contentDescription = "", + modifier = Modifier.size(100.dp), rounded = true, border = false, ) + } - PrezelImagePreviewItem( - label = "Drawable / No Round / Border", + PreviewValueRow(name = "No Round / Border") { + PrezelImage( + resId = PrezelIcons.Blank, + contentDescription = "", + modifier = Modifier.size(100.dp), rounded = false, border = true, ) + } - PrezelImagePreviewItem( - label = "Drawable / Round / Border", + PreviewValueRow(name = "Round / Border") { + PrezelImage( + resId = PrezelIcons.Blank, + contentDescription = "", + modifier = Modifier.size(100.dp), rounded = true, border = true, ) } } } - -@Composable -private fun PrezelImagePreviewItem( - label: String, - rounded: Boolean, - border: Boolean, -) { - Text(text = label) - PrezelImage( - resId = PrezelIcons.Blank, - contentDescription = label, - modifier = Modifier.size(100.dp), - rounded = rounded, - border = border, - ) -} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/list/PrezelList.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/list/PrezelList.kt index cf078ed..20b2e0d 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/list/PrezelList.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/list/PrezelList.kt @@ -18,9 +18,7 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.icon.PrezelIcons import com.team.prezel.core.designsystem.preview.BasicPreview -import com.team.prezel.core.designsystem.preview.PreviewColumn import com.team.prezel.core.designsystem.preview.PreviewSection -import com.team.prezel.core.designsystem.preview.PreviewSurface import com.team.prezel.core.designsystem.theme.PrezelTheme import com.team.prezel.core.designsystem.util.drawDashBorder @@ -76,21 +74,13 @@ private fun RowScope.PrezelListTitle( @BasicPreview @Composable private fun PrezelListSmallPreview() { - PreviewSurface { - PreviewColumn(scrollable = true) { - PrezelListPreviewBySize(PrezelListSize.SMALL) - } - } + PrezelListPreviewBySize(PrezelListSize.SMALL) } @BasicPreview @Composable private fun PrezelListRegularPreview() { - PreviewSurface { - PreviewColumn(scrollable = true) { - PrezelListPreviewBySize(PrezelListSize.REGULAR) - } - } + PrezelListPreviewBySize(PrezelListSize.REGULAR) } @Composable @@ -133,7 +123,6 @@ private fun PrezelListPreviewBySize(size: PrezelListSize) { PreviewSection( title = "PrezelList - $size", description = "점선 테두리는 컴포넌트 경계를 의미하며,\nnested 상태별 leading/trailing 조합을 확인할 수 있습니다.", - showDivider = true, ) { Text(text = "Nested: False", style = PrezelTheme.typography.body2Bold) PrezelListPreviewItem(size, nested = false, showLeadingContent = true, showTrailingContent = true) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/snackbar/PrezelSnackbar.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/snackbar/PrezelSnackbar.kt index 87a9829..b3de7ef 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/snackbar/PrezelSnackbar.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/snackbar/PrezelSnackbar.kt @@ -1,7 +1,6 @@ package com.team.prezel.core.designsystem.component.snackbar import androidx.annotation.DrawableRes -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth @@ -26,6 +25,7 @@ import com.team.prezel.core.designsystem.component.actions.button.config.ButtonT import com.team.prezel.core.designsystem.foundation.typography.PrezelTextStyles import com.team.prezel.core.designsystem.icon.PrezelIcons import com.team.prezel.core.designsystem.preview.BasicPreview +import com.team.prezel.core.designsystem.preview.PreviewSection import com.team.prezel.core.designsystem.theme.PrezelColorScheme import com.team.prezel.core.designsystem.theme.PrezelTheme @@ -89,16 +89,17 @@ private fun PrezelSnackbarLeadingIcon( @BasicPreview @Composable private fun PrezelSnackBarPreview_Cases() { - PrezelTheme { - Column { - PrezelSnackbar( - data = previewData(message = "Message", actionLabel = "Action", iconResId = PrezelIcons.Blank), - ) + PreviewSection( + title = "Snackbar", + description = "유저에게 현재 단계에 대한 정보를 버튼과 함께 제공합니다.", + ) { + PrezelSnackbar( + data = previewData(message = "Message", actionLabel = "Action", iconResId = PrezelIcons.Blank), + ) - PrezelSnackbar( - data = previewData(message = "Message Message Message Message Message", actionLabel = "Action"), - ) - } + PrezelSnackbar( + data = previewData(message = "Message Message Message Message Message", actionLabel = "Action"), + ) } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldLabel.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldLabel.kt index 6588266..c4dd783 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldLabel.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldLabel.kt @@ -6,6 +6,8 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.preview.BasicPreview +import com.team.prezel.core.designsystem.preview.PreviewSection +import com.team.prezel.core.designsystem.preview.PreviewSurface import com.team.prezel.core.designsystem.theme.PrezelTheme @Composable @@ -25,7 +27,9 @@ internal fun PrezelTextFieldLabel( @BasicPreview @Composable private fun PrezelTextFieldLabelPreview() { - PrezelTheme { - PrezelTextFieldLabel(label = "Label", modifier = Modifier.padding(8.dp)) + PreviewSurface { + PreviewSection(title = "TextField Label") { + PrezelTextFieldLabel(label = "Label", modifier = Modifier.padding(8.dp)) + } } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldPlaceholder.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldPlaceholder.kt index 806806d..cc25117 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldPlaceholder.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldPlaceholder.kt @@ -7,6 +7,8 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.LineHeightStyle import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.preview.BasicPreview +import com.team.prezel.core.designsystem.preview.PreviewSection +import com.team.prezel.core.designsystem.preview.PreviewSurface import com.team.prezel.core.designsystem.theme.PrezelTheme @Composable @@ -31,10 +33,12 @@ internal fun PrezelTextFieldPlaceholder( @BasicPreview @Composable private fun PrezelTextFieldPlaceholderPreview() { - PrezelTheme { - PrezelTextFieldPlaceholder( - placeholder = "Placeholder", - modifier = Modifier.padding(16.dp), - ) + PreviewSurface { + PreviewSection(title = "TextField Placeholder") { + PrezelTextFieldPlaceholder( + placeholder = "Placeholder", + modifier = Modifier.padding(16.dp), + ) + } } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldSupportingText.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldSupportingText.kt index c42e789..9fb5902 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldSupportingText.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldSupportingText.kt @@ -11,6 +11,8 @@ import com.team.prezel.core.designsystem.component.textfield.PrezelTextFieldFeed import com.team.prezel.core.designsystem.component.textfield.PrezelTextFieldInteraction import com.team.prezel.core.designsystem.component.textfield.PrezelTextFieldState import com.team.prezel.core.designsystem.preview.BasicPreview +import com.team.prezel.core.designsystem.preview.PreviewSection +import com.team.prezel.core.designsystem.preview.PreviewSurface import com.team.prezel.core.designsystem.theme.PrezelTheme @Composable @@ -30,31 +32,33 @@ internal fun PrezelTextFieldSupportingText( @BasicPreview @Composable private fun PrezelTextFieldSupportingTextPreview() { - PrezelTheme { - Column( - modifier = Modifier.padding(8.dp), - verticalArrangement = Arrangement.spacedBy(8.dp), - ) { - PrezelTextFieldSupportingText( - state = PrezelTextFieldState( - interaction = PrezelTextFieldInteraction.TYPED, - feedback = PrezelTextFieldFeedback.Default("헬퍼 메시지"), - ), - ) + PreviewSurface { + PreviewSection(title = "Supporting Text") { + Column( + modifier = Modifier.padding(8.dp), + verticalArrangement = Arrangement.spacedBy(8.dp), + ) { + PrezelTextFieldSupportingText( + state = PrezelTextFieldState( + interaction = PrezelTextFieldInteraction.TYPED, + feedback = PrezelTextFieldFeedback.Default("헬퍼 메시지"), + ), + ) - PrezelTextFieldSupportingText( - state = PrezelTextFieldState( - interaction = PrezelTextFieldInteraction.TYPED, - feedback = PrezelTextFieldFeedback.Bad("헬퍼 메시지"), - ), - ) + PrezelTextFieldSupportingText( + state = PrezelTextFieldState( + interaction = PrezelTextFieldInteraction.TYPED, + feedback = PrezelTextFieldFeedback.Bad("헬퍼 메시지"), + ), + ) - PrezelTextFieldSupportingText( - state = PrezelTextFieldState( - interaction = PrezelTextFieldInteraction.TYPED, - feedback = PrezelTextFieldFeedback.Good("헬퍼 메시지"), - ), - ) + PrezelTextFieldSupportingText( + state = PrezelTextFieldState( + interaction = PrezelTextFieldInteraction.TYPED, + feedback = PrezelTextFieldFeedback.Good("헬퍼 메시지"), + ), + ) + } } } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelRadius.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelRadius.kt index a731c53..a86cf94 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelRadius.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelRadius.kt @@ -10,12 +10,9 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.preview.BasicPreview -import com.team.prezel.core.designsystem.preview.PreviewColumn import com.team.prezel.core.designsystem.preview.PreviewSection -import com.team.prezel.core.designsystem.preview.PreviewSurface import com.team.prezel.core.designsystem.preview.PreviewValueRow import com.team.prezel.core.designsystem.theme.PrezelTheme -import kotlinx.collections.immutable.persistentListOf object PrezelRadius { val V2 = 2.dp @@ -30,20 +27,11 @@ object PrezelRadius { @BasicPreview @Composable private fun RadiusTokensPreview() { - PreviewSurface { - PreviewColumn(scrollable = true) { - RadiusSection() - } - } -} - -@Composable -private fun RadiusSection() { PreviewSection( title = "Radius", - showDivider = true, + description = "둥근 정도에 사용하는 숫자입니다.", ) { - persistentListOf( + listOf( "V2" to PrezelRadius.V2, "V4" to PrezelRadius.V4, "V6" to PrezelRadius.V6, @@ -72,3 +60,7 @@ private fun RadiusSection() { } } } + +@Composable +private fun RadiusSection() { +} diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelShapes.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelShapes.kt index a9db9bd..3d94cc7 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelShapes.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelShapes.kt @@ -2,9 +2,7 @@ package com.team.prezel.core.designsystem.foundation.number import androidx.compose.foundation.background import androidx.compose.foundation.border -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable @@ -12,13 +10,9 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.preview.BasicPreview -import com.team.prezel.core.designsystem.preview.PreviewColumn import com.team.prezel.core.designsystem.preview.PreviewSection -import com.team.prezel.core.designsystem.preview.PreviewSurface import com.team.prezel.core.designsystem.preview.PreviewValueRow import com.team.prezel.core.designsystem.theme.PrezelTheme -import kotlinx.collections.immutable.ImmutableList -import kotlinx.collections.immutable.persistentListOf object PrezelShapes { val V2 = RoundedCornerShape(PrezelRadius.V2) @@ -33,47 +27,29 @@ object PrezelShapes { @BasicPreview @Composable private fun ShapesTokensPreview() { - PreviewSurface { - PreviewColumn(scrollable = true) { - ShapesSection() - } - } -} - -@Composable -private fun ShapesSection() { PreviewSection( title = "Shapes", - showDivider = true, ) { - ShapeList( - items = persistentListOf( - "V2" to PrezelShapes.V2, - "V4" to PrezelShapes.V4, - "V6" to PrezelShapes.V6, - "V8" to PrezelShapes.V8, - "V12" to PrezelShapes.V12, - "V16" to PrezelShapes.V16, - "V1000" to PrezelShapes.V1000, - ), - ) - } -} - -@Composable -private fun ShapeList(items: ImmutableList>) { - Column(verticalArrangement = Arrangement.spacedBy(10.dp)) { - items.forEach { (name, shape) -> - PreviewValueRow( - name = name, - valueLabel = "shape", - ) { + listOf( + "V2" to PrezelShapes.V2, + "V4" to PrezelShapes.V4, + "V6" to PrezelShapes.V6, + "V8" to PrezelShapes.V8, + "V12" to PrezelShapes.V12, + "V16" to PrezelShapes.V16, + "V1000" to PrezelShapes.V1000, + ).forEach { (name, shape) -> + PreviewValueRow(name = name) { Box( modifier = Modifier .size(40.dp) .clip(shape) .background(PrezelTheme.colors.bgLarge) - .border(PrezelStroke.V1, PrezelTheme.colors.borderRegular, shape), + .border( + width = PrezelStroke.V1, + color = PrezelTheme.colors.borderRegular, + shape = shape, + ), ) } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelSpacing.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelSpacing.kt index 9253018..1b81c98 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelSpacing.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelSpacing.kt @@ -2,20 +2,16 @@ package com.team.prezel.core.designsystem.foundation.number import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.width import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.preview.BasicPreview import com.team.prezel.core.designsystem.preview.PreviewColumn import com.team.prezel.core.designsystem.preview.PreviewSection -import com.team.prezel.core.designsystem.preview.PreviewSurface import com.team.prezel.core.designsystem.preview.PreviewValueRow import com.team.prezel.core.designsystem.theme.PrezelTheme -import kotlinx.collections.immutable.persistentListOf object PrezelSpacing { val V0 = 0.dp @@ -43,46 +39,37 @@ object PrezelSpacing { @BasicPreview @Composable private fun SpacingTokensPreview() { - PreviewSurface { - PreviewColumn(scrollable = true) { - SpacingSection() - } - } -} - -@Composable -private fun SpacingSection() { PreviewSection( title = "Spacing", - showDivider = true, + description = "간격에 사용하는 숫자입니다.", ) { - persistentListOf( - "V0" to PrezelSpacing.V0, - "V2" to PrezelSpacing.V2, - "V4" to PrezelSpacing.V4, - "V6" to PrezelSpacing.V6, - "V8" to PrezelSpacing.V8, - "V10" to PrezelSpacing.V10, - "V12" to PrezelSpacing.V12, - "V14" to PrezelSpacing.V14, - "V16" to PrezelSpacing.V16, - "V20" to PrezelSpacing.V20, - "V24" to PrezelSpacing.V24, - "V28" to PrezelSpacing.V28, - "V32" to PrezelSpacing.V32, - "V36" to PrezelSpacing.V36, - "V40" to PrezelSpacing.V40, - "V48" to PrezelSpacing.V48, - "V56" to PrezelSpacing.V56, - "V64" to PrezelSpacing.V64, - "V72" to PrezelSpacing.V72, - "V80" to PrezelSpacing.V80, - ).forEach { (name, spacing) -> - PreviewValueRow( - name = name, - valueLabel = "${spacing.value}dp", - ) { - Row(verticalAlignment = Alignment.CenterVertically) { + PreviewColumn(scrollable = true) { + listOf( + "V0" to PrezelSpacing.V0, + "V2" to PrezelSpacing.V2, + "V4" to PrezelSpacing.V4, + "V6" to PrezelSpacing.V6, + "V8" to PrezelSpacing.V8, + "V10" to PrezelSpacing.V10, + "V12" to PrezelSpacing.V12, + "V14" to PrezelSpacing.V14, + "V16" to PrezelSpacing.V16, + "V20" to PrezelSpacing.V20, + "V24" to PrezelSpacing.V24, + "V28" to PrezelSpacing.V28, + "V32" to PrezelSpacing.V32, + "V36" to PrezelSpacing.V36, + "V40" to PrezelSpacing.V40, + "V48" to PrezelSpacing.V48, + "V56" to PrezelSpacing.V56, + "V64" to PrezelSpacing.V64, + "V72" to PrezelSpacing.V72, + "V80" to PrezelSpacing.V80, + ).forEach { (name, spacing) -> + PreviewValueRow( + name = name, + valueLabel = "${spacing.value}dp", + ) { Box( modifier = Modifier .height(8.dp) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelStroke.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelStroke.kt index 0ef9315..29d6cf1 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelStroke.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelStroke.kt @@ -7,12 +7,9 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.preview.BasicPreview -import com.team.prezel.core.designsystem.preview.PreviewColumn import com.team.prezel.core.designsystem.preview.PreviewSection -import com.team.prezel.core.designsystem.preview.PreviewSurface import com.team.prezel.core.designsystem.preview.PreviewValueRow import com.team.prezel.core.designsystem.theme.PrezelTheme -import kotlinx.collections.immutable.persistentListOf object PrezelStroke { val V1 = 1.dp @@ -23,20 +20,11 @@ object PrezelStroke { @BasicPreview @Composable private fun StrokeTokensPreview() { - PreviewSurface { - PreviewColumn(scrollable = true) { - StrokeSection() - } - } -} - -@Composable -private fun StrokeSection() { PreviewSection( title = "Stroke", - showDivider = true, + description = "테두리 굵기에 사용하는 숫자입니다.", ) { - persistentListOf( + listOf( "V1" to PrezelStroke.V1, "V2" to PrezelStroke.V2, "V4" to PrezelStroke.V4, @@ -51,7 +39,6 @@ private fun StrokeSection() { .border( width = stroke, color = PrezelTheme.colors.borderLarge, - shape = PrezelShapes.V8, ), ) } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/PreviewComponent.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/PreviewComponent.kt index 5ec7f4a..ae238d6 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/PreviewComponent.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/PreviewComponent.kt @@ -9,17 +9,9 @@ import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.RowScope -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.WindowInsets -import androidx.compose.foundation.layout.asPaddingValues import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.safeDrawing -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.lazy.grid.GridCells -import androidx.compose.foundation.lazy.grid.LazyVerticalGrid -import androidx.compose.foundation.lazy.grid.items import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material3.HorizontalDivider @@ -47,34 +39,26 @@ internal data class PreviewDefaults( /** * 디자인시스템 Preview의 기본 배경, 패딩, 테마를 제공합니다. * - * 대부분의 Preview는 이 컴포넌트로 감싸는 것을 권장합니다. + * 대부분의 Preview는 이 컴포넌트를 기본 루트로 사용합니다. + * 화면 전체 문맥이 필요한 경우에만 `PreviewScaffold`를 사용합니다. */ @Composable internal fun PreviewSurface( modifier: Modifier = Modifier, defaults: PreviewDefaults = PreviewDefaults(), - useSystemInsets: Boolean = false, contentAlignment: Alignment = Alignment.TopStart, content: @Composable BoxScope.() -> Unit, ) { PrezelTheme { Surface( - modifier = modifier.fillMaxSize(), + modifier = modifier.fillMaxWidth(), color = PrezelTheme.colors.bgRegular, ) { - val containerModifier = Modifier - .fillMaxSize() - .background(PrezelTheme.colors.bgRegular) - .then( - if (useSystemInsets) { - Modifier.padding(WindowInsets.safeDrawing.asPaddingValues()) - } else { - Modifier - }, - ).padding(defaults.screenPadding) - Box( - modifier = containerModifier, + modifier = Modifier + .fillMaxWidth() + .background(PrezelTheme.colors.bgRegular) + .padding(defaults.screenPadding), contentAlignment = contentAlignment, content = content, ) @@ -94,21 +78,22 @@ internal fun PreviewColumn( horizontalAlignment: Alignment.Horizontal = Alignment.Start, content: @Composable ColumnScope.() -> Unit, ) { - val scrollModifier = - if (scrollable) { - Modifier.verticalScroll(rememberScrollState()) - } else { - Modifier - } - - Column( - modifier = modifier - .fillMaxWidth() - .then(scrollModifier), - verticalArrangement = verticalArrangement, - horizontalAlignment = horizontalAlignment, - content = content, - ) + PrezelTheme { + Column( + modifier = modifier + .fillMaxWidth() + .then( + if (scrollable) { + Modifier.verticalScroll(rememberScrollState()) + } else { + Modifier + }, + ), + verticalArrangement = verticalArrangement, + horizontalAlignment = horizontalAlignment, + content = content, + ) + } } /** @@ -121,54 +106,13 @@ internal fun PreviewRow( verticalAlignment: Alignment.Vertical = Alignment.CenterVertically, content: @Composable RowScope.() -> Unit, ) { - Row( - modifier = modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(defaults.itemSpacing), - verticalAlignment = verticalAlignment, - content = content, - ) -} - -/** - * Preview에서 반복 가능한 작은 컴포넌트를 그리드 형태로 보여줍니다. - * - * 칩, 아이콘 버튼, 배지처럼 여러 변형을 한 번에 확인할 때 유용합니다. - */ -@Composable -internal fun PreviewGrid( - items: List, - modifier: Modifier = Modifier, - columns: Int = 2, - defaults: PreviewDefaults = PreviewDefaults(), - key: ((T) -> Any)? = null, - itemContent: @Composable (T) -> Unit, -) { - require(columns > 0) { - "columns는 1 이상이어야 합니다." - } - - LazyVerticalGrid( - columns = GridCells.Fixed(columns), - modifier = modifier - .fillMaxWidth() - .fillMaxSize(), - horizontalArrangement = Arrangement.spacedBy(defaults.itemSpacing), - verticalArrangement = Arrangement.spacedBy(defaults.itemSpacing), - userScrollEnabled = true, - ) { - if (key == null) { - items(items) { item -> - itemContent(item) - } - return@LazyVerticalGrid - } - - items( - items = items, - key = key, - ) { item -> - itemContent(item) - } + PrezelTheme { + Row( + modifier = modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(defaults.itemSpacing), + verticalAlignment = verticalAlignment, + content = content, + ) } } @@ -181,35 +125,34 @@ internal fun PreviewSection( modifier: Modifier = Modifier, defaults: PreviewDefaults = PreviewDefaults(), description: String? = null, - showDivider: Boolean = false, content: @Composable ColumnScope.() -> Unit, ) { - Column( - modifier = modifier.fillMaxWidth(), - verticalArrangement = Arrangement.spacedBy(defaults.itemSpacing), - ) { - Text( - text = title, - style = PrezelTheme.typography.title2Medium, - color = PrezelTheme.colors.textLarge, - ) + PreviewSurface { + Column( + modifier = modifier.fillMaxWidth(), + verticalArrangement = Arrangement.spacedBy(defaults.itemSpacing), + ) { + Text( + text = title, + style = PrezelTheme.typography.title2Medium, + color = PrezelTheme.colors.textLarge, + ) + + description?.let { value -> + Text( + text = value, + style = PrezelTheme.typography.body3Regular, + color = PrezelTheme.colors.textRegular, + ) + } - if (showDivider) { HorizontalDivider(color = PrezelTheme.colors.borderRegular) - } - description?.let { value -> - Text( - text = value, - style = PrezelTheme.typography.body3Regular, - color = PrezelTheme.colors.textRegular, + PreviewColumn( + defaults = defaults, + content = content, ) } - - PreviewColumn( - defaults = defaults, - content = content, - ) } } @@ -219,9 +162,8 @@ internal fun PreviewSection( @Composable internal fun PreviewValueRow( name: String, - valueLabel: String, modifier: Modifier = Modifier, - nameWidth: Dp = 120.dp, + valueLabel: String? = null, preview: @Composable () -> Unit, ) { Row( @@ -229,24 +171,23 @@ internal fun PreviewValueRow( horizontalArrangement = Arrangement.spacedBy(12.dp), verticalAlignment = Alignment.CenterVertically, ) { - Text( - text = name, - style = PrezelTheme.typography.body3Medium, - color = PrezelTheme.colors.textMedium, - modifier = Modifier.width(nameWidth), - ) - Text( - text = valueLabel, - style = PrezelTheme.typography.body3Regular, - color = PrezelTheme.colors.textSmall, - modifier = Modifier.weight(1f), - ) - Spacer(modifier = Modifier.weight(1f)) - Box( - modifier = Modifier - .background(PrezelTheme.colors.bgRegular) - .padding(4.dp), - ) { + Row(modifier = Modifier.weight(1f)) { + Text( + text = name, + style = PrezelTheme.typography.body3Medium, + color = PrezelTheme.colors.textMedium, + modifier = Modifier.weight(1f), + ) + valueLabel?.let { label -> + Text( + text = label, + style = PrezelTheme.typography.body3Regular, + color = PrezelTheme.colors.textSmall, + modifier = Modifier.weight(1f), + ) + } + } + Box(contentAlignment = Alignment.CenterEnd) { preview() } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/theme/PrezelColorScheme.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/theme/PrezelColorScheme.kt index 53626eb..49120df 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/theme/PrezelColorScheme.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/theme/PrezelColorScheme.kt @@ -14,9 +14,7 @@ import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.foundation.color.ColorTokens import com.team.prezel.core.designsystem.foundation.color.PrezelColors import com.team.prezel.core.designsystem.preview.BasicPreview -import com.team.prezel.core.designsystem.preview.PreviewColumn import com.team.prezel.core.designsystem.preview.PreviewSection -import com.team.prezel.core.designsystem.preview.PreviewSurface import com.team.prezel.core.designsystem.preview.PreviewValueRow import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf @@ -230,29 +228,23 @@ private fun PrezelColorsPreviewSection( title: String, description: String, items: ImmutableList>, - colors: PrezelColors = PrezelTheme.colors, ) { - PreviewSurface { - PreviewColumn(scrollable = true) { - PreviewSection( - title = title, - description = description, - showDivider = true, + PreviewSection( + title = title, + description = description, + ) { + items.forEach { (name, color) -> + PreviewValueRow( + name = name, + valueLabel = String.format(Locale.ROOT, "#%08X", color.toArgb()), ) { - items.forEach { (name, color) -> - PreviewValueRow( - name = name, - valueLabel = String.format(Locale.ROOT, "#%08X", color.toArgb()), - ) { - Box( - modifier = Modifier - .size(32.dp) - .clip(RoundedCornerShape(8.dp)) - .background(color) - .border(0.3.dp, PrezelTheme.colors.solidBlack, RoundedCornerShape(8.dp)), - ) - } - } + Box( + modifier = Modifier + .size(36.dp) + .clip(RoundedCornerShape(8.dp)) + .background(color) + .border(0.3.dp, PrezelTheme.colors.solidBlack, RoundedCornerShape(8.dp)), + ) } } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/theme/PrezelTypographyScheme.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/theme/PrezelTypographyScheme.kt index 02d3fba..bc5af8b 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/theme/PrezelTypographyScheme.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/theme/PrezelTypographyScheme.kt @@ -1,9 +1,7 @@ package com.team.prezel.core.designsystem.theme import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Text @@ -12,12 +10,10 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.text.TextStyle import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.isSpecified import com.team.prezel.core.designsystem.foundation.typography.PrezelTextStyles import com.team.prezel.core.designsystem.foundation.typography.PrezelTypography -import com.team.prezel.core.designsystem.preview.PreviewColumn import com.team.prezel.core.designsystem.preview.PreviewSection -import com.team.prezel.core.designsystem.preview.PreviewSurface +import com.team.prezel.core.designsystem.preview.PreviewValueRow import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf @@ -47,14 +43,17 @@ internal object PrezelTypographyScheme { @Preview( showBackground = true, - device = "spec:width=800dp,height=600dp", - fontScale = 10f, + device = "spec:width=900dp,height=600dp", ) +private annotation class TypographyPreview + +@TypographyPreview @Composable private fun PrezelTypographyTitlePreview() { val typography = PrezelTypographyScheme.Default() PrezelTypographyPreviewContent( title = "Title", + description = "페이지나 섹션의 주요 제목 등 핵심 정보를 강조하는 데 사용하는 스타일입니다.", items = persistentListOf( "Title1 Medium" to typography.title1Medium, "Title1 Bold" to typography.title1Bold, @@ -64,16 +63,13 @@ private fun PrezelTypographyTitlePreview() { ) } -@Preview( - showBackground = true, - device = "spec:width=800dp,height=1000dp", - fontScale = 10f, -) +@TypographyPreview @Composable private fun PrezelTypographyBodyPreview() { val typography = PrezelTypographyScheme.Default() PrezelTypographyPreviewContent( title = "Body", + description = "일반 본문과 설명, 단일 문장 또는 단락 등의 주된 콘텐츠 전달에 사용하는 스타일입니다.", items = persistentListOf( "Body1 Regular" to typography.body1Regular, "Body1 Medium" to typography.body1Medium, @@ -88,16 +84,13 @@ private fun PrezelTypographyBodyPreview() { ) } -@Preview( - showBackground = true, - device = "spec:width=800dp,height=600dp", - fontScale = 10f, -) +@TypographyPreview @Composable private fun PrezelTypographyCaptionPreview() { val typography = PrezelTypographyScheme.Default() PrezelTypographyPreviewContent( title = "Caption", + description = "부가 정보, 안내, 설명, 작성 시간 등 메인 콘텐츠를 보조하는 짧은 정보를 전달할 때 사용하는 스타일입니다.", items = persistentListOf( "Caption1 Regular" to typography.caption1Regular, "Caption1 Medium" to typography.caption1Medium, @@ -110,59 +103,18 @@ private fun PrezelTypographyCaptionPreview() { @Composable private fun PrezelTypographyPreviewContent( title: String, + description: String, items: ImmutableList>, ) { - PreviewSurface { - PreviewColumn(scrollable = true) { - PreviewSection( - title = title, - showDivider = true, - ) { - Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { - items.forEach { (name, style) -> - TypographyRow(name = name, style = style) - } - } - } - } - } -} - -@Composable -private fun TypographyRow( - name: String, - style: TextStyle, -) { - Column( - modifier = Modifier - .fillMaxSize() - .background( - color = PrezelTheme.colors.bgRegular, - shape = RoundedCornerShape(12.dp), - ), - verticalArrangement = Arrangement.spacedBy(6.dp), + PreviewSection( + title = title, + description = description, ) { - Column(verticalArrangement = Arrangement.spacedBy(2.dp)) { - val fontSize = style.fontSize - val lineHeight = style.lineHeight - val letterSpacing = style.letterSpacing - val fontWeight = style.fontWeight - - Text( - text = buildString { - append("$name (") - append("size: $fontSize") - if (lineHeight.isSpecified) append(" · lh: $lineHeight") - if (letterSpacing.isSpecified) append(" · ls: $letterSpacing") - if (fontWeight != null) append(" · w: ${fontWeight.weight}") - append(")") - }, - style = PrezelTheme.typography.body3Bold, - color = PrezelTheme.colors.textMedium, - ) + items.forEach { (name, style) -> + PreviewValueRow(name = name) { + TypographySampleText(style = style) + } } - - TypographySampleText(style = style) } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/util/DrawDashBorder.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/util/DrawDashBorder.kt index afe6109..d70115b 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/util/DrawDashBorder.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/util/DrawDashBorder.kt @@ -16,7 +16,7 @@ import androidx.compose.ui.graphics.Shape import androidx.compose.ui.graphics.drawscope.Stroke import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.preview.BasicPreview -import com.team.prezel.core.designsystem.theme.PrezelTheme +import com.team.prezel.core.designsystem.preview.PreviewSection /** * 점선 테두리를 그리는 [Modifier] 확장 함수. @@ -73,7 +73,10 @@ fun Modifier.drawDashBorder( @BasicPreview @Composable private fun DrawDashBorderPreview() { - PrezelTheme { + PreviewSection( + title = "Dashed Border", + description = "테두리 외곽선을 점선으로 표시합니다.", + ) { Box( modifier = Modifier .fillMaxWidth() From 43ba42191fbcae54f635f15b5cd8d958d7c3bf13 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Wed, 25 Mar 2026 04:00:44 +0900 Subject: [PATCH 28/42] =?UTF-8?q?chore:=20Detekt=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20=EB=B0=8F=20=EB=AF=B8?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=20=EC=BD=94=EB=93=9C=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/designsystem/foundation/number/PrezelRadius.kt | 4 ---- Prezel/detekt-config.yml | 6 +++--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelRadius.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelRadius.kt index a86cf94..04c0b12 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelRadius.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/foundation/number/PrezelRadius.kt @@ -60,7 +60,3 @@ private fun RadiusTokensPreview() { } } } - -@Composable -private fun RadiusSection() { -} diff --git a/Prezel/detekt-config.yml b/Prezel/detekt-config.yml index b45f3e8..d0af157 100644 --- a/Prezel/detekt-config.yml +++ b/Prezel/detekt-config.yml @@ -15,14 +15,15 @@ style: UnusedPrivateMember: ignoreAnnotated: - Preview - - ThemePreview + - BasicPreview + - TypographyPreview complexity: LongMethod: threshold: 50 ignoreAnnotated: - Preview - - ThemePreview + - BasicPreview NestedBlockDepth: threshold: 4 LongParameterList: @@ -31,7 +32,6 @@ complexity: constructorThreshold: 10 ignoreAnnotated: - Composable - TooManyFunctions: active: true thresholdInFiles: 20 From 4c249c3a4cc7478a4d8ad15469a737067b2af0c2 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Wed, 25 Mar 2026 04:10:13 +0900 Subject: [PATCH 29/42] =?UTF-8?q?refactor:=20TextField=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20Preview=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TextField 구성 요소들의 Preview 코드에서 불필요한 `PreviewSurface` 래퍼를 제거하고 구조를 단순화했습니다. * `PrezelTextFieldLabel`: Preview에서 `PreviewSurface` 제거 및 미사용 import 정리 * `PrezelTextFieldPlaceholder`: Preview에서 `PreviewSurface` 제거 및 미사용 import 정리 * `PrezelTextFieldSupportingText`: Preview에서 `PreviewSurface` 및 불필요한 `Column` 레이아웃 제거, 미사용 import 정리 --- .../component/PrezelTextFieldLabel.kt | 7 +-- .../component/PrezelTextFieldPlaceholder.kt | 13 ++--- .../PrezelTextFieldSupportingText.kt | 50 +++++++------------ 3 files changed, 26 insertions(+), 44 deletions(-) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldLabel.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldLabel.kt index c4dd783..a2baebe 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldLabel.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldLabel.kt @@ -7,7 +7,6 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.preview.BasicPreview import com.team.prezel.core.designsystem.preview.PreviewSection -import com.team.prezel.core.designsystem.preview.PreviewSurface import com.team.prezel.core.designsystem.theme.PrezelTheme @Composable @@ -27,9 +26,7 @@ internal fun PrezelTextFieldLabel( @BasicPreview @Composable private fun PrezelTextFieldLabelPreview() { - PreviewSurface { - PreviewSection(title = "TextField Label") { - PrezelTextFieldLabel(label = "Label", modifier = Modifier.padding(8.dp)) - } + PreviewSection(title = "TextField Label") { + PrezelTextFieldLabel(label = "Label", modifier = Modifier.padding(8.dp)) } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldPlaceholder.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldPlaceholder.kt index cc25117..480ba2d 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldPlaceholder.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldPlaceholder.kt @@ -8,7 +8,6 @@ import androidx.compose.ui.text.style.LineHeightStyle import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.preview.BasicPreview import com.team.prezel.core.designsystem.preview.PreviewSection -import com.team.prezel.core.designsystem.preview.PreviewSurface import com.team.prezel.core.designsystem.theme.PrezelTheme @Composable @@ -33,12 +32,10 @@ internal fun PrezelTextFieldPlaceholder( @BasicPreview @Composable private fun PrezelTextFieldPlaceholderPreview() { - PreviewSurface { - PreviewSection(title = "TextField Placeholder") { - PrezelTextFieldPlaceholder( - placeholder = "Placeholder", - modifier = Modifier.padding(16.dp), - ) - } + PreviewSection(title = "TextField Placeholder") { + PrezelTextFieldPlaceholder( + placeholder = "Placeholder", + modifier = Modifier.padding(16.dp), + ) } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldSupportingText.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldSupportingText.kt index 9fb5902..81d7692 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldSupportingText.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/textfield/component/PrezelTextFieldSupportingText.kt @@ -1,18 +1,13 @@ package com.team.prezel.core.designsystem.component.textfield.component -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.padding import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp import com.team.prezel.core.designsystem.component.textfield.PrezelTextFieldFeedback import com.team.prezel.core.designsystem.component.textfield.PrezelTextFieldInteraction import com.team.prezel.core.designsystem.component.textfield.PrezelTextFieldState import com.team.prezel.core.designsystem.preview.BasicPreview import com.team.prezel.core.designsystem.preview.PreviewSection -import com.team.prezel.core.designsystem.preview.PreviewSurface import com.team.prezel.core.designsystem.theme.PrezelTheme @Composable @@ -32,33 +27,26 @@ internal fun PrezelTextFieldSupportingText( @BasicPreview @Composable private fun PrezelTextFieldSupportingTextPreview() { - PreviewSurface { - PreviewSection(title = "Supporting Text") { - Column( - modifier = Modifier.padding(8.dp), - verticalArrangement = Arrangement.spacedBy(8.dp), - ) { - PrezelTextFieldSupportingText( - state = PrezelTextFieldState( - interaction = PrezelTextFieldInteraction.TYPED, - feedback = PrezelTextFieldFeedback.Default("헬퍼 메시지"), - ), - ) + PreviewSection(title = "Supporting Text") { + PrezelTextFieldSupportingText( + state = PrezelTextFieldState( + interaction = PrezelTextFieldInteraction.TYPED, + feedback = PrezelTextFieldFeedback.Default("헬퍼 메시지"), + ), + ) - PrezelTextFieldSupportingText( - state = PrezelTextFieldState( - interaction = PrezelTextFieldInteraction.TYPED, - feedback = PrezelTextFieldFeedback.Bad("헬퍼 메시지"), - ), - ) + PrezelTextFieldSupportingText( + state = PrezelTextFieldState( + interaction = PrezelTextFieldInteraction.TYPED, + feedback = PrezelTextFieldFeedback.Bad("헬퍼 메시지"), + ), + ) - PrezelTextFieldSupportingText( - state = PrezelTextFieldState( - interaction = PrezelTextFieldInteraction.TYPED, - feedback = PrezelTextFieldFeedback.Good("헬퍼 메시지"), - ), - ) - } - } + PrezelTextFieldSupportingText( + state = PrezelTextFieldState( + interaction = PrezelTextFieldInteraction.TYPED, + feedback = PrezelTextFieldFeedback.Good("헬퍼 메시지"), + ), + ) } } From 5993207c578f62396f1280304dc7b88c3b7fa623 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Wed, 25 Mar 2026 04:51:37 +0900 Subject: [PATCH 30/42] =?UTF-8?q?fix:=20ButtonAreaScope=20=EB=82=B4=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EC=B5=9C=EB=8C=80=20=EA=B0=9C=EC=88=98=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/designsystem/component/actions/area/ButtonAreaScope.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/ButtonAreaScope.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/ButtonAreaScope.kt index ab4b9fa..0a1bfd4 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/ButtonAreaScope.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/ButtonAreaScope.kt @@ -111,6 +111,6 @@ internal class DefaultButtonAreaScope : ButtonAreaScope { } private fun validateButtonCount() { - require(buttons.size <= 2) { "버튼은 최대 2개까지 선언할 수 있습니다." } + require(buttons.size < 2) { "버튼은 최대 2개까지 선언할 수 있습니다." } } } From 38d0e025ef3b588fbf4d0249285a668d1e230c0a Mon Sep 17 00:00:00 2001 From: moondev03 Date: Wed, 25 Mar 2026 04:58:10 +0900 Subject: [PATCH 31/42] =?UTF-8?q?refactor:=20PrezelButtonArea=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=EC=B6=94=EC=B6=9C=20=EB=A1=9C=EC=A7=81=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0=20=EB=B0=8F=20=EC=98=88=EC=99=B8=20=EC=B2=98=EB=A6=AC?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../component/actions/area/PrezelButtonArea.kt | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonArea.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonArea.kt index 11c0a28..a76a2e2 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonArea.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonArea.kt @@ -49,6 +49,11 @@ fun PrezelButtonArea( val scope = remember { DefaultButtonAreaScope() } scope.content() + val mainButton = requireNotNull(scope.buttons.firstOrNull()) { + "PrezelButtonArea에는 최소 1개의 버튼이 필요합니다." + } + val subButton = scope.buttons.getOrNull(1) + Column( modifier = modifier .fillMaxWidth() @@ -58,15 +63,15 @@ fun PrezelButtonArea( if (isVertical) { ButtonAreaVertical( - mainButton = scope.buttons[0], - subButton = scope.buttons.getOrNull(1), + mainButton = mainButton, + subButton = subButton, modifier = Modifier.padding(config.contentPadding), ) } else { ButtonAreaHorizontal( isStrongStrength = isStrongStrength, - mainButton = scope.buttons[0], - subButton = scope.buttons.getOrNull(1), + mainButton = mainButton, + subButton = subButton, modifier = Modifier.padding(config.contentPadding), ) } From 7117c364ac6431d5dacb5626fc2e67611c537539 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Wed, 25 Mar 2026 04:59:02 +0900 Subject: [PATCH 32/42] =?UTF-8?q?refactor:=20PrezelFloatingMenu=20?= =?UTF-8?q?=EB=82=B4=EB=B6=80=20=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20?= =?UTF-8?q?=EA=B5=AC=EC=A1=B0=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `PrezelFloatingMenu` 컴포넌트 내의 간격 조정 로직을 수정하여 시각적 일관성을 개선했습니다. --- .../component/actions/button/floating/PrezelFloatingMenu.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingMenu.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingMenu.kt index 23faa9f..aad175e 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingMenu.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingMenu.kt @@ -53,10 +53,9 @@ fun PrezelFloatingMenu( }, content = items, ) + Spacer(modifier = Modifier.height(PrezelTheme.spacing.V16)) } - Spacer(modifier = Modifier.height(PrezelTheme.spacing.V16)) - PrezelFloatingButton( isExpanded = isExpanded, onChangeExpanded = onChangeExpanded, From 747f0b3f6b61233f27d7a770f234cd0d84d53556 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Wed, 25 Mar 2026 05:00:36 +0900 Subject: [PATCH 33/42] =?UTF-8?q?refactor:=20PrezelFloatingMenu=20?= =?UTF-8?q?=EC=82=AC=EC=9D=B4=EC=A6=88=20=EB=A7=A4=ED=95=91=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../component/actions/button/floating/PrezelFloatingMenu.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingMenu.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingMenu.kt index aad175e..1bcc506 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingMenu.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/floating/PrezelFloatingMenu.kt @@ -47,9 +47,10 @@ fun PrezelFloatingMenu( if (isExpanded) { PrezelMenu( size = when (size) { - ButtonSize.SMALL -> MenuSize.SMALL ButtonSize.REGULAR -> MenuSize.REGULAR - else -> MenuSize.REGULAR + ButtonSize.SMALL, + ButtonSize.XSMALL, + -> MenuSize.SMALL }, content = items, ) From e6e2ab6447cfc565b8d5a2e39d8e76447667790a Mon Sep 17 00:00:00 2001 From: moondev03 Date: Wed, 25 Mar 2026 05:01:37 +0900 Subject: [PATCH 34/42] =?UTF-8?q?style:=20PrezelAvatar=20=EB=AF=B8?= =?UTF-8?q?=EB=A6=AC=EB=B3=B4=EA=B8=B0=EC=9D=98=20contentDescription=20?= =?UTF-8?q?=EB=A6=AC=EC=86=8C=EC=8A=A4=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/team/prezel/core/designsystem/component/PrezelAvatar.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelAvatar.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelAvatar.kt index 5671b6f..7a95d13 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelAvatar.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelAvatar.kt @@ -150,7 +150,7 @@ private fun PrezelAvatarPreview() { ) { PrezelAvatar( imageUrl = "https://picsum.photos/200", - contentDescription = "Image Type", + contentDescription = "이미지", size = PrezelAvatarSize.SMALL, ) } From 706de2aeca5a34e27b57dd775db9a76453293f59 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Wed, 25 Mar 2026 05:02:35 +0900 Subject: [PATCH 35/42] =?UTF-8?q?style:=20BasicPreview=20=EB=B0=B0?= =?UTF-8?q?=EA=B2=BD=EC=83=89=20=EB=A6=AC=EC=86=8C=EC=8A=A4=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `BasicPreview` 어노테이션의 `backgroundColor` 값을 올바른 8자리 16진수 색상 코드(`0xFFFFFFFF`)로 수정하였습니다. --- .../com/team/prezel/core/designsystem/preview/BasicPreview.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/BasicPreview.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/BasicPreview.kt index 8c47826..b1ca96e 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/BasicPreview.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/BasicPreview.kt @@ -5,7 +5,7 @@ import androidx.compose.ui.tooling.preview.Preview @Preview( showBackground = true, - backgroundColor = 0xFFFFFF, + backgroundColor = 0xFFFFFFFF, uiMode = Configuration.UI_MODE_NIGHT_NO, ) annotation class BasicPreview From 0b520302bf51f3a1be18b1a174062415ed41b3ef Mon Sep 17 00:00:00 2001 From: moondev03 Date: Wed, 25 Mar 2026 05:09:19 +0900 Subject: [PATCH 36/42] =?UTF-8?q?refactor:=20=EB=94=94=EC=9E=90=EC=9D=B8?= =?UTF-8?q?=20=EC=8B=9C=EC=8A=A4=ED=85=9C=20=ED=94=84=EB=A6=AC=EB=B7=B0=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B5=AC=EC=A1=B0=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0=20=EB=B0=8F=20TopAppBar=20=EC=BD=94=EB=93=9C?= =?UTF-8?q?=20=EC=A0=95=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/designsystem/component/TopAppBar.kt | 87 +++++++++---------- .../designsystem/preview/PreviewComponent.kt | 12 +-- 2 files changed, 46 insertions(+), 53 deletions(-) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/TopAppBar.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/TopAppBar.kt index 402dda4..e8309fd 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/TopAppBar.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/TopAppBar.kt @@ -17,7 +17,6 @@ import androidx.compose.ui.res.painterResource import com.team.prezel.core.designsystem.icon.PrezelIcons import com.team.prezel.core.designsystem.preview.BasicPreview import com.team.prezel.core.designsystem.preview.PreviewSection -import com.team.prezel.core.designsystem.preview.PreviewSurface import com.team.prezel.core.designsystem.theme.PrezelTheme @OptIn(ExperimentalMaterial3Api::class) @@ -58,10 +57,8 @@ private fun prezelTopAppBarColors() = @BasicPreview @Composable private fun PrezelTopAppBarTitleOnlyPreview() { - PreviewSurface { - PreviewSection(title = "Title Only") { - PrezelTopAppBar(title = { Text(text = "제목") }) - } + PreviewSection(title = "Title Only") { + PrezelTopAppBar(title = { Text(text = "제목") }) } } @@ -69,20 +66,18 @@ private fun PrezelTopAppBarTitleOnlyPreview() { @BasicPreview @Composable private fun PrezelTopAppBarWithLeadingPreview() { - PreviewSurface { - PreviewSection(title = "With Leading") { - PrezelTopAppBar( - title = { Text(text = "제목") }, - leadingIcon = { - IconButton(onClick = {}) { - Icon( - painter = painterResource(PrezelIcons.Blank), - contentDescription = "뒤로가기", - ) - } - }, - ) - } + PreviewSection(title = "With Leading") { + PrezelTopAppBar( + title = { Text(text = "제목") }, + leadingIcon = { + IconButton(onClick = {}) { + Icon( + painter = painterResource(PrezelIcons.Blank), + contentDescription = "뒤로가기", + ) + } + }, + ) } } @@ -90,33 +85,31 @@ private fun PrezelTopAppBarWithLeadingPreview() { @BasicPreview @Composable private fun PrezelTopAppBarWithAllIconsPreview() { - PreviewSurface { - PreviewSection(title = "With All Icons") { - PrezelTopAppBar( - title = { Text(text = "Title") }, - leadingIcon = { - IconButton(onClick = {}) { - Icon( - painter = painterResource(PrezelIcons.Blank), - contentDescription = "뒤로가기", - ) - } - }, - trailingIcons = { - IconButton(onClick = {}) { - Icon( - painter = painterResource(PrezelIcons.Blank), - contentDescription = "검색", - ) - } - IconButton(onClick = {}) { - Icon( - painter = painterResource(PrezelIcons.Blank), - contentDescription = "메뉴", - ) - } - }, - ) - } + PreviewSection(title = "With All Icons") { + PrezelTopAppBar( + title = { Text(text = "Title") }, + leadingIcon = { + IconButton(onClick = {}) { + Icon( + painter = painterResource(PrezelIcons.Blank), + contentDescription = "뒤로가기", + ) + } + }, + trailingIcons = { + IconButton(onClick = {}) { + Icon( + painter = painterResource(PrezelIcons.Blank), + contentDescription = "검색", + ) + } + IconButton(onClick = {}) { + Icon( + painter = painterResource(PrezelIcons.Blank), + contentDescription = "메뉴", + ) + } + }, + ) } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/PreviewComponent.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/PreviewComponent.kt index ae238d6..f0bf4f7 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/PreviewComponent.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/PreviewComponent.kt @@ -127,11 +127,11 @@ internal fun PreviewSection( description: String? = null, content: @Composable ColumnScope.() -> Unit, ) { - PreviewSurface { - Column( - modifier = modifier.fillMaxWidth(), - verticalArrangement = Arrangement.spacedBy(defaults.itemSpacing), - ) { + PreviewSurface( + modifier = modifier.fillMaxWidth(), + defaults = defaults, + ) { + Column(verticalArrangement = Arrangement.spacedBy(defaults.itemSpacing)) { Text( text = title, style = PrezelTheme.typography.title2Medium, @@ -187,7 +187,7 @@ internal fun PreviewValueRow( ) } } - Box(contentAlignment = Alignment.CenterEnd) { + Box(modifier = Modifier.weight(1f), contentAlignment = Alignment.CenterEnd) { preview() } } From 1b32b77ec20bd0c9a8d584dd7c8c1019cf9df116 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Wed, 25 Mar 2026 05:15:19 +0900 Subject: [PATCH 37/42] =?UTF-8?q?refactor:=20PrezelHyperlinkButton?= =?UTF-8?q?=EC=9D=98=20enabled=20=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0=20=EB=B0=8F=20=EA=B3=A0=EC=A0=95=EA=B0=92=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../component/actions/button/PrezelHyperlinkButton.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelHyperlinkButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelHyperlinkButton.kt index 2320ca9..f3ee475 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelHyperlinkButton.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/PrezelHyperlinkButton.kt @@ -25,7 +25,6 @@ fun PrezelHyperlinkButton( text: String, onClick: () -> Unit, modifier: Modifier = Modifier, - enabled: Boolean = true, size: ButtonSize = ButtonSize.XSMALL, config: PrezelButtonDefault = PrezelButtonDefaults.getDefault( isIconOnly = false, @@ -38,8 +37,8 @@ fun PrezelHyperlinkButton( PrezelButtonBase( text = text, iconResId = null, + enabled = true, onClick = onClick, - enabled = enabled, modifier = modifier, layoutModifier = Modifier.prezelButtonUnderline(), config = config, From 4f89ca8c4a9a8c250eb8ccba9bef42c4db8e2f66 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Wed, 25 Mar 2026 05:20:44 +0900 Subject: [PATCH 38/42] =?UTF-8?q?refactor:=20PrezelButtonBase=20=EB=82=B4?= =?UTF-8?q?=EB=B6=80=20=ED=85=8D=EC=8A=A4=ED=8A=B8=20=EB=A0=8C=EB=8D=94?= =?UTF-8?q?=EB=A7=81=20=EA=B5=AC=EC=A1=B0=20=EB=8B=A8=EC=88=9C=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `PrezelButtonBase` 컴포넌트 내에서 불필요한 레이아웃 중첩을 제거하여 구조를 최적화했습니다. --- .../actions/button/config/PrezelButtonBase.kt | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonBase.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonBase.kt index a352d05..1fc2ab9 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonBase.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/button/config/PrezelButtonBase.kt @@ -8,7 +8,6 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -87,15 +86,7 @@ private fun ButtonContentLayout( verticalAlignment = Alignment.CenterVertically, ) { leadingIcon?.invoke() - - text?.let { - Box( - modifier = Modifier.wrapContentHeight(), - contentAlignment = Alignment.Center, - ) { - text() - } - } + text?.invoke() } } } From 8808ec7500ee0a1e47b93531cfbc5061dcc69625 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Thu, 26 Mar 2026 20:03:35 +0900 Subject: [PATCH 39/42] =?UTF-8?q?refactor:=20ButtonAreaScope=20=EB=82=B4?= =?UTF-8?q?=20=EB=B2=84=ED=8A=BC=20=EA=B0=9C=EC=88=98=20=EA=B2=80=EC=A6=9D?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `ButtonAreaScope` 클래스의 `validateButtonCount` 함수에서 버튼 개수를 확인할 때, 외부 노출용 리스트(`buttons`) 대신 내부 가변 리스트(`_buttons`)를 참조하도록 수정하였습니다. --- .../core/designsystem/component/actions/area/ButtonAreaScope.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/ButtonAreaScope.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/ButtonAreaScope.kt index 0a1bfd4..2774b13 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/ButtonAreaScope.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/ButtonAreaScope.kt @@ -111,6 +111,6 @@ internal class DefaultButtonAreaScope : ButtonAreaScope { } private fun validateButtonCount() { - require(buttons.size < 2) { "버튼은 최대 2개까지 선언할 수 있습니다." } + require(_buttons.size < 2) { "버튼은 최대 2개까지 선언할 수 있습니다." } } } From 74644b72384d824303d6136dc2ca6179d3baa687 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Thu, 26 Mar 2026 20:29:24 +0900 Subject: [PATCH 40/42] =?UTF-8?q?refactor:=20PrezelButtonArea=20=EC=8A=A4?= =?UTF-8?q?=ED=83=80=EC=9D=BC=20=EC=A0=81=EC=9A=A9=20=EB=B0=8F=20=EB=A0=8C?= =?UTF-8?q?=EB=8D=94=EB=A7=81=20=EB=A1=9C=EC=A7=81=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../component/actions/area/PrezelButtonArea.kt | 16 ++++++++-------- .../actions/area/PrezelButtonAreaDefaults.kt | 16 +++++++--------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonArea.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonArea.kt index a76a2e2..cb39893 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonArea.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonArea.kt @@ -40,10 +40,7 @@ fun PrezelButtonArea( isStrongStrength: Boolean = true, showBackground: Boolean = false, isNested: Boolean = false, - config: PrezelButtonAreaDefault = PrezelButtonAreaDefaults.getDefault( - showBackground = showBackground, - isNested = isNested, - ), + config: PrezelButtonAreaDefault = PrezelButtonAreaDefaults.getDefault(), content: @Composable ButtonAreaScope.() -> Unit, ) { val scope = remember { DefaultButtonAreaScope() } @@ -53,26 +50,29 @@ fun PrezelButtonArea( "PrezelButtonArea에는 최소 1개의 버튼이 필요합니다." } val subButton = scope.buttons.getOrNull(1) + val contentModifier = if (isNested) Modifier else Modifier.padding(config.contentPadding) Column( modifier = modifier .fillMaxWidth() - .background(config.backgroundColor), + .then(if (showBackground) Modifier.background(config.backgroundColor) else Modifier), ) { - PrezelHorizontalDivider(type = PrezelDividerType.THICK, color = config.borderColor) + if (showBackground) { + PrezelHorizontalDivider(type = PrezelDividerType.THICK, color = config.borderColor) + } if (isVertical) { ButtonAreaVertical( mainButton = mainButton, subButton = subButton, - modifier = Modifier.padding(config.contentPadding), + modifier = contentModifier, ) } else { ButtonAreaHorizontal( isStrongStrength = isStrongStrength, mainButton = mainButton, subButton = subButton, - modifier = Modifier.padding(config.contentPadding), + modifier = contentModifier, ) } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonAreaDefaults.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonAreaDefaults.kt index e6f9c9e..42fa6a9 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonAreaDefaults.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/actions/area/PrezelButtonAreaDefaults.kt @@ -21,15 +21,13 @@ data class PrezelButtonAreaDefault( */ object PrezelButtonAreaDefaults { /** - * 배경 노출 여부와 중첩 여부에 맞는 기본 스타일을 반환합니다. + * 버튼 영역에 사용할 기본 스타일을 반환합니다. */ @Composable fun getDefault( - showBackground: Boolean = false, - isNested: Boolean = false, - backgroundColor: Color = getBackgroundColor(showBackground = showBackground), - borderColor: Color = getBorderColor(showBackground = showBackground), - contentPadding: PaddingValues = getContentPadding(isNested = isNested), + backgroundColor: Color = getBackgroundColor(), + borderColor: Color = getBorderColor(), + contentPadding: PaddingValues = getContentPadding(), ): PrezelButtonAreaDefault = PrezelButtonAreaDefault( backgroundColor = backgroundColor, @@ -38,11 +36,11 @@ object PrezelButtonAreaDefaults { ) @Composable - private fun getBackgroundColor(showBackground: Boolean): Color = if (showBackground) PrezelTheme.colors.bgRegular else Color.Transparent + private fun getBackgroundColor(): Color = PrezelTheme.colors.bgRegular @Composable - private fun getBorderColor(showBackground: Boolean): Color = if (showBackground) PrezelTheme.colors.borderRegular else Color.Transparent + private fun getBorderColor(): Color = PrezelTheme.colors.borderRegular @Composable - private fun getContentPadding(isNested: Boolean): PaddingValues = PaddingValues(if (isNested) PrezelTheme.spacing.V0 else PrezelTheme.spacing.V20) + private fun getContentPadding(): PaddingValues = PaddingValues(PrezelTheme.spacing.V20) } From 079d6f0143b426c2633b832cb768ae40ffa91b44 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Thu, 26 Mar 2026 20:33:12 +0900 Subject: [PATCH 41/42] =?UTF-8?q?refactor:=20=EB=94=94=EC=9E=90=EC=9D=B8?= =?UTF-8?q?=20=EC=8B=9C=EC=8A=A4=ED=85=9C=20Preview=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20?= =?UTF-8?q?=EB=B0=8F=20Divider=20=EB=AF=B8=EB=A6=AC=EB=B3=B4=EA=B8=B0=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/designsystem/component/PrezelDivider.kt | 10 ++++++++-- .../core/designsystem/preview/PreviewComponent.kt | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelDivider.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelDivider.kt index da25a4b..6085337 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelDivider.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelDivider.kt @@ -1,6 +1,8 @@ package com.team.prezel.core.designsystem.component +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.width import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.VerticalDivider import androidx.compose.runtime.Composable @@ -65,10 +67,14 @@ private fun PrezelHorizontalDividerPreview() { description = "Divider는 두 요소 사이를 구분합니다.", ) { PreviewValueRow(name = "DEFAULT") { - PrezelHorizontalDivider(type = PrezelDividerType.DEFAULT) + Box(Modifier.width(100.dp)) { + PrezelHorizontalDivider(type = PrezelDividerType.DEFAULT) + } } PreviewValueRow(name = "THICK") { - PrezelHorizontalDivider(type = PrezelDividerType.THICK) + Box(Modifier.width(100.dp)) { + PrezelHorizontalDivider(type = PrezelDividerType.THICK) + } } } } diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/PreviewComponent.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/PreviewComponent.kt index f0bf4f7..1daa9b3 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/PreviewComponent.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/PreviewComponent.kt @@ -187,7 +187,7 @@ internal fun PreviewValueRow( ) } } - Box(modifier = Modifier.weight(1f), contentAlignment = Alignment.CenterEnd) { + Box(modifier = Modifier, contentAlignment = Alignment.CenterEnd) { preview() } } From 3dab6849c3344a3b73bdbef4a4b9f77411f001f2 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Thu, 26 Mar 2026 20:38:30 +0900 Subject: [PATCH 42/42] =?UTF-8?q?refactor:=20PreviewValueRow=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=9C=A0=EC=97=B0=EC=84=B1=20?= =?UTF-8?q?=EB=B0=8F=20=EC=9D=BC=EA=B4=80=EC=84=B1=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `PreviewValueRow` 컴포넌트에서 하드코딩된 간격 값을 제거하고 공통 설정을 적용할 수 있도록 개선하였습니다. * `defaults` 파라미터를 추가하여 `PreviewDefaults`를 통해 레이아웃 설정을 주입받을 수 있도록 수정 * `horizontalArrangement`의 하드코딩된 간격(`12.dp`)을 `defaults.itemSpacing` 토큰으로 교체 --- .../team/prezel/core/designsystem/preview/PreviewComponent.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/PreviewComponent.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/PreviewComponent.kt index 1daa9b3..9c5cb15 100644 --- a/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/PreviewComponent.kt +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/preview/PreviewComponent.kt @@ -163,12 +163,13 @@ internal fun PreviewSection( internal fun PreviewValueRow( name: String, modifier: Modifier = Modifier, + defaults: PreviewDefaults = PreviewDefaults(), valueLabel: String? = null, preview: @Composable () -> Unit, ) { Row( modifier = modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.spacedBy(12.dp), + horizontalArrangement = Arrangement.spacedBy(defaults.itemSpacing), verticalAlignment = Alignment.CenterVertically, ) { Row(modifier = Modifier.weight(1f)) {