Skip to content

PrezelAccordion 구현#55

Open
HamBeomJoon wants to merge 10 commits intodevelopfrom
feat/#52-prezel-accordion
Open

PrezelAccordion 구현#55
HamBeomJoon wants to merge 10 commits intodevelopfrom
feat/#52-prezel-accordion

Conversation

@HamBeomJoon
Copy link
Contributor

@HamBeomJoon HamBeomJoon commented Feb 8, 2026

📌 작업 내용

  1. PrezelAccordion 구현

    • Header / Label / Content를 slot API로 제공
    • 펼침 상태에 따른 chevron rotation 애니메이션 적용
    • AnimatedVisibility 기반 expand / collapse 처리
    • Divider 표시 옵션 제공
    • Ripple 제거된 클릭 정책 적용
  2. PrezelIcon 업데이트

    • 전체적으로 아이콘이 Outlined -> Filled로 변경되었습니다.

🧩 관련 이슈


📸 스크린샷

스크린샷 2026-02-08 22 09 52
2026-02-08.22.10.42.mov

Summary by CodeRabbit

릴리스 노트

  • New Features

    • 새로운 Accordion 컴포넌트 추가: 클릭으로 확장/축소, 회전 애니메이션 아이콘 및 페이드/확장 콘텐츠 표시 지원
  • New Icons

    • 아이콘 라이브러리 확장/조정: Edit, Lock, Menu, Search, Setting, Storage, Upload 등 추가 및 Info/Warning의 Filled·Outlined 변형 도입
  • Style / Assets

    • 여러 아이콘 그래픽 경로 업데이트로 시각적 일관성 향상
    • 접근성 문자열(아코디언 설명) 추가
  • Previews

    • 상단바 및 컴포넌트 미리보기 아이콘 갱신으로 데모 표현 개선

디자인시스템에 아코디언 컴포넌트인 `PrezelAccordion`을 새롭게 추가했습니다.

*   `AnimatedVisibility`를 이용한 펼치기/접기 애니메이션 구현
*   헤더, 라벨, 콘텐츠 영역을 커스텀할 수 있는 슬롯 구조 적용
*   `showDivider` 옵션을 통한 구분선 표시 기능 제공
*   상태별 미리보기(Collapsed, Expanded, Interactive) 추가
아이콘 세트를 전반적으로 업데이트하고, 명명 규칙을 통일했습니다.

*   신규 아이콘 추가: `Menu`, `Search`, `Upload`, `Lock`, `Storage`, `QuestionCircle` 등
*   기존 아이콘 리팩토링: `Calendar`, `Balloon`, `Check`, `Person`, `Video` 등 벡터 패스 및 색상 수정
*   아이콘 명명 규칙 변경: `WarningCircle` -> `WarningCircleOutlined` 등 형태에 따른 접미사 추가
*   `PrezelIcons` 클래스 내 리소스 참조 업데이트 및 신규 아이콘 등록
*   불필요한 아이콘 삭제 (`ic_info`, `ic_warning`) 및 `PrezelAccordion` 코드 스타일 수정
@HamBeomJoon HamBeomJoon self-assigned this Feb 8, 2026
@HamBeomJoon HamBeomJoon added the ✨ feat 새로운 기능 추가 또는 기존 기능 확장 label Feb 8, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 8, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

새로운 Compose UI 컴포넌트 PrezelAccordion(공개 함수)이 추가되었고, 이를 구성하는 private 컴포저블들(헤더, 회전 쉐브론, 구분선, 애니메이트된 콘텐츠 컨테이너)과 여러 Preview가 포함되었습니다. PrezelIcons에 다수의 아이콘 상수가 추가·재구성되었고, 여러 벡터 drawable 리소스가 신규 추가·수정·삭제되었습니다. 문자열 리소스 core_designsystem_accordion_desc가 새로 추가되었습니다.

