Skip to content

PrezelButton 높이 고정 문제 해결을 위한 Surface → Box 구조 변경#78

Merged
moondev03 merged 13 commits intodevelopfrom
fix/#77-prezel-button-min-height
Mar 15, 2026
Merged

PrezelButton 높이 고정 문제 해결을 위한 Surface → Box 구조 변경#78
moondev03 merged 13 commits intodevelopfrom
fix/#77-prezel-button-min-height

Conversation

@moondev03
Copy link
Member

@moondev03 moondev03 commented Mar 8, 2026

📌 작업 내용

  • PrezelButton 렌더링 구조를 Surface에서 Box + clickable 기반으로 변경하여 외형/동작 로직을 분리했습니다.
  • PrezelButtonAppearance를 도입해 텍스트 스타일, 색상, 패딩, shape, border, icon size 계산을 한 곳에서 관리하도록 정리했습니다.
  • 버튼 콘텐츠(텍스트/아이콘) 렌더링 로직을 정리하고 underline 처리 modifier를 분리했습니다.
  • Ghost 버튼 프리뷰에 shape 기반 점선 보더가 보이도록 개선했습니다.
  • 점선 보더 유틸을 DrawDashBorder.kt로 정리하고 기존 오타 파일(DrowDashBorder.kt)을 제거했습니다.
  • 검증: ./gradlew :core-designsystem:compileDebugKotlin 빌드 성공

🧩 관련 이슈


📸 스크린샷

이전에 말씀드린 것처럼, 배경과 경계가 시각적으로 구분되지 않는 컴포넌트의 경우 프리뷰에서 식별이 어렵기 때문에 DashBorder를 적용했습니다. 프리뷰 환경에서만 컴포넌트의 경계를 명확하게 확인하기 위한 용도입니다.

image

📢 논의하고 싶은 내용

Summary by CodeRabbit

릴리스 노트

  • Refactor

    • 버튼 렌더링 구조가 재구성되어 레이아웃과 상호작용 처리가 일관되게 동작합니다.
    • 스타일 계산이 통합되어 유지보수성이 향상되었습니다.
  • Style

    • 아이콘/텍스트 간격, 패딩, 크기 등 시각 요소가 통일된 외형 설정으로 적용됩니다.
    • 점선(대시) 테두리 장식 옵션이 추가되었습니다.
  • Chores

    • 미리보기 컴포넌트가 아이콘 전용 표시와 수정자 전달을 지원하도록 개선되었습니다.

`PrezelButton`의 아이콘 크기 결정 로직을 `PrezelButtonAppearance`로 캡슐화하여 컴포넌트 구조를 개선했습니다.

* `PrezelButtonAppearance` 데이터 클래스에 `iconSize` 프로퍼티를 추가했습니다.
* `PrezelButton` 컴포저블 내부에서 `buttonSize`를 직접 참조하여 아이콘 크기를 계산하던 방식에서, 생성된 `appearance.iconSize`를 사용하도록 변경했습니다.
* `prezelButtonIconSize` 함수의 가시성을 `private`으로 변경하고 위치를 조정했습니다.
* `PrezelButtonIcon` 컴포저블의 불필요한 `buttonSize` 파라미터를 제거했습니다.
@moondev03 moondev03 self-assigned this Mar 8, 2026
@moondev03 moondev03 requested a review from HamBeomJoon as a code owner March 8, 2026 19:07
@moondev03 moondev03 added 🔧 fix 정상 동작해야 하는 기능의 결함 수정 🔨 refactor 기능 변경 없이 내부 구조, 설계, 가독성 개선 labels Mar 8, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 8, 2026

Walkthrough

이 변경은 PrezelButton을 Surface 기반에서 Box 기반으로 전환해 LocalMinimumInteractiveComponentSize 영향으로 인한 최소 높이 제약을 제거했고, 스타일 속성을 중앙화한 내부 데이터 클래스 PrezelButtonAppearance를 도입했습니다. 버튼 렌더링을 PrezelButtonContent로 분리해 아이콘/텍스트 레이아웃과 색상/패딩을 appearance로 일원화했으며, 언더라인 처리는 새로운 prezelButtonUnderline 모디파이어로 대체했습니다. 프리뷰 헬퍼들은 modifierisIconOnly 매개변수를 전달하도록 업데이트되었고, 대시 테두리 유틸리티(drawDashBorder)가 새로 추가되면서 기존 유사 파일이 삭제되었습니다.

