From f5f558b9176ad8cc1a35ac886e7391b3ce8c3b67 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Sat, 24 Jan 2026 02:47:01 +0900 Subject: [PATCH 01/18] =?UTF-8?q?feat:=20=EA=B7=B8=EB=A6=BC=EC=9E=90=20?= =?UTF-8?q?=ED=9A=A8=EA=B3=BC=EB=A5=BC=20=EC=9C=84=ED=95=9C=20`dropShadowC?= =?UTF-8?q?ache`=20Modifier=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 그림자 렌더링 성능을 최적화하기 위해 `drawWithCache`를 사용하는 `dropShadowCache` Modifier 확장 함수를 추가했습니다. 이 함수는 그림자 관련 Paint 및 Path 객체를 캐시하여 리컴포지션 시 불필요한 재생성을 방지합니다. * **기능**: `dropShadowCache` Modifier를 추가하여 Composable에 그림자 효과를 적용할 수 있도록 함 * **파라미터**: 색상(`color`), 오프셋(`offsetX`, `offsetY`), 블러 반경(`blurRadius`), 모양(`shape`), 블러 스타일(`blurStyle`) 설정 기능 제공 * **최적화**: `drawWithCache`를 활용하여 그림자 렌더링 성능 개선 --- .../core/designsystem/util/DropShadowCache.kt | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create 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 new file mode 100644 index 0000000..dd5a61f --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/util/DropShadowCache.kt @@ -0,0 +1,46 @@ +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 9a34d13e0ef6fb96b175bf9351ce547ad46d43b8 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Sat, 24 Jan 2026 02:47:44 +0900 Subject: [PATCH 02/18] =?UTF-8?q?feat:=20FloatingActionButton=20=EC=8A=A4?= =?UTF-8?q?=ED=83=80=EC=9D=BC=20=EC=A0=95=EC=9D=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 디자인 시스템에 사용될 `PrezelFloatingActionButton`의 스타일 속성을 정의했습니다. * **스타일 계층(Hierarchy)**: `PRIMARY`, `SECONDARY` 두 종류의 계층을 `PrezelFloatingButtonHierarchy` 열거형으로 정의 * **크기(Size)**: `SMALL`(36dp), `REGULAR`(48dp) 두 가지 크기를 `PrezelFloatingButtonSize` 열거형으로 정의 * **색상**: 계층에 따라 `containerColor`와 `contentColor`를 반환하는 `@Composable` 함수 추가 * **그림자**: `dropShadowCache`를 사용하여 공통 그림자 스타일(`applyPrezelFloatingButtonShadow`) 적용 * **아이콘 크기**: 버튼 크기에 따라 아이콘 크기(16dp, 20dp)를 결정하는 `prezelFloatingButtonIconSize` 함수 추가 --- .../floating/PrezelFloatingButtonStyle.kt | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/floating/PrezelFloatingButtonStyle.kt 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 new file mode 100644 index 0000000..8c5eccf --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/floating/PrezelFloatingButtonStyle.kt @@ -0,0 +1,68 @@ +package com.team.prezel.core.designsystem.component.button.floating + +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.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.iconLarge + } + +@Composable +internal fun prezelFloatingButtonContainerColor( + hierarchy: PrezelFloatingButtonHierarchy, + colors: PrezelColors = PrezelTheme.colors, +): Color = + when (hierarchy) { + PrezelFloatingButtonHierarchy.PRIMARY -> colors.interactiveRegular + PrezelFloatingButtonHierarchy.SECONDARY -> colors.bgLarge + } From b2390aae8d63e200a7dfff4cd04d4afcb526be0f Mon Sep 17 00:00:00 2001 From: moondev03 Date: Sat, 24 Jan 2026 02:47:52 +0900 Subject: [PATCH 03/18] =?UTF-8?q?feat:=20FloatingActionButton=20=EC=8A=A4?= =?UTF-8?q?=ED=83=80=EC=9D=BC=20=EC=A0=95=EC=9D=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 디자인 시스템에 사용될 `PrezelFloatingActionButton`의 스타일 속성을 정의했습니다. * **스타일 계층(Hierarchy)**: `PRIMARY`, `SECONDARY` 두 종류의 계층을 `PrezelFloatingButtonHierarchy` 열거형으로 정의 * **크기(Size)**: `SMALL`(36dp), `REGULAR`(48dp) 두 가지 크기를 `PrezelFloatingButtonSize` 열거형으로 정의 * **색상**: 계층에 따라 `containerColor`와 `contentColor`를 반환하는 `@Composable` 함수 추가 * **그림자**: `dropShadowCache`를 사용하여 공통 그림자 스타일(`applyPrezelFloatingButtonShadow`) 적용 * **아이콘 크기**: 버튼 크기에 따라 아이콘 크기(16dp, 20dp)를 결정하는 `prezelFloatingButtonIconSize` 함수 추가 --- .../button/floating/PrezelFloatingButton.kt | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/floating/PrezelFloatingButton.kt 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 new file mode 100644 index 0000000..a2ddea0 --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/floating/PrezelFloatingButton.kt @@ -0,0 +1,80 @@ +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.DrawableIcon +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 = DrawableIcon(resId = PrezelIcons.Blank), + style = PrezelFloatingButtonStyle(hierarchy = PrezelFloatingButtonHierarchy.PRIMARY, size = PrezelFloatingButtonSize.REGULAR), + onClick = {}, + ) + + PrezelFloatingButton( + iconSource = DrawableIcon(resId = PrezelIcons.Blank), + style = PrezelFloatingButtonStyle(hierarchy = PrezelFloatingButtonHierarchy.PRIMARY, size = PrezelFloatingButtonSize.SMALL), + onClick = {}, + ) + + PrezelFloatingButton( + iconSource = DrawableIcon(resId = PrezelIcons.Blank), + style = PrezelFloatingButtonStyle(hierarchy = PrezelFloatingButtonHierarchy.SECONDARY, size = PrezelFloatingButtonSize.REGULAR), + onClick = {}, + ) + + PrezelFloatingButton( + iconSource = DrawableIcon(resId = PrezelIcons.Blank), + style = PrezelFloatingButtonStyle(hierarchy = PrezelFloatingButtonHierarchy.SECONDARY, size = PrezelFloatingButtonSize.SMALL), + onClick = {}, + ) + } + } +} From 655f237b1192c86ed1cae80e1caa1e4cfed14781 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Sat, 24 Jan 2026 03:14:48 +0900 Subject: [PATCH 04/18] =?UTF-8?q?feat:=20FloatingActionButton=20=EC=8A=A4?= =?UTF-8?q?=ED=83=80=EC=9D=BC=20=EC=A0=95=EC=9D=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 디자인 시스템에 사용될 `PrezelFloatingActionButton`의 스타일 속성을 정의했습니다. * **스타일 계층(Hierarchy)**: `PRIMARY`, `SECONDARY` 두 종류의 계층을 `PrezelFloatingButtonHierarchy` 열거형으로 정의 * **크기(Size)**: `SMALL`(36dp), `REGULAR`(48dp) 두 가지 크기를 `PrezelFloatingButtonSize` 열거형으로 정의 * **색상**: 계층에 따라 `containerColor`와 `contentColor`를 반환하는 `@Composable` 함수 추가 * **그림자**: `dropShadowCache`를 사용하여 공통 그림자 스타일(`applyPrezelFloatingButtonShadow`) 적용 * **아이콘 크기**: 버튼 크기에 따라 아이콘 크기(16dp, 20dp)를 결정하는 `prezelFloatingButtonIconSize` 함수 추가 --- .../component/button/floating/PrezelFloatingButtonStyle.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index 8c5eccf..264cb79 100644 --- 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 @@ -54,7 +54,7 @@ internal fun prezelFloatingButtonContentColor( ): Color = when (hierarchy) { PrezelFloatingButtonHierarchy.PRIMARY -> colors.solidWhite - PrezelFloatingButtonHierarchy.SECONDARY -> colors.iconLarge + PrezelFloatingButtonHierarchy.SECONDARY -> colors.iconRegular } @Composable From faafd41c254716f20eb05b1b0dd5ed7a187d3a9e Mon Sep 17 00:00:00 2001 From: moondev03 Date: Sat, 24 Jan 2026 03:15:09 +0900 Subject: [PATCH 05/18] =?UTF-8?q?feat:=20=ED=94=8C=EB=A1=9C=ED=8C=85=20?= =?UTF-8?q?=EB=A9=94=EB=89=B4=20=EB=B2=84=ED=8A=BC=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=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 확장 가능한 메뉴를 포함하는 `PrezelFloatingMenuButton` 컴포저블을 추가했습니다. 이 버튼은 클릭 시 하위 메뉴 항목들을 표시하거나 숨길 수 있습니다. * **주요 기능**: * `isExpanded` 상태에 따라 주 버튼의 아이콘이 기본 아이콘에서 `Cancel` 아이콘으로 전환됩니다. * 확장 메뉴(`content`)는 `AnimatedVisibility`를 사용하여 페이드 인/아웃 효과와 함께 나타납니다. * 메뉴 컨테이너는 흰색 배경과 둥근 모서리(`V12`) 스타일이 적용됩니다. * **구성 요소**: * `PrezelFloatingMenuButton`: 메인 플로팅 버튼과 확장 메뉴를 포함하는 최상위 컴포저블입니다. * `PrezelMainFloatingButton`: 상태에 따라 아이콘이 변경되는 주 버튼입니다. * `PrezelFloatingButtonMenu`: 애니메이션 효과가 적용된 메뉴 컨테이너입니다. * **미리보기**: `Primary` 및 `Secondary` 계층과 `Regular`, `Small` 크기 조합에 대한 확장/축소 상태별 미리보기를 추가했습니다. --- .../floating/PrezelFloatingMenuButton.kt | 186 ++++++++++++++++++ 1 file changed, 186 insertions(+) create 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/floating/PrezelFloatingMenuButton.kt b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/floating/PrezelFloatingMenuButton.kt new file mode 100644 index 0000000..e5f38e5 --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/floating/PrezelFloatingMenuButton.kt @@ -0,0 +1,186 @@ +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.Row +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.requiredHeightIn +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.foundation.layout.wrapContentSize +import androidx.compose.material3.LocalContentColor +import androidx.compose.material3.LocalTextStyle +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import com.team.prezel.core.designsystem.icon.DrawableIcon +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 PrezelTheme.colors.textMedium, + LocalTextStyle provides PrezelTheme.typography.body2Regular, + ) { + Column( + modifier = modifier, + horizontalAlignment = Alignment.End, + verticalArrangement = Arrangement.spacedBy(PrezelTheme.spacing.V16), + ) { + PrezelFloatingButtonMenu( + isExpanded = isExpanded, + 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) DrawableIcon(resId = PrezelIcons.Cancel, contentDescription = "플로팅 버튼 닫기") else iconSource + + PrezelFloatingButton( + iconSource = currentIconSource, + onClick = onClick, + modifier = modifier, + style = style, + ) +} + +@Composable +private fun PrezelFloatingButtonMenu( + isExpanded: Boolean, + modifier: Modifier = Modifier, + content: @Composable ColumnScope.() -> Unit, +) { + AnimatedVisibility( + visible = isExpanded, + enter = fadeIn(), + exit = fadeOut(), + ) { + Column( + modifier = modifier + .wrapContentSize() + .background( + shape = PrezelTheme.shapes.V12, + color = PrezelTheme.colors.solidWhite, + ).padding(PrezelTheme.spacing.V4), + horizontalAlignment = Alignment.Start, + verticalArrangement = Arrangement.spacedBy(PrezelTheme.spacing.V4), + content = content, + ) + } +} + +@ThemePreview +@Composable +private fun PrimaryPrezelFloatingMenuButtonPreview() { + PrezelTheme { + Row( + modifier = Modifier + .wrapContentHeight() + .requiredHeightIn(200.dp) + .background(PrezelTheme.colors.bgRegular) + .padding(12.dp), + verticalAlignment = Alignment.Bottom, + horizontalArrangement = Arrangement.spacedBy(12.dp), + ) { + PreviewFloatingMenuButton( + isExpanded = false, + style = PrezelFloatingButtonStyle(hierarchy = PrezelFloatingButtonHierarchy.PRIMARY, size = PrezelFloatingButtonSize.REGULAR), + ) + PreviewFloatingMenuButton( + isExpanded = true, + style = PrezelFloatingButtonStyle(hierarchy = PrezelFloatingButtonHierarchy.PRIMARY, size = PrezelFloatingButtonSize.REGULAR), + ) + PreviewFloatingMenuButton( + isExpanded = false, + style = PrezelFloatingButtonStyle(hierarchy = PrezelFloatingButtonHierarchy.PRIMARY, size = PrezelFloatingButtonSize.SMALL), + ) + PreviewFloatingMenuButton( + isExpanded = 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.bgRegular) + .padding(12.dp), + verticalAlignment = Alignment.Bottom, + horizontalArrangement = Arrangement.spacedBy(12.dp), + ) { + PreviewFloatingMenuButton( + isExpanded = false, + style = PrezelFloatingButtonStyle(hierarchy = PrezelFloatingButtonHierarchy.SECONDARY, size = PrezelFloatingButtonSize.REGULAR), + ) + PreviewFloatingMenuButton( + isExpanded = true, + style = PrezelFloatingButtonStyle(hierarchy = PrezelFloatingButtonHierarchy.SECONDARY, size = PrezelFloatingButtonSize.REGULAR), + ) + PreviewFloatingMenuButton( + isExpanded = false, + style = PrezelFloatingButtonStyle(hierarchy = PrezelFloatingButtonHierarchy.SECONDARY, size = PrezelFloatingButtonSize.SMALL), + ) + PreviewFloatingMenuButton( + isExpanded = true, + style = PrezelFloatingButtonStyle(hierarchy = PrezelFloatingButtonHierarchy.SECONDARY, size = PrezelFloatingButtonSize.SMALL), + ) + } + } +} + +@Composable +private fun PreviewFloatingMenuButton( + isExpanded: Boolean, + style: PrezelFloatingButtonStyle, +) { + PrezelFloatingMenuButton( + iconSource = DrawableIcon(resId = PrezelIcons.Blank), + isExpanded = isExpanded, + onClick = {}, + style = style, + ) { + Text(text = "Label") + Text(text = "Label") + Text(text = "Label") + } +} From ff94a47400f85d2540ed66ee5eb55fbc125f413f Mon Sep 17 00:00:00 2001 From: moondev03 Date: Sat, 24 Jan 2026 03:59:09 +0900 Subject: [PATCH 06/18] =?UTF-8?q?feat:=20`PrezelFloatingMenuButton`?= =?UTF-8?q?=EC=9D=98=20=EB=A9=94=EB=89=B4=20=EC=95=84=EC=9D=B4=ED=85=9C=20?= =?UTF-8?q?=EC=BB=B4=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 `PrezelFloatingMenuButton` 내에서 사용될 `PrezelFloatingButtonMenuItem` 컴포넌트를 추가하여, 확장된 메뉴의 각 항목을 일관된 디자인 시스템에 따라 구현할 수 있도록 개선했습니다. * **기능 추가**: `PrezelFloatingButtonMenuItem` 컴포저블 추가 * `label`, `icon`, `onClick` 액션을 설정할 수 있습니다. * `PrezelFloatingButtonMenuItemSize` (`REGULAR`, `SMALL`) enum을 통해 크기(패딩, 아이콘, 텍스트 스타일)를 조절할 수 있습니다. * **리팩토링**: `PrezelFloatingMenuButton`의 컨텐츠 스타일링 방식 변경 * 기존에 `LocalTextStyle`을 제공하던 방식에서 `LocalContentColor`만 제공하도록 수정했습니다. * 메뉴 항목의 텍스트 스타일은 새로운 `PrezelFloatingButtonMenuItem`이 직접 관리합니다. * **기타**: `PrezelFloatingButtonMenuItem`의 다양한 상태(아이콘 유무, 크기)를 확인할 수 있도록 Preview 코드를 추가 및 개선했습니다. --- .../floating/PrezelFloatingButtonMenuItem.kt | 103 ++++++++++++++++++ .../PrezelFloatingButtonMenuItemStyle.kt | 41 +++++++ .../floating/PrezelFloatingMenuButton.kt | 47 ++++++-- 3 files changed, 180 insertions(+), 11 deletions(-) create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/floating/PrezelFloatingButtonMenuItem.kt create mode 100644 Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/floating/PrezelFloatingButtonMenuItemStyle.kt 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 new file mode 100644 index 0000000..81cca73 --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/floating/PrezelFloatingButtonMenuItem.kt @@ -0,0 +1,103 @@ +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.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.DrawableIcon +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, + size: PrezelFloatingButtonMenuItemSize = PrezelFloatingButtonMenuItemSize.REGULAR, +) { + Row( + modifier = modifier + .clip(PrezelTheme.shapes.V4) + .clickable( + indication = ripple(), + interactionSource = null, + onClick = onClick, + ).padding(prezelFloatingButtonMenuItemPaddingValues(size)), + verticalAlignment = Alignment.CenterVertically, + ) { + iconSource?.let { source -> PrezelFloatingButtonMenuItemIcon(iconSource = source, size = size) } + Text(text = label, style = prezelFloatingButtonMenuItemTextStyle(size)) + } +} + +@Composable +private fun PrezelFloatingButtonMenuItemIcon( + iconSource: IconSource, + size: PrezelFloatingButtonMenuItemSize, +) { + Icon( + painter = iconSource.painter(), + contentDescription = iconSource.contentDescription, + modifier = Modifier.size(prezelFloatingButtonMenuItemIconSize(size)), + ) + + when (size) { + PrezelFloatingButtonMenuItemSize.SMALL -> PrezelTheme.spacing.V4 + PrezelFloatingButtonMenuItemSize.REGULAR -> PrezelTheme.spacing.V8 + }.let { spacing -> Spacer(modifier = Modifier.width(spacing)) } +} + +@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 = DrawableIcon(resId = PrezelIcons.Blank), + size = PrezelFloatingButtonMenuItemSize.REGULAR, + ) + + PrezelFloatingButtonMenuItem( + label = "Label", + onClick = {}, + iconSource = DrawableIcon(resId = PrezelIcons.Blank), + size = PrezelFloatingButtonMenuItemSize.SMALL, + ) + PrezelFloatingButtonMenuItem( + label = "Label", + onClick = {}, + size = PrezelFloatingButtonMenuItemSize.REGULAR, + ) + + PrezelFloatingButtonMenuItem( + label = "Label", + onClick = {}, + size = PrezelFloatingButtonMenuItemSize.SMALL, + ) + } + } +} 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 new file mode 100644 index 0000000..1cbf578 --- /dev/null +++ b/Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/floating/PrezelFloatingButtonMenuItemStyle.kt @@ -0,0 +1,41 @@ +package com.team.prezel.core.designsystem.component.button.floating + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.runtime.Composable +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, +} + +@Composable +internal fun prezelFloatingButtonMenuItemTextStyle( + size: PrezelFloatingButtonMenuItemSize, + typography: PrezelTypography = PrezelTheme.typography, +): TextStyle = + when (size) { + PrezelFloatingButtonMenuItemSize.SMALL -> typography.body3Regular + PrezelFloatingButtonMenuItemSize.REGULAR -> typography.body2Regular + } + +@Composable +internal fun prezelFloatingButtonMenuItemPaddingValues( + size: PrezelFloatingButtonMenuItemSize, + 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) } + +internal fun prezelFloatingButtonMenuItemIconSize(size: PrezelFloatingButtonMenuItemSize): Dp = + when (size) { + PrezelFloatingButtonMenuItemSize.SMALL -> 16.dp + PrezelFloatingButtonMenuItemSize.REGULAR -> 20.dp + } 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 index e5f38e5..71342e8 100644 --- 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 @@ -13,8 +13,6 @@ import androidx.compose.foundation.layout.requiredHeightIn import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.material3.LocalContentColor -import androidx.compose.material3.LocalTextStyle -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.ui.Alignment @@ -24,6 +22,7 @@ import com.team.prezel.core.designsystem.icon.DrawableIcon 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 import com.team.prezel.core.designsystem.theme.PrezelTheme @Composable @@ -35,10 +34,7 @@ fun PrezelFloatingMenuButton( style: PrezelFloatingButtonStyle = PrezelFloatingButtonStyle(), content: @Composable (ColumnScope.() -> Unit), ) { - CompositionLocalProvider( - LocalContentColor provides PrezelTheme.colors.textMedium, - LocalTextStyle provides PrezelTheme.typography.body2Regular, - ) { + CompositionLocalProvider(LocalContentColor provides PrezelColorScheme.Light.textMedium) { Column( modifier = modifier, horizontalAlignment = Alignment.End, @@ -110,7 +106,7 @@ private fun PrimaryPrezelFloatingMenuButtonPreview() { modifier = Modifier .wrapContentHeight() .requiredHeightIn(200.dp) - .background(PrezelTheme.colors.bgRegular) + .background(PrezelTheme.colors.bgScrim) .padding(12.dp), verticalAlignment = Alignment.Bottom, horizontalArrangement = Arrangement.spacedBy(12.dp), @@ -143,7 +139,7 @@ private fun SecondaryPrezelFloatingMenuButtonPreview() { modifier = Modifier .wrapContentHeight() .requiredHeightIn(200.dp) - .background(PrezelTheme.colors.bgRegular) + .background(PrezelTheme.colors.bgScrim) .padding(12.dp), verticalAlignment = Alignment.Bottom, horizontalArrangement = Arrangement.spacedBy(12.dp), @@ -179,8 +175,37 @@ private fun PreviewFloatingMenuButton( onClick = {}, style = style, ) { - Text(text = "Label") - Text(text = "Label") - Text(text = "Label") + 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) DrawableIcon(resId = PrezelIcons.Blank) else null + + PrezelFloatingMenuButton( + modifier = Modifier + .background(PrezelTheme.colors.bgScrim) + .padding(16.dp), + iconSource = DrawableIcon(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 c81b55f3897b166909b77abe4dca06aa486833a9 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Sat, 24 Jan 2026 04:04:25 +0900 Subject: [PATCH 07/18] =?UTF-8?q?style:=20detekt=20`MatchingDeclarationNam?= =?UTF-8?q?e`=20=EA=B7=9C=EC=B9=99=20=EB=B9=84=ED=99=9C=EC=84=B1=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit detekt-config.yml 설정 파일에서 `MatchingDeclarationName` 규칙을 비활성화하여, 파일 이름과 클래스/객체 이름이 일치하지 않아도 경고가 발생하지 않도록 수정했습니다. --- Prezel/detekt-config.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Prezel/detekt-config.yml b/Prezel/detekt-config.yml index 3f97a7a..4829866 100644 --- a/Prezel/detekt-config.yml +++ b/Prezel/detekt-config.yml @@ -47,6 +47,8 @@ complexity: naming: active: true + MatchingDeclarationName: + active: false FunctionNaming: active: true ignoreAnnotated: From fb32bb0c4928249d3e516cfa5739af649f4798e2 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Sat, 24 Jan 2026 04:30:17 +0900 Subject: [PATCH 08/18] =?UTF-8?q?feat:=20`PrezelFloatingMenuButton`=20?= =?UTF-8?q?=EC=8A=A4=ED=83=80=EC=9D=BC=20=ED=99=95=EC=9E=A5=20=EB=B0=8F=20?= =?UTF-8?q?=EA=B3=84=EC=B8=B5=20=EA=B5=AC=EC=A1=B0=20=EC=A7=80=EC=9B=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `PrezelFloatingMenuButton` 컴포넌트의 스타일링 유연성을 높이고, `PrezelFloatingButtonStyle`에 정의된 계층(`hierarchy`)과 크기(`size`)에 따라 메뉴 아이템의 스타일이 동적으로 변경되도록 개선했습니다. * **스타일 동기화**: `PrezelFloatingMenuButton`의 `hierarchy`와 `size`가 하위 메뉴(`PrezelFloatingButtonMenu`)와 메뉴 아이템(`PrezelFloatingButtonMenuItem`)에 자동으로 반영되도록 수정했습니다. * `PrezelFloatingMenuButton`의 `hierarchy`에 따라 메뉴 컨테이너의 배경색과 내부 콘텐츠(텍스트/아이콘) 색상이 변경됩니다. * `PrezelFloatingMenuButton`의 `size`에 맞춰 메뉴 컨테이너의 내부 패딩과 메뉴 아이템의 크기가 조정됩니다. * **CompositionLocal 활용**: `LocalPrezelFloatingButtonMenuItemSize`를 추가하여, `PrezelFloatingMenuButton`의 `size`를 하위 컴포넌트인 `PrezelFloatingButtonMenuItem`으로 효율적으로 전달하도록 리팩토링했습니다. 이로 인해 `PrezelFloatingButtonMenuItem`에서 `size` 파라미터가 제거되었습니다. * **스타일 함수 추가**: `hierarchy`와 `size`에 따른 색상 및 패딩 값을 반환하는 `prezelFloatingMenuButtonContainerColor`, `prezelFloatingMenuButtonContentColor`, `prezelFloatingMenuButtonPaddingValues` 함수를 추가했습니다. --- .../floating/PrezelFloatingButtonMenuItem.kt | 20 +++-------- .../PrezelFloatingButtonMenuItemStyle.kt | 9 +++++ .../floating/PrezelFloatingButtonStyle.kt | 33 +++++++++++++++++++ .../floating/PrezelFloatingMenuButton.kt | 20 +++++++---- 4 files changed, 61 insertions(+), 21 deletions(-) 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 index 81cca73..68d04b9 100644 --- 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 @@ -13,6 +13,7 @@ import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.material3.ripple import androidx.compose.runtime.Composable +import androidx.compose.runtime.compositionLocalOf import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -23,14 +24,17 @@ import com.team.prezel.core.designsystem.icon.PrezelIcons import com.team.prezel.core.designsystem.preview.ThemePreview import com.team.prezel.core.designsystem.theme.PrezelTheme +internal val LocalPrezelFloatingButtonMenuItemSize = compositionLocalOf { PrezelFloatingButtonMenuItemSize.REGULAR } + @Composable fun PrezelFloatingButtonMenuItem( label: String, onClick: () -> Unit, modifier: Modifier = Modifier, iconSource: IconSource? = null, - size: PrezelFloatingButtonMenuItemSize = PrezelFloatingButtonMenuItemSize.REGULAR, ) { + val size = LocalPrezelFloatingButtonMenuItemSize.current + Row( modifier = modifier .clip(PrezelTheme.shapes.V4) @@ -78,25 +82,11 @@ private fun PrezelFloatingButtonMenuItemPreview() { label = "Label", onClick = {}, iconSource = DrawableIcon(resId = PrezelIcons.Blank), - size = PrezelFloatingButtonMenuItemSize.REGULAR, - ) - - PrezelFloatingButtonMenuItem( - label = "Label", - onClick = {}, - iconSource = DrawableIcon(resId = PrezelIcons.Blank), - size = PrezelFloatingButtonMenuItemSize.SMALL, - ) - PrezelFloatingButtonMenuItem( - label = "Label", - onClick = {}, - size = PrezelFloatingButtonMenuItemSize.REGULAR, ) PrezelFloatingButtonMenuItem( label = "Label", onClick = {}, - size = PrezelFloatingButtonMenuItemSize.SMALL, ) } } 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 index 1cbf578..afefb55 100644 --- 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 @@ -12,6 +12,15 @@ 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 + } + } } @Composable 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 index 264cb79..d9774d4 100644 --- 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 @@ -1,5 +1,6 @@ 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 @@ -7,6 +8,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.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 @@ -66,3 +69,33 @@ internal fun prezelFloatingButtonContainerColor( 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 index 71342e8..bb1cd8d 100644 --- 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 @@ -22,7 +22,6 @@ import com.team.prezel.core.designsystem.icon.DrawableIcon 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 import com.team.prezel.core.designsystem.theme.PrezelTheme @Composable @@ -34,7 +33,9 @@ fun PrezelFloatingMenuButton( style: PrezelFloatingButtonStyle = PrezelFloatingButtonStyle(), content: @Composable (ColumnScope.() -> Unit), ) { - CompositionLocalProvider(LocalContentColor provides PrezelColorScheme.Light.textMedium) { + CompositionLocalProvider( + LocalContentColor provides prezelFloatingMenuButtonContentColor(style.hierarchy), + ) { Column( modifier = modifier, horizontalAlignment = Alignment.End, @@ -42,6 +43,7 @@ fun PrezelFloatingMenuButton( ) { PrezelFloatingButtonMenu( isExpanded = isExpanded, + style = style, content = content, ) @@ -77,6 +79,7 @@ private fun PrezelMainFloatingButton( private fun PrezelFloatingButtonMenu( isExpanded: Boolean, modifier: Modifier = Modifier, + style: PrezelFloatingButtonStyle, content: @Composable ColumnScope.() -> Unit, ) { AnimatedVisibility( @@ -89,12 +92,17 @@ private fun PrezelFloatingButtonMenu( .wrapContentSize() .background( shape = PrezelTheme.shapes.V12, - color = PrezelTheme.colors.solidWhite, - ).padding(PrezelTheme.spacing.V4), + color = prezelFloatingMenuButtonContainerColor(style.hierarchy), + ).padding(prezelFloatingMenuButtonPaddingValues(style.size)), horizontalAlignment = Alignment.Start, verticalArrangement = Arrangement.spacedBy(PrezelTheme.spacing.V4), - content = content, - ) + ) { + CompositionLocalProvider( + LocalPrezelFloatingButtonMenuItemSize provides PrezelFloatingButtonMenuItemSize.buttonMenuItemSize(style.size), + ) { + content() + } + } } } From d31441f431d318b7e5d56b3512cd457a83bc8f0f Mon Sep 17 00:00:00 2001 From: moondev03 Date: Sat, 24 Jan 2026 04:37:22 +0900 Subject: [PATCH 09/18] =?UTF-8?q?refactor:=20`PrezelFloatingButtonMenuItem?= =?UTF-8?q?`=20=EC=8A=A4=ED=83=80=EC=9D=BC=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0=20=EB=B0=8F=20=EC=9D=98=EC=A1=B4=EC=84=B1=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `PrezelFloatingButtonMenuItem`의 스타일 관련 로직을 별도의 `...Style.kt` 파일로 이동하고, `CompositionLocal`을 활용하여 스타일 속성을 관리하도록 구조를 개선했습니다. * **리팩토링**: * `LocalPrezelFloatingButtonMenuItemSize`를 `...Style.kt` 파일로 이동시켜 컴포넌트의 의존성을 줄였습니다. * `PrezelFloatingButtonMenuItem` 내부에서 사이즈(`size`)를 직접 전달받지 않고, `CompositionLocal`에서 현재 값을 가져와 스타일 함수(`prezelFloatingButtonMenuItem...`)에 적용하도록 변경했습니다. * **기능 추가**: * 아이콘과 텍스트 사이의 간격(`Spacer`)을 스타일 파일 내에서 관리하기 위해 `prezelFloatingButtonMenuItemSpaceDp` 함수를 추가했습니다. * **구조 개선**: * 기존 스타일 관련 함수들이 `size`를 필수로 요구하던 것에서 `LocalPrezelFloatingButtonMenuItemSize.current`를 기본값으로 사용하도록 변경하여 호출을 단순화했습니다. --- .../floating/PrezelFloatingButtonMenuItem.kt | 23 +++++-------------- .../PrezelFloatingButtonMenuItemStyle.kt | 20 +++++++++++++--- 2 files changed, 23 insertions(+), 20 deletions(-) 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 index 68d04b9..9110c7e 100644 --- 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 @@ -13,7 +13,6 @@ import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.material3.ripple import androidx.compose.runtime.Composable -import androidx.compose.runtime.compositionLocalOf import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip @@ -24,8 +23,6 @@ import com.team.prezel.core.designsystem.icon.PrezelIcons import com.team.prezel.core.designsystem.preview.ThemePreview import com.team.prezel.core.designsystem.theme.PrezelTheme -internal val LocalPrezelFloatingButtonMenuItemSize = compositionLocalOf { PrezelFloatingButtonMenuItemSize.REGULAR } - @Composable fun PrezelFloatingButtonMenuItem( label: String, @@ -33,8 +30,6 @@ fun PrezelFloatingButtonMenuItem( modifier: Modifier = Modifier, iconSource: IconSource? = null, ) { - val size = LocalPrezelFloatingButtonMenuItemSize.current - Row( modifier = modifier .clip(PrezelTheme.shapes.V4) @@ -42,29 +37,23 @@ fun PrezelFloatingButtonMenuItem( indication = ripple(), interactionSource = null, onClick = onClick, - ).padding(prezelFloatingButtonMenuItemPaddingValues(size)), + ).padding(prezelFloatingButtonMenuItemPaddingValues()), verticalAlignment = Alignment.CenterVertically, ) { - iconSource?.let { source -> PrezelFloatingButtonMenuItemIcon(iconSource = source, size = size) } - Text(text = label, style = prezelFloatingButtonMenuItemTextStyle(size)) + iconSource?.let { source -> PrezelFloatingButtonMenuItemIcon(iconSource = source) } + Text(text = label, style = prezelFloatingButtonMenuItemTextStyle()) } } @Composable -private fun PrezelFloatingButtonMenuItemIcon( - iconSource: IconSource, - size: PrezelFloatingButtonMenuItemSize, -) { +private fun PrezelFloatingButtonMenuItemIcon(iconSource: IconSource) { Icon( painter = iconSource.painter(), contentDescription = iconSource.contentDescription, - modifier = Modifier.size(prezelFloatingButtonMenuItemIconSize(size)), + modifier = Modifier.size(prezelFloatingButtonMenuItemIconSize()), ) - when (size) { - PrezelFloatingButtonMenuItemSize.SMALL -> PrezelTheme.spacing.V4 - PrezelFloatingButtonMenuItemSize.REGULAR -> PrezelTheme.spacing.V8 - }.let { spacing -> Spacer(modifier = Modifier.width(spacing)) } + Spacer(modifier = Modifier.width(prezelFloatingButtonMenuItemSpaceDp())) } @ThemePreview 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 index afefb55..8371677 100644 --- 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 @@ -2,6 +2,7 @@ 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 @@ -23,9 +24,11 @@ enum class PrezelFloatingButtonMenuItemSize { } } +internal val LocalPrezelFloatingButtonMenuItemSize = compositionLocalOf { PrezelFloatingButtonMenuItemSize.REGULAR } + @Composable internal fun prezelFloatingButtonMenuItemTextStyle( - size: PrezelFloatingButtonMenuItemSize, + size: PrezelFloatingButtonMenuItemSize = LocalPrezelFloatingButtonMenuItemSize.current, typography: PrezelTypography = PrezelTheme.typography, ): TextStyle = when (size) { @@ -35,7 +38,7 @@ internal fun prezelFloatingButtonMenuItemTextStyle( @Composable internal fun prezelFloatingButtonMenuItemPaddingValues( - size: PrezelFloatingButtonMenuItemSize, + size: PrezelFloatingButtonMenuItemSize = LocalPrezelFloatingButtonMenuItemSize.current, spacing: PrezelSpacing = PrezelTheme.spacing, ): PaddingValues = when (size) { @@ -43,8 +46,19 @@ internal fun prezelFloatingButtonMenuItemPaddingValues( PrezelFloatingButtonMenuItemSize.REGULAR -> spacing.V12 to spacing.V8 }.let { (horizontal, vertical) -> PaddingValues(horizontal = horizontal, vertical = vertical) } -internal fun prezelFloatingButtonMenuItemIconSize(size: PrezelFloatingButtonMenuItemSize): Dp = +@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 + } From ec4d560a26a4133d413295fdf051e4e4c27effc2 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Sat, 24 Jan 2026 04:52:07 +0900 Subject: [PATCH 10/18] =?UTF-8?q?refactor:=20`PrezelFloatingMenuButton`=20?= =?UTF-8?q?=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20=EB=84=88=EB=B9=84=20?= =?UTF-8?q?=EB=8F=99=EC=9E=91=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `PrezelFloatingMenuButton` 및 하위 `PrezelFloatingButtonMenuItem`의 너비 계산 방식을 개선하여 일관된 레이아웃을 제공하도록 수정했습니다. * **`PrezelFloatingMenuButton`**: * 기존 `wrapContentSize()`를 `width(IntrinsicSize.Max)`로 변경하여, 메뉴 아이템의 너비가 콘텐츠 길이에 맞춰 자동으로 확장되도록 수정했습니다. 이를 통해 아이템들이 동일한 너비를 갖게 됩니다. * **`PrezelFloatingButtonMenuItem`**: * `fillMaxWidth()`를 적용하여 부모 컴포넌트(`PrezelFloatingMenuButton`)에 의해 결정된 너비를 채우도록 변경했습니다. --- .../button/floating/PrezelFloatingButtonMenuItem.kt | 3 ++- .../component/button/floating/PrezelFloatingMenuButton.kt | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) 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 index 9110c7e..48e682d 100644 --- 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 @@ -6,6 +6,7 @@ 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 @@ -32,7 +33,7 @@ fun PrezelFloatingButtonMenuItem( ) { Row( modifier = modifier - .clip(PrezelTheme.shapes.V4) + .fillMaxWidth() .clickable( indication = ripple(), interactionSource = null, 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 index bb1cd8d..4aac228 100644 --- 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 @@ -7,11 +7,12 @@ 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.foundation.layout.wrapContentSize import androidx.compose.material3.LocalContentColor import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider @@ -89,7 +90,7 @@ private fun PrezelFloatingButtonMenu( ) { Column( modifier = modifier - .wrapContentSize() + .width(IntrinsicSize.Max) .background( shape = PrezelTheme.shapes.V12, color = prezelFloatingMenuButtonContainerColor(style.hierarchy), From 8ef0a62655aeb5001443097944b96467ee9d31ad Mon Sep 17 00:00:00 2001 From: moondev03 Date: Sat, 24 Jan 2026 04:52:38 +0900 Subject: [PATCH 11/18] =?UTF-8?q?fix:=20=ED=94=8C=EB=A1=9C=ED=8C=85=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EB=A9=94=EB=89=B4=20=EC=95=84=EC=9D=B4?= =?UTF-8?q?=ED=85=9C=EC=97=90=20clip=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `PrezelFloatingButtonMenuItem` 컴포넌트의 Row에 `PrezelTheme.shapes.V6`를 사용하여 clip을 적용했습니다. 이를 통해 클릭 시 ripple 효과가 아이템의 둥근 모서리 영역을 벗어나지 않도록 수정했습니다. --- .../component/button/floating/PrezelFloatingButtonMenuItem.kt | 1 + 1 file changed, 1 insertion(+) 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 index 48e682d..dba2d74 100644 --- 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 @@ -34,6 +34,7 @@ fun PrezelFloatingButtonMenuItem( Row( modifier = modifier .fillMaxWidth() + .clip(PrezelTheme.shapes.V6) .clickable( indication = ripple(), interactionSource = null, From 6615ffbf4d5a490786387a6795b2ae24b30dfae7 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Sat, 24 Jan 2026 05:14:06 +0900 Subject: [PATCH 12/18] =?UTF-8?q?feat:=20`PrezelFloatingMenuButton`=20?= =?UTF-8?q?=ED=94=84=EB=A6=AC=EB=B7=B0=20=EB=8F=99=EC=9E=91=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `PrezelFloatingMenuButton`의 Preview에서 버튼을 클릭하면 확장/축소 상태가 실제로 변경되도록 상호작용 기능을 추가했습니다. * `remember`와 `mutableStateOf`를 사용하여 프리뷰 내에서 `isExpanded` 상태를 관리합니다. * `onClick` 람다에서 상태를 토글하도록 수정하여 UI 변경을 바로 확인할 수 있게 개선했습니다. --- .../component/button/floating/PrezelFloatingMenuButton.kt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) 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 index 4aac228..e0b41ef 100644 --- 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 @@ -16,6 +16,10 @@ 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 @@ -178,10 +182,12 @@ private fun PreviewFloatingMenuButton( isExpanded: Boolean, style: PrezelFloatingButtonStyle, ) { + var isExpanded by remember { mutableStateOf(isExpanded) } + PrezelFloatingMenuButton( iconSource = DrawableIcon(resId = PrezelIcons.Blank), isExpanded = isExpanded, - onClick = {}, + onClick = { isExpanded = !isExpanded }, style = style, ) { PrezelFloatingButtonMenuItem(label = "LongLabel", onClick = {}) From 96b280ae96a6d1f723a1ac30f1758596c1e601ff Mon Sep 17 00:00:00 2001 From: moondev03 Date: Sat, 24 Jan 2026 20:22:48 +0900 Subject: [PATCH 13/18] =?UTF-8?q?refactor:=20IconSource=20=EA=B5=AC?= =?UTF-8?q?=EC=A1=B0=20=EA=B0=9C=EC=84=A0=20=EB=B0=8F=20contentDescription?= =?UTF-8?q?=20=EC=A7=80=EC=9B=90=20=EA=B0=95=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `IconSource` 인터페이스와 `DrawableIcon` 구현을 리팩터링하여 콘텐츠 설명(content description)을 유연하게 처리하도록 개선했습니다. * **구조 변경**: `IconSource` 인터페이스의 `contentDescription` 프로퍼티를 `@Composable` 함수인 `contentDescription()`으로 변경했습니다. * **기능 추가**: `DrawableIcon`에 `@StringRes` 타입의 `contentDescTextId` 파라미터를 추가하여, 문자열 리소스를 통해 콘텐츠 설명을 제공할 수 있도록 지원합니다. * **동작 변경**: 기존에 `DrawableIcon`에 직접 문자열로 전달하던 `contentDescription`을 제거하고, `contentDescription()` 함수 내에서 `stringResource`를 호출하여 처리하도록 수정했습니다. --- .../team/prezel/core/designsystem/icon/IconSource.kt | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) 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 index 40d8ecf..1f29c13 100644 --- 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 @@ -1,24 +1,30 @@ package com.team.prezel.core.designsystem.icon import androidx.annotation.DrawableRes +import androidx.annotation.StringRes import androidx.compose.runtime.Composable import androidx.compose.runtime.Immutable import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource @Immutable interface IconSource { - val contentDescription: String? - @Composable fun painter(): Painter + + @Composable + fun contentDescription(): String? } @Immutable data class DrawableIcon( - override val contentDescription: String? = null, @param:DrawableRes val resId: Int, + @param:StringRes val contentDescTextId: Int? = null, ) : IconSource { @Composable override fun painter(): Painter = painterResource(resId) + + @Composable + override fun contentDescription(): String? = contentDescTextId?.let { stringResource(contentDescTextId) } } From a1e09a5b3989273208fd272ee699b21d257c0276 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Sat, 24 Jan 2026 20:23:02 +0900 Subject: [PATCH 14/18] =?UTF-8?q?refactor:=20=ED=94=8C=EB=A1=9C=ED=8C=85?= =?UTF-8?q?=20=EB=B2=84=ED=8A=BC=EC=9D=98=20Content=20Description=EC=9D=84?= =?UTF-8?q?=20=EB=A6=AC=EC=86=8C=EC=8A=A4=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 하드코딩 되어있던 `PrezelFloatingMenuButton`의 "플로팅 버튼 닫기" Content Description을 `strings.xml` 리소스로 추출하여 관리하도록 수정했습니다. * **주요 변경 사항**: * `core/designsystem` 모듈에 `strings.xml` 파일 추가 및 `close_floating_btn_content_desc` 문자열 리소스 정의. * `PrezelFloatingMenuButton`에서 확장 상태(`isExpanded`)일 때, 하드코딩된 문자열 대신 `R.string.close_floating_btn_content_desc` 리소스를 참조하도록 변경. --- .../component/button/floating/PrezelFloatingMenuButton.kt | 4 +++- Prezel/core/designsystem/src/main/res/values/strings.xml | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 Prezel/core/designsystem/src/main/res/values/strings.xml 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 index e0b41ef..2eb970f 100644 --- 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 @@ -23,6 +23,7 @@ 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.DrawableIcon import com.team.prezel.core.designsystem.icon.IconSource import com.team.prezel.core.designsystem.icon.PrezelIcons @@ -70,7 +71,8 @@ private fun PrezelMainFloatingButton( onClick: () -> Unit, modifier: Modifier = Modifier, ) { - val currentIconSource = if (isExpanded) DrawableIcon(resId = PrezelIcons.Cancel, contentDescription = "플로팅 버튼 닫기") else iconSource + val currentIconSource = + if (isExpanded) DrawableIcon(resId = PrezelIcons.Cancel, contentDescTextId = R.string.close_floating_btn_content_desc) else iconSource PrezelFloatingButton( iconSource = currentIconSource, diff --git a/Prezel/core/designsystem/src/main/res/values/strings.xml b/Prezel/core/designsystem/src/main/res/values/strings.xml new file mode 100644 index 0000000..370c924 --- /dev/null +++ b/Prezel/core/designsystem/src/main/res/values/strings.xml @@ -0,0 +1,4 @@ + + + 플로팅 버튼 닫기 + From 619ab1183c4ab8417e3e32f92855f6393d57a8b6 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Sat, 24 Jan 2026 20:23:09 +0900 Subject: [PATCH 15/18] =?UTF-8?q?refactor:=20`IconSource`=EC=9D=98=20conte?= =?UTF-8?q?ntDescription=EC=9D=84=20=ED=95=A8=EC=88=98=20=ED=98=B8?= =?UTF-8?q?=EC=B6=9C=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `IconSource`의 `contentDescription` 프로퍼티 접근 방식을 직접 참조에서 함수(`contentDescription()`) 호출로 변경하여 일관성을 확보하고 향후 확장을 용이하게 했습니다. * `PrezelFloatingButtonMenuItem` * `PrezelButtonStyle` * `PrezelFloatingButton` 위 컴포넌트들에서 `Icon`의 `contentDescription`을 `iconSource.contentDescription()`으로 수정했습니다. --- .../core/designsystem/component/button/PrezelButtonStyle.kt | 2 +- .../component/button/floating/PrezelFloatingButton.kt | 2 +- .../component/button/floating/PrezelFloatingButtonMenuItem.kt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) 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 index f98193e..6691d93 100644 --- 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 @@ -54,7 +54,7 @@ internal fun PrezelButtonIcon( if (icon == null) return Icon( painter = icon.painter(), - contentDescription = icon.contentDescription, + contentDescription = icon.contentDescription(), modifier = modifier.size( when (size) { PrezelButtonSize.XSMALL -> 14.dp 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 index a2ddea0..9ed408d 100644 --- 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 @@ -36,7 +36,7 @@ fun PrezelFloatingButton( ) { Icon( painter = iconSource.painter(), - contentDescription = iconSource.contentDescription, + contentDescription = iconSource.contentDescription(), modifier = Modifier.size(prezelFloatingButtonIconSize(style.size)), ) } 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 index dba2d74..5b198d2 100644 --- 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 @@ -51,7 +51,7 @@ fun PrezelFloatingButtonMenuItem( private fun PrezelFloatingButtonMenuItemIcon(iconSource: IconSource) { Icon( painter = iconSource.painter(), - contentDescription = iconSource.contentDescription, + contentDescription = iconSource.contentDescription(), modifier = Modifier.size(prezelFloatingButtonMenuItemIconSize()), ) From 47432800e26297e0bc46c6ac5364734c7a0c4965 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Sat, 24 Jan 2026 20:37:35 +0900 Subject: [PATCH 16/18] =?UTF-8?q?refactor:=20`IconSource`=EC=9D=98=20`cont?= =?UTF-8?q?entDescription`=20=EA=B8=B0=EB=8A=A5=20=ED=99=95=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `IconSource` 인터페이스와 그 구현체인 `ResIconSource`에서 `contentDescription` 함수의 파라미터를 변경하여, 동적인 포맷 인자(format arguments)를 전달할 수 있도록 개선했습니다. * **`IconSource` 인터페이스**: `contentDescription()` 함수에 가변 인자(vararg) `args: String`를 추가했습니다. * **`ResIconSource` 클래스**: `stringResource` 호출 시 전달받은 `args`를 포함하도록 수정하여, 문자열 리소스에 동적 값을 삽입할 수 있게 되었습니다. --- .../java/com/team/prezel/core/designsystem/icon/IconSource.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 index 1f29c13..7f714f0 100644 --- 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 @@ -14,7 +14,7 @@ interface IconSource { fun painter(): Painter @Composable - fun contentDescription(): String? + fun contentDescription(vararg args: String): String? } @Immutable @@ -26,5 +26,5 @@ data class DrawableIcon( override fun painter(): Painter = painterResource(resId) @Composable - override fun contentDescription(): String? = contentDescTextId?.let { stringResource(contentDescTextId) } + override fun contentDescription(vararg args: String): String? = contentDescTextId?.let { resId -> stringResource(resId, args) } } From c7990a01cbf570d841cc98d6620e88b0e83dfbc3 Mon Sep 17 00:00:00 2001 From: moondev03 Date: Sat, 24 Jan 2026 20:39:35 +0900 Subject: [PATCH 17/18] =?UTF-8?q?refactor:=20PrezelFloatingMenuButton?= =?UTF-8?q?=EC=9D=98=20Preview=20=ED=8C=8C=EB=9D=BC=EB=AF=B8=ED=84=B0?= =?UTF-8?q?=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `PrezelFloatingMenuButton.kt` 파일 내 Preview용 컴포저블 함수인 `PreviewFloatingMenuButton`의 파라미터명을 더 명확하게 수정했습니다. * `isExpanded` 파라미터명을 `initialExpanded`로 변경하여, 상태의 초기값을 설정하는 역할을 명확히 표현했습니다. * 이 변경 사항을 `PrimaryFloatingMenuButtonPreview`와 `SecondaryFloatingMenuButtonPreview` 내 호출부에 반영했습니다. --- .../floating/PrezelFloatingMenuButton.kt | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) 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 index 2eb970f..d2c1002 100644 --- 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 @@ -127,19 +127,19 @@ private fun PrimaryPrezelFloatingMenuButtonPreview() { horizontalArrangement = Arrangement.spacedBy(12.dp), ) { PreviewFloatingMenuButton( - isExpanded = false, + initialExpanded = false, style = PrezelFloatingButtonStyle(hierarchy = PrezelFloatingButtonHierarchy.PRIMARY, size = PrezelFloatingButtonSize.REGULAR), ) PreviewFloatingMenuButton( - isExpanded = true, + initialExpanded = true, style = PrezelFloatingButtonStyle(hierarchy = PrezelFloatingButtonHierarchy.PRIMARY, size = PrezelFloatingButtonSize.REGULAR), ) PreviewFloatingMenuButton( - isExpanded = false, + initialExpanded = false, style = PrezelFloatingButtonStyle(hierarchy = PrezelFloatingButtonHierarchy.PRIMARY, size = PrezelFloatingButtonSize.SMALL), ) PreviewFloatingMenuButton( - isExpanded = true, + initialExpanded = true, style = PrezelFloatingButtonStyle(hierarchy = PrezelFloatingButtonHierarchy.PRIMARY, size = PrezelFloatingButtonSize.SMALL), ) } @@ -160,19 +160,19 @@ private fun SecondaryPrezelFloatingMenuButtonPreview() { horizontalArrangement = Arrangement.spacedBy(12.dp), ) { PreviewFloatingMenuButton( - isExpanded = false, + initialExpanded = false, style = PrezelFloatingButtonStyle(hierarchy = PrezelFloatingButtonHierarchy.SECONDARY, size = PrezelFloatingButtonSize.REGULAR), ) PreviewFloatingMenuButton( - isExpanded = true, + initialExpanded = true, style = PrezelFloatingButtonStyle(hierarchy = PrezelFloatingButtonHierarchy.SECONDARY, size = PrezelFloatingButtonSize.REGULAR), ) PreviewFloatingMenuButton( - isExpanded = false, + initialExpanded = false, style = PrezelFloatingButtonStyle(hierarchy = PrezelFloatingButtonHierarchy.SECONDARY, size = PrezelFloatingButtonSize.SMALL), ) PreviewFloatingMenuButton( - isExpanded = true, + initialExpanded = true, style = PrezelFloatingButtonStyle(hierarchy = PrezelFloatingButtonHierarchy.SECONDARY, size = PrezelFloatingButtonSize.SMALL), ) } @@ -181,10 +181,10 @@ private fun SecondaryPrezelFloatingMenuButtonPreview() { @Composable private fun PreviewFloatingMenuButton( - isExpanded: Boolean, + initialExpanded: Boolean, style: PrezelFloatingButtonStyle, ) { - var isExpanded by remember { mutableStateOf(isExpanded) } + var isExpanded by remember { mutableStateOf(initialExpanded) } PrezelFloatingMenuButton( iconSource = DrawableIcon(resId = PrezelIcons.Blank), From 46c85db80073647e0b5bd7d198d477f2ad73c02a Mon Sep 17 00:00:00 2001 From: MunJangHun <105299421+moondev03@users.noreply.github.com> Date: Sat, 24 Jan 2026 20:42:01 +0900 Subject: [PATCH 18/18] =?UTF-8?q?fix:=20spread=20=EC=97=B0=EC=82=B0?= =?UTF-8?q?=EC=9E=90=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- .../java/com/team/prezel/core/designsystem/icon/IconSource.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index 7f714f0..223c8d9 100644 --- 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 @@ -26,5 +26,5 @@ data class DrawableIcon( override fun painter(): Painter = painterResource(resId) @Composable - override fun contentDescription(vararg args: String): String? = contentDescTextId?.let { resId -> stringResource(resId, args) } + override fun contentDescription(vararg args: String): String? = contentDescTextId?.let { resId -> stringResource(resId, *args) } }