Possibly related PRs

  • Team-Prezel/Prezel-Android PR 45: PrezelIcons.kt의 아이콘 매핑 추가/수정이 이루어져 리소스·심볼 변경이 직접적으로 겹칩니다.
  • Team-Prezel/Prezel-Android PR 19: 동일하게 PrezelIcons.kt와 관련 drawable 리소스의 추가/조정 작업이 포함되어 코드·리소스 수준의 중복 가능성이 높습니다.
  • Team-Prezel/Prezel-Android PR 49: 디자인 시스템의 drawable 및 아이콘 리소스를 대규모로 변경하는 커밋으로 리소스 파일 변경이 직접적으로 연관됩니다.
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning Multiple icon files were modified and added beyond the PrezelAccordion implementation scope. While icon updates are mentioned in the PR description, the extensive icon geometry changes appear to be a separate refactoring effort. Consider separating icon refactoring (Outlined → Filled conversion) into a separate pull request to maintain clear scope boundaries and facilitate easier review and maintenance.
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 (3 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title 'PrezelAccordion 구현' clearly and directly describes the main change: implementing the PrezelAccordion component, which is the primary focus of this changeset.
Description check ✅ Passed The description adequately covers the main implementation details using the template format with 작업 내용, 관련 이슈, and 스크린샷 sections, though 논의하고 싶은 내용 section is omitted.
Linked Issues check ✅ Passed The pull request successfully implements the PrezelAccordion component from issue #52 with header/label/content slot API, chevron animation, AnimatedVisibility, divider option, and ripple-free interaction as required.

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


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: 2

🤖 Fix all issues with AI agents
In
`@Prezel/core/designsystem/src/main/res/drawable/core_designsystem_ic_calendar.xml`:
- Around line 7-8: Update the calendar drawable's fill color: locate the
android:fillColor attribute in core_designsystem_ic_calendar.xml (the <path>
element containing the calendar android:pathData) and change its value from
"#2F3238" to "#6E737D" so it matches the other design system icons.

In
`@Prezel/core/designsystem/src/main/res/drawable/core_designsystem_ic_menu.xml`:
- Around line 1-9: The vector drawable's pathData defines three horizontal dots
(a "more" icon) but the resource is named core_designsystem_ic_menu.xml (which
implies a hamburger/menu icon); either update the pathData to the three-line
hamburger shape in the <path> (replace the current dot pathData) or rename the
asset to reflect "more" (e.g., core_designsystem_ic_more) and update any
references; locate the <vector> and its <path> (android:pathData) in
core_designsystem_ic_menu.xml to make the change so resource name and visual
match the design system convention.
🧹 Nitpick comments (5)
Prezel/core/designsystem/src/main/res/drawable/core_designsystem_ic_person.xml (1)

6-11: 하드코딩된 fillColor 대신 테마 컬러 참조 고려

두 path 모두 fillColor#6E737D로 하드코딩되어 있습니다. Compose에서 tint를 통해 항상 색상을 오버라이드한다면 문제없지만, 그렇지 않은 경우 다크 모드 등 테마 전환 시 아이콘이 배경과 구분되지 않을 수 있습니다.

AI 요약에 따르면 이번 PR의 다른 아이콘들도 동일한 패턴을 사용하고 있으므로, 전체 아이콘 세트에 대해 일관된 방침이 있는지 확인해 주세요.

Prezel/core/designsystem/src/main/res/drawable/core_designsystem_ic_search.xml (1)

1-9: 새 Search 아이콘 추가 확인.

아이콘 구조와 fillColor가 일관됩니다. 참고로, TopAppBar.kt (Line 112)에서 PrezelIcons.Blank을 contentDescription "검색"으로 사용하고 있는 부분이 있습니다. 이 새로운 Search 아이콘으로 교체하는 것이 적절할 수 있습니다.

Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelAccordion.kt (3)

115-125: 접근성: chevron 아이콘에 contentDescription 추가 권장

contentDescription = null로 설정되어 있어 스크린 리더 사용자가 아코디언의 확장/축소 상태를 인지할 수 없습니다. 확장 상태에 따라 적절한 설명을 제공하는 것이 좋습니다.

또한, R.drawable.core_designsystem_ic_chevron_down을 직접 참조하는 대신 PrezelIcons.ChevronDown을 사용하면 다른 컴포넌트(PrezelRadio, PrezelCheckbox 등)와 일관성을 유지할 수 있습니다.

♻️ 제안
 `@Composable`
 private fun PrezelAccordionChevron(rotation: Float) {
     Icon(
-        painter = painterResource(R.drawable.core_designsystem_ic_chevron_down),
-        contentDescription = null,
+        painter = painterResource(PrezelIcons.ChevronDown),
+        contentDescription = "Toggle accordion",
         modifier = Modifier
             .size(24.dp)
             .rotate(rotation),
         tint = PrezelTheme.colors.iconRegular,
     )
 }

40-77: 공개 API 시그니처 검토

전체적으로 잘 구성되어 있습니다. 슬롯 기반 API로 header/label/content를 분리하고, AnimatedVisibility 기반의 확장/축소, ripple 제거 클릭 정책 등 PR 목표를 충실히 구현했습니다.

한 가지 고려할 점: enabled = false일 때 chevron이 여전히 표시되고 시각적 비활성화 표시가 없습니다. 비활성 상태의 시각적 피드백(예: 투명도 조절)을 추가하면 사용자 경험이 개선될 수 있습니다.


87-112: 헤더 영역의 클릭 영역과 접근성 시맨틱스

clickable modifier에 indication = null과 커스텀 interactionSource를 사용하여 ripple을 제거한 것은 PR 목표와 일치합니다. 다만, 접근성 향상을 위해 semantics 혹은 toggleable modifier를 활용하여 확장/축소 역할(Role)을 명시하면 TalkBack 등 보조 기술에서 더 나은 경험을 제공할 수 있습니다. 참고로 PrezelCheckbox에서는 toggleableRole.Checkbox를 사용하고 있습니다.

* 아코디언 컴포넌트에 접근성 보조를 위한 content description 리소스를 추가하고 적용했습니다.
* 아코디언 및 TopAppBar에 사용되는 아이콘 리소스를 `PrezelIcons` 상수로 교체했습니다.
* 캘린더 아이콘의 색상을 수정했습니다(`2F3238` -> `6E737D`).
* TopAppBar 프리뷰의 아이콘을 실제 아이콘으로 업데이트했습니다.
PrezelAccordion의 가독성과 유연성을 높이기 위해 파라미터 명칭을 변경하고 레이아웃을 조정하였습니다.

*   `label` 파라미터 명칭을 `trailingContent`로 변경하여 역할을 명확히 함
*   `chevron` 파라미터 명칭을 `icon`으로 변경
*   `onClick` 콜백 명칭을 `onTap`으로 변경
*   헤더 내부의 컴포넌트 간 간격(Spacer) 조정 및 레이아웃 최적화
*   Preview 코드에 변경된 파라미터 명칭 반영
…cordion

# Conflicts:
#	Prezel/core/designsystem/src/main/res/values/strings.xml
* refactor: PrezelAccordion 하드코딩된 수치를 디자인 시스템 토큰으로 교체

`PrezelAccordion` 컴포넌트 내부에서 사용되던 하드코딩된 여백 값(`12.dp`, `8.dp`)을 `PrezelTheme.spacing` 토큰(`V12`, `V8`)으로 수정하였습니다.

* style: strings.xml 리소스 위치 정렬

`core_designsystem_accordion_desc` 리소스의 위치를 가독성을 위해 상단으로 이동시켰습니다.
Copy link
Member

@moondev03 moondev03 left a comment

Choose a reason for hiding this comment

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

👍

`PrezelAccordion` 컴포넌트의 내부 구조를 정리하고 여백 및 클릭 로직을 개선했습니다.

*   **구조 및 레이아웃 개선**:
    *   `Surface`를 제거하고 `Modifier.background(Color.Transparent)`를 적용한 `Column`으로 변경했습니다.
    *   `PrezelAccordionHeader` 내부의 패딩 설정을 조정하고, `PrezelAccordionContent`의 고정 패딩(`V12`)을 제거하여 외부에서 제어할 수 있도록 수정했습니다.
    *   `PrezelAccordionChevron` 애니메이션 로직을 컴포넌트 내부로 캡슐화했습니다.
*   **코드 정리**:
    *   `clickable`의 `interactionSource`를 `null`로 설정하여 불필요한 메모리 할당을 방지했습니다.
    *   컴포저블 파라미터 순서를 표준 가이드에 맞춰 조정했습니다.
    *   Preview 코드 내의 불필요한 여백 및 스타일 적용 방식을 수정했습니다.
`PrezelAccordion` 컴포넌트의 내부 구조를 정리하고, 패딩 및 컴포저블 파라미터 설정을 유연하게 수정했습니다.

*   `header` 및 `trailingContent` 파라미터에서 불필요한 `expanded` 상태 전달 제거
*   `contentPadding` 파라미터를 추가하여 헤더의 패딩을 외부에서 조절할 수 있도록 개선
*   `PrezelAccordionDivider` 비공개 컴포저블을 제거하고 `PrezelHorizontalDivider`를 직접 사용하도록 로직 단순화
*   `PrezelAccordionHeader`에 `contentPadding` 적용 및 관련 프리뷰 코드 업데이트
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/PrezelAccordion.kt`:
- Around line 87-97: Add proper accessibility semantics to the accordion header:
update the Row modifier that uses Modifier.clickable(...) to include role =
Role.Button (same pattern as PrezelButton.kt) and add a semantics block
conveying the expanded state (e.g., .semantics { stateDescription = if
(expanded) "expanded" else "collapsed" } or set ToggleableState using
ToggleableState.On/Off depending on your existing boolean named expanded), and
change the Icon's contentDescription to null so it is treated as decorative
(replace the existing non-null string). Ensure you reference the
Row/Modifier.clickable usage, the expanded state variable (expanded or
isExpanded), and the Icon(contentDescription = ...) in your edits.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 051ab7a and 17b9f0c.

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

Comment on lines +87 to +97
Row(
modifier = Modifier
.fillMaxWidth()
.padding(contentPadding)
.defaultMinSize(minHeight = 48.dp)
.clickable(
enabled = enabled,
indication = null,
interactionSource = null,
onClick = onTap,
),
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

🧩 Analysis chain

🏁 Script executed:

cat -n "Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelAccordion.kt" | head -150

Repository: Team-Prezel/Prezel-Android

Length of output: 5927


🏁 Script executed:

# Check if the file exists and get overall structure
wc -l "Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelAccordion.kt"

Repository: Team-Prezel/Prezel-Android

Length of output: 175


🏁 Script executed:

# Look for any existing semantics usage in the file
rg "semantics|contentDescription|role" "Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/PrezelAccordion.kt" -n

Repository: Team-Prezel/Prezel-Android

Length of output: 161


🏁 Script executed:

# Search for semantics usage in other design system components
rg "semantics|stateDescription|Role\\.Button" Prezel/core/designsystem/src/main/java/ -A 2 -B 2

Repository: Team-Prezel/Prezel-Android

Length of output: 3322


🏁 Script executed:

# Look for similar button/toggle components that might have accessibility implementations
fd "\.kt$" Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/ -exec rg -l "clickable|Button" {} \; | head -10

Repository: Team-Prezel/Prezel-Android

Length of output: 278


🏁 Script executed:

# Check if R.string.core_designsystem_accordion_desc exists
rg "core_designsystem_accordion_desc" Prezel/core/designsystem/src/main/res/

Repository: Team-Prezel/Prezel-Android

Length of output: 195


🏁 Script executed:

# Check how PrezelButton implements accessibility semantics
cat -n "Prezel/core/designsystem/src/main/java/com/team/prezel/core/designsystem/component/button/PrezelButton.kt" | grep -A 20 "semantics"

Repository: Team-Prezel/Prezel-Android

Length of output: 2366


🏁 Script executed:

# Check if stateDescription is used anywhere in the codebase
rg "stateDescription" Prezel/core/designsystem/src/main/java/ -B 2 -A 2

Repository: Team-Prezel/Prezel-Android

Length of output: 52


🏁 Script executed:

# Check how clickable handles accessibility elsewhere
rg "clickable.*role|role.*clickable" Prezel/core/designsystem/src/main/java/ -B 3 -A 3

Repository: Team-Prezel/Prezel-Android

Length of output: 52


🏁 Script executed:

# Check if the proposed imports for stateDescription are valid
rg "stateDescription" --type kotlin | head -5

Repository: Team-Prezel/Prezel-Android

Length of output: 52


🏁 Script executed:

# Verify clickable modifier accepts onClickLabel parameter in this Compose version
rg "clickable.*onClickLabel|onClickLabel.*clickable" --type kotlin -B 2 -A 2 | head -20

Repository: Team-Prezel/Prezel-Android

Length of output: 52


🏁 Script executed:

# Check what strings might be needed for state description
cat "Prezel/core/designsystem/src/main/res/values/strings.xml" | grep -i "accordion\|expand\|collapse\|button"

Repository: Team-Prezel/Prezel-Android

Length of output: 138


아코디언의 접근성 시맨틱(역할/상태)이 누락되어 있습니다.

Line 92의 clickable 모디파이어에 role 시맨틱이 없어 보조기기에서 "이것이 버튼"임을 인식하지 못합니다. 또한 확장/축소 상태가 전달되지 않아 현재 상태를 알기 어렵습니다. 아울러 Line 123의 Icon contentDescription = "아코디언 토글"은 헤더의 텍스트와 의미가 중복되므로 아이콘은 장식 처리(null)가 더 안전합니다.

최소한 다음을 적용하세요:

  1. Row 모디파이어에 role = Role.Button 추가 (PrezelButton.kt 패턴 참고)
  2. Icon의 contentDescriptionnull로 변경
  3. 확장/축소 상태를 시맨틱으로 전달하는 방식은 별도 검증 필요
기본 수정안
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.rotate
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.res.painterResource
 import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.semantics.Role
+import androidx.compose.ui.semantics.semantics

@@
 private fun PrezelAccordionHeader(
     enabled: Boolean,
     expanded: Boolean,
@@
     Row(
         modifier = Modifier
             .fillMaxWidth()
             .padding(contentPadding)
             .defaultMinSize(minHeight = 48.dp)
+            .semantics { role = Role.Button }
             .clickable(
                 enabled = enabled,
                 indication = null,
                 interactionSource = null,
                 onClick = onTap,
             ),
@@
     Icon(
         painter = painterResource(PrezelIcons.ChevronDown),
-        contentDescription = stringResource(R.string.core_designsystem_accordion_desc),
+        contentDescription = null,
         modifier = Modifier
             .size(24.dp)
             .rotate(rotation),
         tint = PrezelTheme.colors.iconRegular,
     )
 }

TalkBack에서 "버튼, 아코디언 토글"로 읽히고 Icon 중복 낭독이 없는지 확인해 주세요.

🤖 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/PrezelAccordion.kt`
around lines 87 - 97, Add proper accessibility semantics to the accordion
header: update the Row modifier that uses Modifier.clickable(...) to include
role = Role.Button (same pattern as PrezelButton.kt) and add a semantics block
conveying the expanded state (e.g., .semantics { stateDescription = if
(expanded) "expanded" else "collapsed" } or set ToggleableState using
ToggleableState.On/Off depending on your existing boolean named expanded), and
change the Icon's contentDescription to null so it is treated as decorative
(replace the existing non-null string). Ensure you reference the
Row/Modifier.clickable usage, the expanded state variable (expanded or
isExpanded), and the Icon(contentDescription = ...) in your edits.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ feat 새로운 기능 추가 또는 기존 기능 확장

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PrezelAccordion 구현

2 participants