Possibly related PRs

  • PR 25: 동일한 버튼 컴포저블과 스타일 계층(PrezelButton, PrezelButtonStyle) 및 프리뷰/유틸리티 리팩토링을 다루며 코드 수준으로 직접 연관됨.
  • PR 63: 버튼의 shape·패딩·아이콘 처리 로직 변경과 겹치는 계산 및 visibility/시그니처 조정이 포함되어 있음.
  • PR 74: 버튼 언더라인(그리기) 처리 관련 구현 변경을 다루며 언더라인 모디파이어 및 drawBehind 기반 코드와 직접 연관됨.

Suggested labels

🧹 chore

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목이 변경 내용의 핵심을 정확히 전달합니다: Surface에서 Box 기반으로의 구조 변경으로 버튼 높이 고정 문제 해결.
Description check ✅ Passed PR 설명이 템플릿의 모든 필수 섹션(작업 내용, 관련 이슈, 스크린샷, 논의 사항)을 포함하며 상세하고 명확합니다.
Linked Issues check ✅ Passed PR의 모든 코드 변경이 이슈 #77의 목표를 충족합니다: Surface를 Box로 변경, 높이 강제 확대 문제 해결, 외형/동작 로직 분리.
Out of Scope Changes check ✅ Passed 모든 변경사항이 이슈 #77의 범위 내에 있습니다: 버튼 구조 변경, 외형 관리 체계화, 유틸 정리는 모두 목표 달성에 필요한 변경입니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButton.kt`:
- Around line 42-50: The clickable is applied after applyButtonAppearance which
reduces the visual Box size (especially icon-only XSMALL/SMALL in
PrezelButtonStyle) and thus shrinks the hit target; change the modifier order or
add an explicit minimum touch target so the clickable hit area remains at least
48.dp by default. Specifically, in PrezelButton.kt ensure
Modifier.clickable(...) is applied before any size-restricting modifiers from
applyButtonAppearance or add a min touch target (e.g., sizeIn/minHeight 48.dp)
around the composable unless an explicit opt-out is provided in
PrezelButtonStyle; keep references to modifier, applyButtonAppearance,
clickable, and PrezelButtonStyle when making the change.
- Around line 41-43: The Box in PrezelButton.kt that starts with "Box(modifier =
modifier.applyButtonAppearance(appearance)" lacks a contentAlignment so when
callers use Modifier.fillMaxWidth() or fixed height the Row children stick to
the top-left; update that Box to set contentAlignment = Alignment.Center (or
Alignment.CenterStart/CenterEnd as desired) so its children (the inner Row and
its text/icon) are centered inside the Box while keeping the Row's internal
arrangement unchanged.

In
`@Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonPreview.kt`:
- Around line 109-117: The ghost icon preview is using a wrong shape because
appearance is always computed with isIconOnly = false; update
PrezelButtonPreview to compute PrezelButtonAppearance via
PrezelButtonAppearance.of(...) using the actual content context (set isIconOnly
= true for icon-only previews) before passing it into content and the Modifier
chain (especially where PrezelButtonType.GHOST and Modifier.drawDashBorder(...)
are applied), so each preview item derives its appearance from the real content
rather than a common false value.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 7d36d01f-bac4-4942-918b-0ae291c96609

📥 Commits

Reviewing files that changed from the base of the PR and between ab6e9e2 and 9b1a209.

📒 Files selected for processing (7)
  • Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButton.kt
  • Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonPreview.kt
  • Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonStyle.kt
  • Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelIconButton.kt
  • Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelTextButton.kt
  • Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/util/DrawDashBorder.kt
  • Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/util/DrowDashBorder.kt
💤 Files with no reviewable changes (1)
  • Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/util/DrowDashBorder.kt

