-
Notifications
You must be signed in to change notification settings - Fork 1
PrezelButton 구현 #25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
PrezelButton 구현 #25
Conversation
Walkthrough디자인 시스템에 버튼 컴포넌트군을 추가합니다. 새 공개 Composable Possibly related PRs
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
There was a problem hiding this 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
🤖 Fix all issues with AI agents
In
`@Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButton.kt`:
- Around line 27-68: PrezelButton에 iconContentDescription: String? 파라미터를 추가하고
내부에서 PrezelButtonIcon에 전달하도록 변경하라; 텍스트가 없는(hasText == false) 경우
iconContentDescription이 null이면 require를 사용해 예외를 발생시켜 스크린리더용 설명을 강제하고(예:
require(hasText || iconContentDescription != null) { ... }), PrezelButtonIcon 호출
시 contentDescription 파라미터로 전달하라; 동일한 iconContentDescription 파라미터를
PrezelIconButton에도 노출시키고 해당 호출부에서 전달되도록 동기화해 접근성 요구사항을 충족시켜라.
In
`@Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonStyle.kt`:
- Around line 122-137: The function prezelButtonContentColor currently checks
isSystemInDarkTheme() and returns PrezelColorScheme.Dark.textLarge for
PrezelButtonType.FILLED, which ignores the injected theme and causes contrast
issues; change the logic to rely only on the theme-provided colors/flags (e.g.,
use the passed colors: PrezelColors and/or a theme flag such as
PrezelTheme.isDarkTheme or add a Boolean parameter isDarkTheme) instead of
isSystemInDarkTheme(), and replace any reference to
PrezelColorScheme.Dark.textLarge with the appropriate color from the injected
colors so FILLED text color is derived solely from the active PrezelTheme.
In `@Prezel/detekt-config.yml`:
- Around line 29-30: The rule entry "DestructuringDeclarationWithTooManyEntries"
has incorrect indentation; adjust it to match other rules by using two spaces
for the rule key level and two additional spaces for its properties so the block
reads with a 2-space indent for the rule name and its "active: false" property
indented two spaces further under that rule (i.e., follow the same 2-space rule
+ 2-space property nesting used by other rule entries).
🧹 Nitpick comments (2)
Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelIconButton.kt (1)
10-25: IconSource 추상화와 API 타입이 일관되지 않습니다.
추상화가 이미 도입된 만큼, 공개 API도DrawableIcon대신IconSource를 받는 편이 확장성에 유리합니다.♻️ 리팩터링 제안
-fun PrezelIconButton( - icon: DrawableIcon, +fun PrezelIconButton( + icon: IconSource, onClick: () -> Unit, modifier: Modifier = Modifier, enabled: Boolean = true, style: PrezelButtonStyle = PrezelButtonStyle(), ) {Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonPreview.kt (1)
88-115: 불필요한Column래퍼 제거 고려.
Column내부에Row가 하나만 있어 불필요한 중첩으로 보입니다. 향후 확장 계획이 없다면Row만 사용하는 것이 더 간결합니다.♻️ 선택적 리팩토링 제안
`@Composable` private fun PrezelButtonPreviewHierarchyBlock( type: PrezelButtonType, hierarchy: PrezelButtonHierarchy, enabled: Boolean, isRounded: Boolean, content: PrezelButtonPreviewContent, modifier: Modifier = Modifier, ) { - Column( - modifier = modifier, - verticalArrangement = Arrangement.spacedBy(8.dp), - ) { - Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) { - PreviewSizes.forEach { size -> - content( - PrezelButtonStyle( - buttonType = type, - buttonHierarchy = hierarchy, - buttonSize = size, - isRounded = isRounded, - ), - enabled, - ) - } + Row( + modifier = modifier, + horizontalArrangement = Arrangement.spacedBy(8.dp), + ) { + PreviewSizes.forEach { size -> + content( + PrezelButtonStyle( + buttonType = type, + buttonHierarchy = hierarchy, + buttonSize = size, + isRounded = isRounded, + ), + enabled, + ) } } }
...esignsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButton.kt
Show resolved
Hide resolved
...system/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButtonStyle.kt
Show resolved
Hide resolved
`PrezelTheme`의 `CompositionLocalProvider`에 `LocalTextStyle`과 `LocalContentColor`를 추가하여 앱 전체의 기본 텍스트 스타일과 콘텐츠 색상을 명시적으로 설정했습니다. * `LocalTextStyle`에 `typographyScheme.body3Regular`를 적용하여 기본 텍스트 스타일을 지정했습니다. * `LocalContentColor`에 `colorScheme.textLarge`를 적용하여 기본 콘텐츠 색상을 지정했습니다.
`LightPrezelColorScheme`에서 `borderSmall`의 색상 값을 `CoolGray500`에서 `CoolGray50`으로 변경했습니다.
디자인 시스템의 공통 버튼 컴포넌트인 `PrezelButton`을 추가했습니다. 이 컴포넌트는 타입, 계층, 크기, 모양 등 다양한 조합을 통해 유연하게 사용할 수 있도록 설계되었습니다.
* **주요 기능 및 속성**
* `PrezelButtonType`: `FILLED`, `OUTLINED`, `GHOST` 3가지 버튼 타입을 지원합니다.
* `PrezelButtonHierarchy`: `PRIMARY`, `SECONDARY` 2가지 계층을 제공합니다.
* `PrezelButtonSize`: `XSMALL`, `SMALL`, `REGULAR` 3가지 크기 옵션을 포함합니다.
* `isRounded` 파라미터를 통해 버튼의 모서리를 둥글게 또는 직각으로 설정할 수 있습니다.
* `leadingIconResId`를 사용하여 버튼 텍스트 앞에 아이콘을 추가할 수 있습니다.
* 활성화(`enabled`) 상태에 따라 컨테이너 색상, 콘텐츠 색상, 보더 스타일이 자동으로 변경됩니다.
* **미리보기 추가**
* 버튼의 타입(`FILLED`, `OUTLINED`, `GHOST`), 계층, 크기, 활성화 상태, 모서리 모양 등 모든 조합을 시각적으로 확인할 수 있는 상세한 `@Preview` 코드를 추가했습니다.
아이콘 리소스를 추상화하는 `IconSource` 인터페이스를 추가하여 다양한 종류의 아이콘(Drawable 등)을 일관된 방식으로 처리할 수 있는 기반을 마련했습니다. * **`IconSource` 인터페이스 추가**: `@Composable fun painter(): Painter` 함수를 통해 Painter 리소스를 반환하도록 정의했습니다. * **`DrawableIcon` 구현체 추가**: `@DrawableRes` ID를 받아 `IconSource`를 구현하는 데이터 클래스를 추가했습니다.
디자인 시스템의 `PrezelButton`에 사용될 스타일 속성과 하위 구성 요소를 정의하는 `PrezelButtonStyle.kt` 파일을 추가했습니다.
* **스타일 속성 정의**:
* `PrezelButtonType`: `FILLED`, `OUTLINED`, `GHOST`
* `PrezelButtonHierarchy`: `PRIMARY`, `SECONDARY`
* `PrezelButtonSize`: `XSMALL`, `SMALL`, `REGULAR`
* `PrezelButtonStyle`: 위의 속성들을 조합하여 버튼 스타일을 구성하는 데이터 클래스
* **Composable 함수 추가**:
* 버튼의 모양(`prezelButtonShape`), 테두리(`prezelButtonBorderStroke`), 텍스트 스타일(`prezelButtonTextStyle`), 배경색(`prezelButtonContainerColor`), 콘텐츠 색상(`prezelButtonContentColor`), 내부 패딩(`prezelButtonContentPadding`)을 동적으로 결정하는 내부 함수들을 구현했습니다.
* `PrezelButtonIcon`: 버튼 내부에 사용될 아이콘과 아이콘 좌우의 공백을 처리하는 컴포저블을 추가했습니다.
`PrezelButton`의 파라미터 구조를 스타일 객체(`PrezelButtonStyle`) 기반으로 변경하여 확장성을 높이고, 아이콘 처리를 `IconSource`로 통합하여 유연성을 강화했습니다. * **구조 변경**: `buttonType`, `buttonHierarchy`, `buttonSize`, `isRounded` 등 개별 파라미터를 `PrezelButtonStyle` 데이터 클래스로 통합했습니다. * **아이콘 처리 개선**: `@DrawableRes` 정수 ID 대신 `IconSource` 타입을 사용하도록 `icon` 파라미터를 변경하여 벡터 아이콘 등 다양한 아이콘 소스를 지원하도록 개선했습니다. * **기능 추가**: 텍스트(`text`)와 아이콘(`icon`)이 모두 `null`일 경우 에러를 발생시키는 로직을 추가하여 버튼이 비어있지 않도록 보장합니다. * **코드 정리**: 버튼의 속성(색상, 모양, 패딩 등)을 결정하는 내부 `private` 함수들을 제거하고, 관련 로직을 `PrezelButtonStyle`로 이전했습니다.
Compose 컴파일러가 `PrezelButtonStyle`을 안정적인 클래스로 인식하도록 `@Immutable` 어노테이션을 추가했습니다. 이를 통해 불필요한 리컴포지션을 방지하여 성능을 최적화합니다.
디자인 시스템의 버튼 컴포넌트를 시각적으로 테스트하고 검증하기 위한 공통 프리뷰 유틸리티를 추가했습니다. 이 유틸리티는 버튼의 다양한 상태(Type, Hierarchy, Size, Enabled, Rounded) 조합을 체계적으로 확인할 수 있도록 돕습니다. * `PrezelButtonPreviewByType`: 버튼 타입(`PrezelButtonType`)에 따라 모든 변형(variant)을 표시하는 최상위 프리뷰 컨테이너 * `PrezelButtonVariantSection`, `PrezelButtonPreviewHierarchyBlock`: 활성화(enabled), 둥근 모서리(isRounded), 계층(hierarchy) 등 다양한 속성 조합에 따라 버튼을 섹션별로 그룹화하여 렌더링 * `PreviewVariants`, `PreviewSizes`: 테스트할 버튼의 상태와 크기 목록을 `immutable.persistentListOf`를 사용해 정의
`PrezelButton` 컴포넌트의 미리보기(@Preview) 구현을 단순화하고 재사용성을 높였습니다. * **리팩토링**: `PrezelButtonPreviewByType` 함수의 역할을 분리하여, 레이아웃(`PrezelButtonPreviewByType`)과 아이템 렌더링(`PrezelButtonPreviewItem`)으로 구조를 개선했습니다. * **단순화**: 복잡한 조합(활성화, 둥근 모서리 등)을 생성하던 `PrezelButtonVariantSection`과 `PrezelButtonPreviewHierarchyBlock` 함수를 제거하고, `PrezelButtonPreviewItem`을 사용하여 각 버튼 상태를 직접 명확하게 보여주도록 변경했습니다. * **기타**: 불필요한 import 문과 `persistentListOf` 사용 코드를 정리했습니다.
텍스트만으로 구성된 공통 버튼 컴포넌트인 `PrezelTextButton`을 추가했습니다. * **컴포넌트 구현**: `PrezelButton`을 재사용하여 텍스트 기반의 버튼을 생성합니다. * **파라미터**: `text`, `onClick`, `modifier`, `enabled`, `style`을 설정할 수 있습니다. * **미리보기 추가**: Filled, Outlined, Ghost 타입별로 `PrezelTextButton`의 상태(활성/비활성)를 확인할 수 있는 Preview 코드를 작성했습니다.
`PrezelButton`에서 아이콘만 포함된 버튼의 패딩 계산 방식을 개선하고, 아이콘 컴포넌트 내 불필요한 `Spacer`를 제거하여 코드를 최적화했습니다. * **리팩토링**: `prezelButtonContentPadding` 함수에 `onlyIcon` 파라미터를 추가하여, 텍스트 없이 아이콘만 있을 경우를 처리하는 `prezelIconButtonContentPadding` 함수를 호출하도록 로직을 분리했습니다. * **기능 추가**: 아이콘 버튼의 크기(`XSMALL`, `SMALL`, `REGULAR`)에 따라 적절한 패딩 값을 반환하는 `prezelIconButtonContentPadding` 함수를 추가했습니다. * **코드 개선**: `LeadingIcon` 컴포저블 내에서 아이콘과 텍스트 사이의 간격을 조절하던 `Spacer`를 제거했습니다. 이는 버튼 자체의 `contentPadding`으로 간격을 관리하는 것이 더 적절하기 때문입니다.
`PrezelButton` 컴포넌트의 내부 로직을 개선하여 아이콘과 텍스트 사이의 간격을 추가하고, 아이콘만 있을 경우의 패딩을 조정했습니다. * **기능 변경**: 아이콘과 텍스트 사이에 `Spacer`를 추가하여 버튼 크기(`REGULAR` 또는 그 외)에 따라 간격을 동적으로 조절합니다. * **리팩토링**: `prezelButtonContentPadding` 함수에 `onlyIcon` 파라미터를 추가하여, 텍스트 없이 아이콘만 있는 버튼일 때 좌우 패딩이 적용되지 않도록 수정했습니다.
아이콘 전용 버튼인 `PrezelIconButton` 컴포저블을 추가했습니다. 이 컴포넌트는 내부적으로 `PrezelButton`을 사용하여 구현되었습니다. * **기능**: `DrawableIcon`, `onClick`, `enabled`, `style` 등의 파라미터를 통해 아이콘 버튼을 생성할 수 있습니다. * **미리보기**: Filled, Outlined, Ghost 스타일에 대한 `PrezelIconButtonPreview`를 추가하여 각 버튼 유형별 상태(활성화/비활성화)를 시각적으로 확인할 수 있도록 했습니다.
detekt-config.yml 파일에 `DestructuringDeclarationWithTooManyEntries` 규칙을 비활성화(`active: false`)하는 설정을 추가했습니다. 이를 통해 여러 항목을 가진 데이터 클래스 등을 구조 분해 할당할 때 발생하는 경고를 무시하도록 합니다.
`PrezelButton` 컴포넌트의 내부 로직을 개선하여 코드 가독성과 안정성을 높였습니다.
* **변경 사항**:
* `text`와 `icon`의 null 여부를 `hasText`, `hasIcon` Boolean 변수로 관리하여 조건문을 간소화했습니다.
* 기존의 `error` 호출을 `require`로 변경하여, 버튼에 `text`나 `icon`이 없는 경우 더 명확한 예외 메시지("Button은 text 또는 icon 중 하나는 반드시 필요합니다.")를 제공하도록 수정했습니다.
* 아이콘과 텍스트가 함께 있을 때 간격(`Spacer`)을 추가하는 로직과 텍스트를 표시하는 로직의 흐름을 개선했습니다.
`PrezelIconButton` 컴포저블의 아이콘 파라미터 타입을 `DrawableIcon`에서 `IconSource`로 변경했습니다. 이를 통해 아이콘 소스를 더 유연하게 처리할 수 있도록 개선했습니다.
`PrezelButtonPreview.kt` 내 `PrezelButtonPreviewContentRow` 컴포저블의 레이아웃을 `Column`에서 `Row`로 변경하여 불필요한 중첩 구조를 제거하고 코드를 간소화했습니다.
`IconSource` 인터페이스와 이를 구현하는 `DrawableIcon` 데이터 클래스에 `contentDescription` 속성을 추가하여 아이콘의 접근성을 향상시켰습니다. * `IconSource` 인터페이스에 `contentDescription: String?` 프로퍼티 추가 * `DrawableIcon` 데이터 클래스 생성자에 `contentDescription` 파라미터 추가 및 인터페이스 구현 업데이트
`detekt-config.yml` 파일의 가독성 향상을 위해 전체적으로 일관된 들여쓰기를 적용했습니다. 기능적인 설정 변경은 없습니다.
e3a38ad to
4ecb9c4
Compare
`PrezelTopAppBar` 컴포넌트의 프리뷰(Preview) 코드를 개선하여 가독성을 높이고 중복을 제거했습니다. * `Surface`를 추가하여 프리뷰 배경색(`bgRegular`)을 명시적으로 지정했습니다. * 타이틀(`Text`)에 적용되던 `PrezelTextStyles.Body2Bold`를 제거했습니다. (`ProvideTextStyle`을 통해 기본 스타일이 이미 적용되고 있음) * 아이콘(`Icon`)에 직접 지정하던 `tint`를 제거하여 `LocalContentColor`를 통해 색상이 적용되도록 수정했습니다. * 스크롤 테스트 프리뷰(`PrezelTopAppBarScrollTestPreview`)의 배경색을 설정하고 `LazyColumn` 내부 아이템 레이아웃을 간소화했습니다.
📌 작업 내용
Prezel 서비스 테마를 사용한 기본 컴포넌트
PrezelButton,PrezelTextButton,PrezelIconButton을 구현했습니다.Prezel Button Property
각 Property에 맞는 디자인을 반영하기 위한 코드는
PrezelButtonStyle에 구현했습니다.원하는 스타일의 버튼을 사용하기 위해서는
PrezelButtonStyle를 정의하여 사용하시면 됩니다.IconSource구현Painter는 추상 클래스이기 때문에 컴파일 타임에 안정성(Stable)을 판단할 수 없습니다.이 문제를 해결하기 위해
IconSource와 이를 구현한DrawableIcon을 도입했습니다.이 구조를 통해 아이콘에 필요한
Painter와contentDescription그리고 리소스 정보를 하나의 객체로 일관되게 관리할 수 있습니다.그 결과, 아이콘을 사용하는 컴포저블에서는
IconSource만 전달받아iconSource.painter()와iconSource.contentDescription처럼 명확하고 안전한 방식으로 사용할 수 있게 되었습니다.이는 API 사용성을 개선할 뿐만 아니라, 아이콘 관련 책임을 한 곳에 모아 컴포저블의 역할을 더욱 단순하게 prove 데에도 도움이 됩니다.
기존
PrezelTopAppBarPreview 코드 개선Preview 코드에 배경 색상을 적용했습니다.
🧩 관련 이슈
📸 스크린샷
PrezelButton(Icon + Text)PrezelTextButtonPrezelIconButtonSummary by CodeRabbit
릴리스 노트
새로운 기능
스타일
잡무(Chores)
✏️ Tip: You can customize this high-level summary in your review settings.