moondev03 and others added 5 commits March 9, 2026 04:26
`PrezelButton` 컴포넌트의 최상위 `Box` 컨테이너에 `contentAlignment = Alignment.Center` 속성을 추가하여 내부 콘텐츠가 중앙에 정렬되도록 수정하였습니다.
* `PrezelButtonAppearance` 데이터 클래스의 생성자에서 `private` 키워드를 제거하여 내부(internal) 패키지 내에서의 가시성을 확보했습니다.
`PrezelButton` 컴포넌트의 텍스트 색상 결정 로직에서 불필요한 테마 체크와 의존성을 제거하였습니다.

*   `FILLED` 타입 버튼의 텍스트 색상을 결정할 때 `isSystemInDarkTheme()` 체크 및 `PrezelColorScheme.Dark` 직접 참조를 제거하고, 현재 테마의 `colors.textLarge`를 사용하도록 수정했습니다.
*   사용되지 않는 `isSystemInDarkTheme` 및 `PrezelColorScheme` 임포트 문을 정리했습니다.
Copy link
Contributor

@HamBeomJoon HamBeomJoon left a comment

Choose a reason for hiding this comment

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

👍

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonStyle.kt (2)

66-66: 데이터 클래스 구조 분해는 필드 순서에 의존적입니다.

PrezelButtonStyle의 필드 순서가 변경되면 구조 분해가 조용히 깨질 수 있습니다. 명시적 접근 방식이 더 안전할 수 있습니다.

♻️ 제안된 수정
-            val (buttonType, buttonHierarchy, buttonSize, isRounded) = style
-
-            return PrezelButtonAppearance(
-                textStyle = prezelButtonTextStyle(size = buttonSize),
+            return PrezelButtonAppearance(
+                textStyle = prezelButtonTextStyle(size = style.buttonSize),
                 contentColor = prezelButtonContentColor(
-                    type = buttonType,
-                    hierarchy = buttonHierarchy,
+                    type = style.buttonType,
+                    hierarchy = style.buttonHierarchy,
                     enabled = enabled,
                 ),
                 contentPadding = prezelButtonContentPadding(
-                    size = buttonSize,
+                    size = style.buttonSize,
                     isIconOnly = isIconOnly,
                 ),
-                iconSpacing = prezelButtonIconSpacing(size = buttonSize),
+                iconSpacing = prezelButtonIconSpacing(size = style.buttonSize),
                 shape = prezelButtonShape(
                     isIconOnly = isIconOnly,
-                    isRounded = isRounded,
-                    buttonSize = buttonSize,
+                    isRounded = style.isRounded,
+                    buttonSize = style.buttonSize,
                 ),
                 containerColor = prezelButtonContainerColor(
-                    type = buttonType,
-                    hierarchy = buttonHierarchy,
+                    type = style.buttonType,
+                    hierarchy = style.buttonHierarchy,
                     enabled = enabled,
                 ),
                 borderStroke = prezelButtonBorderStroke(
-                    type = buttonType,
-                    hierarchy = buttonHierarchy,
+                    type = style.buttonType,
+                    hierarchy = style.buttonHierarchy,
                     enabled = enabled,
                 ),
-                iconSize = prezelButtonIconSize(size = buttonSize),
+                iconSize = prezelButtonIconSize(size = style.buttonSize),
             )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonStyle.kt`
at line 66, The destructuring val (buttonType, buttonHierarchy, buttonSize,
isRounded) = style is brittle because it depends on PrezelButtonStyle's field
order; replace the destructuring with explicit property access (e.g., use
style.buttonType, style.buttonHierarchy, style.buttonSize, style.isRounded)
wherever those variables are needed so changes to PrezelButtonStyle's
declaration won’t silently break behavior.

239-245: 아이콘 크기를 디자인 토큰으로 관리하는 것을 고려해 주세요.

다른 치수들은 PrezelSpacing, PrezelShapes 등의 디자인 토큰을 사용하지만, 아이콘 크기는 하드코딩되어 있습니다. 일관성을 위해 디자인 토큰으로 관리하는 것을 고려해 볼 수 있습니다.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonStyle.kt`
around lines 239 - 245, The icon sizes in prezelButtonIconSize currently use
hardcoded dp values; extract these into a design token (e.g., add a
PrezelIconSizes object or extend an existing token file like
PrezelSpacing/PrezelShapes) and replace the hardcoded 14.dp, 16.dp, 20.dp with
token properties (e.g., PrezelIconSizes.xsmall, .small, .regular) so
prezelButtonIconSize(PrezelButtonSize) returns the token values; update the
token definitions and any imports/usage in PrezelButtonStyle.kt to reference the
new tokens.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonStyle.kt`:
- Line 66: The destructuring val (buttonType, buttonHierarchy, buttonSize,
isRounded) = style is brittle because it depends on PrezelButtonStyle's field
order; replace the destructuring with explicit property access (e.g., use
style.buttonType, style.buttonHierarchy, style.buttonSize, style.isRounded)
wherever those variables are needed so changes to PrezelButtonStyle's
declaration won’t silently break behavior.
- Around line 239-245: The icon sizes in prezelButtonIconSize currently use
hardcoded dp values; extract these into a design token (e.g., add a
PrezelIconSizes object or extend an existing token file like
PrezelSpacing/PrezelShapes) and replace the hardcoded 14.dp, 16.dp, 20.dp with
token properties (e.g., PrezelIconSizes.xsmall, .small, .regular) so
prezelButtonIconSize(PrezelButtonSize) returns the token values; update the
token definitions and any imports/usage in PrezelButtonStyle.kt to reference the
new tokens.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 17f3b7ca-b1d0-42cd-a2fa-246734540454

📥 Commits

Reviewing files that changed from the base of the PR and between 422ddd0 and 0a763c5.

📒 Files selected for processing (1)
  • Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonStyle.kt

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonStyle.kt`:
- Around line 194-195: The FILLED branch in the color-selection logic
incorrectly hardcodes PrezelColorScheme.Dark.textLarge causing dark-theme text
to be used even when a light theme is active; update the PrezelButtonStyle.kt
branch handling PrezelButtonType.FILLED to use the provided colors parameter
(use colors.solidWhite) instead of PrezelColorScheme.Dark.textLarge so the white
text contrasts with the interactiveRegular background in both themes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0f6451fb-4a9f-4523-94fc-eedfdce8551d

📥 Commits

Reviewing files that changed from the base of the PR and between 0a763c5 and b469857.

📒 Files selected for processing (1)
  • Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonStyle.kt

Comment on lines 194 to +195
return when (type) {
PrezelButtonType.FILLED -> if (isSystemInDarkTheme()) colors.textLarge else PrezelColorScheme.Dark.textLarge
PrezelButtonType.FILLED -> PrezelColorScheme.Dark.textLarge
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

테마 무시 버그: PrezelColorScheme.Dark.textLarge 하드코딩

colors 파라미터를 받으면서도 FILLED 타입에서 PrezelColorScheme.Dark.textLarge를 직접 참조하고 있어, 라이트 테마에서도 다크 테마 색상이 사용됩니다.

FILLED 버튼의 interactiveRegular(파란색) 배경에 대비되는 흰색 텍스트가 필요하다면, 두 테마 모두에서 일관된 값을 갖는 colors.solidWhite를 사용해야 합니다.

🐛 테마 일관성을 위한 수정 제안
     return when (type) {
-        PrezelButtonType.FILLED -> PrezelColorScheme.Dark.textLarge
+        PrezelButtonType.FILLED -> colors.solidWhite
         PrezelButtonType.OUTLINED -> colors.interactiveRegular
         PrezelButtonType.GHOST -> colors.interactiveRegular
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonStyle.kt`
around lines 194 - 195, The FILLED branch in the color-selection logic
incorrectly hardcodes PrezelColorScheme.Dark.textLarge causing dark-theme text
to be used even when a light theme is active; update the PrezelButtonStyle.kt
branch handling PrezelButtonType.FILLED to use the provided colors parameter
(use colors.solidWhite) instead of PrezelColorScheme.Dark.textLarge so the white
text contrasts with the interactiveRegular background in both themes.

@moondev03 moondev03 merged commit 1d2cc20 into develop Mar 15, 2026
2 checks passed
@moondev03 moondev03 deleted the fix/#77-prezel-button-min-height branch March 15, 2026 07:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔧 fix 정상 동작해야 하는 기능의 결함 수정 🔨 refactor 기능 변경 없이 내부 구조, 설계, 가독성 개선

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PrezelButton 높이 고정 문제 해결을 위한 Surface → Box 구조 변경

2 participants