Skip to content

Comments

Feat/#19 CherrishButtoncomponent 수정#33

Merged
sum130 merged 5 commits intodevelopfrom
feat/#19-buttoncomponent
Jan 12, 2026
Merged

Feat/#19 CherrishButtoncomponent 수정#33
sum130 merged 5 commits intodevelopfrom
feat/#19-buttoncomponent

Conversation

@sum130
Copy link
Contributor

@sum130 sum130 commented Jan 10, 2026

🔗 연결된 이슈

📄 작업 내용

  • Cherrish버튼 컴포넌트
구현 내용 IPhone 13 mini
GIF

💻 주요 코드 설명

struct CherrishButtonStyle: ButtonStyle {
    let state: ButtonState
    let type: CherrishButtonType
    
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .frame(
                width: configuration.isPressed ? type.width * 0.95 : type.width,
                height: configuration.isPressed ? type.height * 0.95 : type.height
            )
            .background(type.backgroundColor(for: state))
            .cornerRadius(
                configuration.isPressed
                ? type.cornerRadius * 0.95
                : type.cornerRadius
        )
    }
}
  • 위와 같이 탭할 때 pressed 되어서 버튼 형태가 바뀌는 방식으로 구현했습니다.
  • state로 normal(비활성상태)랑 active로 상태 나눴습니다.
  • 버튼 타입을 나눠서 각각 색상 및 크기 변경할 수 있게 했습니다.

@coderabbitai
Copy link

coderabbitai bot commented Jan 10, 2026

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

iOS 자산 카탈로그에 cherrishIcon 및 다수의 SVG imageset용 Contents.json 파일들을 추가하고, SwiftUI 기반의 버튼 컴포넌트 CherrishButton(스타일·상태·타입 포함)을 추가합니다.

Changes

코호트 / 파일(s) 설명
Asset Catalog: cherrishIcon
Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/Contents.json, .../check_circular.imageset/Contents.json, .../checkbox_active.imageset/Contents.json, .../checkbox_default.imageset/Contents.json, .../chevron_left.imageset/Contents.json, .../chevron_right.imageset/Contents.json, .../clock.imageset/Contents.json, .../close.imageset/Contents.json, .../deletebox.imageset/Contents.json, .../info.imageset/Contents.json, .../plus.imageset/Contents.json, .../radiobtn_default.imageset/Contents.json, .../radiobtn_selected.imageset/Contents.json, .../return.imageset/Contents.json, .../search.imageset/Contents.json, .../sun.imageset/Contents.json
각 imageset에 대한 Contents.json 파일 추가(각 SVG 파일명, idiom: "universal", Xcode 메타데이터 author/version). 리소스 메타데이터 추가만 이루어짐.
UI 컴포넌트: 버튼
Cherrish-iOS/Cherrish-iOS/Presentation/Global/Components/CherrishButton.swift
CherrishButton 뷰, CherrishButtonStyle, ButtonState, CherrishButtonType 추가. 버튼 타입별 크기·모서리·색상·비활성화 로직 및 스타일링 구현.

Sequence Diagram(s)

(생성 기준 미충족 — 생략)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 분

Possibly related PRs

Suggested labels

Add

Suggested reviewers

  • y-eonee
  • soseoyo12
  • wotjs020708
🚥 Pre-merge checks | ✅ 3 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning PR은 버튼 컴포넌트 기본 구조(next, confirm, save, addEvent 타입)를 구현했으나, 이슈의 To-Do 항목들은 완전히 충족되지 않았습니다. 이슈 #19의 To-Do 체크리스트 항목들(다음 버튼 ×3, 추가 버튼 ×2, 확인 버튼 ×2, 등록하기 버튼 ×2)을 완전히 구현하거나 이슈를 분할하여 관리해주세요.
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 PR 제목이 변경 사항의 주요 내용과 명확하게 관련되어 있으며, CherrishButton 컴포넌트 구현을 명시하고 있습니다.
Description check ✅ Passed PR 설명에서 Cherrish 버튼 컴포넌트 구현, 구현 방식, 상태 관리 등 변경 사항과 관련된 내용을 포함하고 있습니다.
Out of Scope Changes check ✅ Passed PR의 모든 변경 사항(asset catalog 파일들과 CherrishButton 컴포넌트)이 이슈 #19의 버튼 컴포넌트 구현 범위 내에 있습니다.

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

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/#19-buttoncomponent

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2dccca3 and fec5a6d.

📒 Files selected for processing (1)
  • Cherrish-iOS/Cherrish-iOS/Presentation/Global/Components/CherrishButton.swift

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

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

🤖 Fix all issues with AI agents
In
@Cherrish-iOS/Cherrish-iOS/Presentation/Global/Components/CherrishButton.swift:
- Around line 61-86: The extension on CherrishButtonType currently hardcodes
CGFloat sizes in the width, height, and cornerRadius properties which breaks
responsiveness; change these to compute sizes from the environment (e.g., add
width(for screenWidth: CGFloat) and height(for traitCollection:
UITraitCollection or screenScale) methods or return values that reference
DesignSystem.Layout tokens) and replace direct numeric literals for
.next/.save/.confirm/.addEvent with either screen-width based calculations
(percentages or inset-based like screenWidth - x) or constants from a
centralized DesignSystem (e.g.,
DesignSystem.Layout.buttonWidthLarge/Medium/Small and
DesignSystem.CornerRadius.button) so the button scales across devices and
respects Dynamic Type.
- Around line 10-13: The enum ButtonState is currently internal and should be
made explicitly public for reuse in Global Components; update the declaration
for ButtonState to include the public access modifier (e.g., public enum
ButtonState) and, if useful for callers, add protocol conformances such as
Equatable, Hashable, and/or CaseIterable (e.g., public enum ButtonState:
CaseIterable, Equatable { ... }) so the type is accessible and more usable
across modules.
- Around line 15-20: CherrishButtonType is missing explicit access control and
could benefit from CaseIterable for safer reuse; update the enum declaration for
CherrishButtonType to include the public access modifier (e.g., public enum
CherrishButtonType) and, if iteration over cases is needed, conform it to
CaseIterable (public enum CherrishButtonType: CaseIterable) while leaving the
existing cases (next, confirm, save, addEvent) unchanged.
- Line 22: Make the reusable component accessible by adding the public access
modifier to the CherrishButton declaration and its initializer: change struct
CherrishButton to public struct CherrishButton and mark the init(...)
initializer as public (the initializer that takes title: String, type:
CherrishButtonType, state: Binding<ButtonState>, action: @escaping () -> Void).
Ensure any stored properties or related types referenced by the public API
(e.g., CherrishButtonType, ButtonState) are at least internal/public as needed
to avoid access-level conflicts.
- Around line 29-37: Add VoiceOver support to CherrishButton by attaching
accessibility modifiers to the Button in CherrishButton.body: set an
accessibilityLabel (use title/localized), call
CherrishButtonType.accessibilityHint(for: state) for accessibilityHint, add
accessibilityAddTraits(.isButton) and conditionally add .isDisabled trait when
type.isDisabled(for: state) is true. Also implement the suggested extension
method on CherrishButtonType: func accessibilityHint(for state: ButtonState) ->
String that returns localized hints for each case (.next, .confirm, .save,
.addEvent) to be used by the button.
- Around line 41-58: Make CherrishButtonStyle public and add light haptic
feedback when the button is pressed: change the declaration to public struct
CherrishButtonStyle and inside makeBody observe configuration.isPressed (e.g.,
.onChange(of: configuration.isPressed) or equivalent) to call a
UIImpactFeedbackGenerator(style: .light).impactOccurred() when it becomes true;
also add import UIKit at the top so haptics compile. Reference:
CherrishButtonStyle, makeBody, configuration.isPressed.
- Around line 88-120: Add a Color extension that defines the missing static
color properties used by CherrishButtonType (e.g., .red700, .gray0, .gray200,
.gray400, .gray600, .gray700) so the calls in backgroundColor(for:) and
textColor(for:) compile; implement a new extension on Color with static lets
mapping each property to the corresponding asset name (e.g., "red_700",
"gray_0", etc.) and add that file to the project alongside other UI extensions.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 627390e and 9a11966.

⛔ Files ignored due to path filters (15)
  • Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/check_circular.imageset/check_circular.svg is excluded by !**/*.svg
  • Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/checkbox_active.imageset/checkbox_active.svg is excluded by !**/*.svg
  • Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/checkbox_default.imageset/checkbox_default.svg is excluded by !**/*.svg
  • Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/chevron_left.imageset/chevron_left.svg is excluded by !**/*.svg
  • Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/chevron_right.imageset/chevron_right.svg is excluded by !**/*.svg
  • Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/clock.imageset/clock.svg is excluded by !**/*.svg
  • Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/close.imageset/close.svg is excluded by !**/*.svg
  • Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/deletebox.imageset/deletebox.svg is excluded by !**/*.svg
  • Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/info.imageset/info.svg is excluded by !**/*.svg
  • Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/plus.imageset/plus.svg is excluded by !**/*.svg
  • Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/radiobtn_default.imageset/radiobtn_default.svg is excluded by !**/*.svg
  • Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/radiobtn_selected.imageset/radiobtn_selected.svg is excluded by !**/*.svg
  • Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/return.imageset/return.svg is excluded by !**/*.svg
  • Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/search.imageset/search.svg is excluded by !**/*.svg
  • Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/sun.imageset/sun.svg is excluded by !**/*.svg
📒 Files selected for processing (17)
  • Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/Contents.json
  • Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/check_circular.imageset/Contents.json
  • Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/checkbox_active.imageset/Contents.json
  • Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/checkbox_default.imageset/Contents.json
  • Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/chevron_left.imageset/Contents.json
  • Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/chevron_right.imageset/Contents.json
  • Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/clock.imageset/Contents.json
  • Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/close.imageset/Contents.json
  • Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/deletebox.imageset/Contents.json
  • Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/info.imageset/Contents.json
  • Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/plus.imageset/Contents.json
  • Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/radiobtn_default.imageset/Contents.json
  • Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/radiobtn_selected.imageset/Contents.json
  • Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/return.imageset/Contents.json
  • Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/search.imageset/Contents.json
  • Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/sun.imageset/Contents.json
  • Cherrish-iOS/Cherrish-iOS/Presentation/Global/Components/CherrishButton.swift
🧰 Additional context used
🧬 Code graph analysis (1)
Cherrish-iOS/Cherrish-iOS/Presentation/Global/Components/CherrishButton.swift (1)
Cherrish-iOS/Cherrish-iOS/Presentation/Global/Extension/Font+.swift (1)
  • typography (52-56)
🔇 Additional comments (16)
Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/sun.imageset/Contents.json (1)

1-12: 올바른 에셋 카탈로그 구조입니다.

표준 형식을 준수하며 문제없습니다.

Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/check_circular.imageset/Contents.json (1)

1-12: 올바른 에셋 카탈로그 구조입니다.

표준 형식을 준수하며 문제없습니다.

Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/chevron_left.imageset/Contents.json (1)

1-12: 올바른 에셋 카탈로그 구조입니다.

표준 형식을 준수하며 문제없습니다.

Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/deletebox.imageset/Contents.json (1)

1-12: 올바른 에셋 카탈로그 구조입니다.

표준 형식을 준수하며 문제없습니다.

Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/radiobtn_selected.imageset/Contents.json (1)

1-12: 에셋 카탈로그 구조가 올바릅니다.

JSON 구조가 유효하며 Xcode 에셋 카탈로그의 표준 형식을 따릅니다. 참조된 SVG 파일(radiobtn_selected.svg)이 디렉토리에 실제로 존재합니다.

Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/return.imageset/Contents.json (1)

1-12: 애셋 카탈로그 구조가 정상입니다.

return 아이콘에 대한 표준 애셋 카탈로그 정의가 올바르게 작성되었습니다.

Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/Contents.json (1)

1-6: 루트 레벨 애셋 카탈로그 메타데이터가 올바릅니다.

cherrishIcon 폴더의 루트 레벨 Contents.json 파일로, 표준 구조를 따르고 있습니다.

Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/chevron_right.imageset/Contents.json (1)

1-12: 애셋 카탈로그 구조가 정상입니다.

chevron_right 아이콘에 대한 표준 애셋 카탈로그 정의가 올바르게 작성되었습니다.

Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/search.imageset/Contents.json (1)

1-12: 애셋 카탈로그 구조가 올바르게 구성되었습니다.

JSON 구조와 메타데이터가 Xcode 규칙을 따르고 있으며, 참조된 search.svg 파일이 올바른 위치에 존재합니다. SVG 형식 사용은 해상도 독립적인 아이콘에 적합합니다.

Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/checkbox_active.imageset/Contents.json (1)

1-12: 애셋 카탈로그 구조가 올바르게 작성되었습니다.

checkbox_active 이미지셋의 Contents.json이 표준 Xcode 애셋 카탈로그 형식을 따르고 있으며, 참조되는 checkbox_active.svg 파일이 실제로 존재합니다. 모든 15개의 cherrishIcon SVG 애셋이 올바르게 배치되어 있습니다.

Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/close.imageset/Contents.json (1)

1-12: LGTM! 에셋 구조가 올바릅니다.

close 아이콘에 대한 에셋 카탈로그가 표준 형식을 따르고 있습니다.

Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/info.imageset/Contents.json (1)

1-12: LGTM! 표준 구조를 따릅니다.

info 아이콘 에셋이 올바르게 정의되어 있습니다.

Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/radiobtn_default.imageset/Contents.json (1)

1-12: LGTM! 라디오 버튼 에셋이 올바르게 구성되었습니다.

radiobtn_default 아이콘의 에셋 카탈로그 정의가 표준을 따르고 있습니다.

Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/checkbox_default.imageset/Contents.json (1)

1-12: LGTM! 체크박스 에셋이 올바르게 정의되었습니다.

checkbox_default 아이콘의 에셋 카탈로그가 표준 형식을 따르고 있습니다.

Cherrish-iOS/Cherrish-iOS/Assets.xcassets/cherrishIcon/clock.imageset/Contents.json (1)

1-12: 구조 및 파일 모두 올바르게 구성되어 있습니다.

clock 아이콘에 대한 에셋 카탈로그 정의가 표준 구조를 따르고 있으며, clock.svg 파일이 올바른 위치에 존재합니다. SVG 형식과 universal idiom 설정이 적절합니다.

현재 iOS 배포 타겟(16.6 이상)이 SVG asset catalog 지원 요구사항(iOS 16.0 이상)을 충족하므로 문제가 없습니다.

Cherrish-iOS/Cherrish-iOS/Presentation/Global/Components/CherrishButton.swift (1)

26-27: state Binding의 사용 의도를 명확히 하세요.

@Binding var state가 선언되어 있지만, 버튼 내부에서 이 상태를 변경하지 않습니다. 상태 변경이 외부에서만 이루어지는 것이 의도된 설계인지 확인이 필요합니다. 만약 버튼이 자체적으로 상태를 토글해야 한다면 로직 추가가 필요합니다.

현재 설계가 의도된 것인지, 아니면 버튼이 탭될 때 상태를 자동으로 변경해야 하는지 확인해주세요. 만약 후자라면 다음과 같이 수정할 수 있습니다:

var body: some View {
    Button(action: {
        // 상태 토글 로직 추가
        if type == .next && state == .active {
            state = .normal
        }
        action()
    }) {
        Text(title)
            .typography(.title2_sb_16)
            .foregroundStyle(type.textColor(for: state))
    }
    .buttonStyle(CherrishButtonStyle(state: state, type: type))
    .disabled(type.isDisabled(for: state))
}

Comment on lines +15 to +20
enum CherrishButtonType {
case next
case confirm
case save
case addEvent
}
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

접근 제어 수정자 추가를 고려하세요.

재사용 가능한 컴포넌트의 일부이므로 CherrishButtonType enum에도 명시적인 public 접근 제어 수정자를 추가하세요. 타입 안전성을 위해 CaseIterable 프로토콜 준수도 고려해볼 수 있습니다.

♻️ 제안하는 개선사항
-enum CherrishButtonType {
+public enum CherrishButtonType: CaseIterable {
     case next
     case confirm
     case save
     case addEvent
 }
🤖 Prompt for AI Agents
In
@Cherrish-iOS/Cherrish-iOS/Presentation/Global/Components/CherrishButton.swift
around lines 15 - 20, CherrishButtonType is missing explicit access control and
could benefit from CaseIterable for safer reuse; update the enum declaration for
CherrishButtonType to include the public access modifier (e.g., public enum
CherrishButtonType) and, if iteration over cases is needed, conform it to
CaseIterable (public enum CherrishButtonType: CaseIterable) while leaving the
existing cases (next, confirm, save, addEvent) unchanged.

case addEvent
}

struct CherrishButton: View {
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

접근 제어 수정자를 추가하세요.

Global Components로 제공되는 재사용 가능한 컴포넌트이므로 CherrishButton struct에 public 접근 제어 수정자가 필요합니다.

♻️ 제안하는 개선사항
-struct CherrishButton: View {
+public struct CherrishButton: View {

초기화 메서드도 public으로 명시해야 합니다:

public init(title: String, type: CherrishButtonType, state: Binding<ButtonState>, action: @escaping () -> Void) {
    self.title = title
    self.type = type
    self._state = state
    self.action = action
}
🤖 Prompt for AI Agents
In
@Cherrish-iOS/Cherrish-iOS/Presentation/Global/Components/CherrishButton.swift
at line 22, Make the reusable component accessible by adding the public access
modifier to the CherrishButton declaration and its initializer: change struct
CherrishButton to public struct CherrishButton and mark the init(...)
initializer as public (the initializer that takes title: String, type:
CherrishButtonType, state: Binding<ButtonState>, action: @escaping () -> Void).
Ensure any stored properties or related types referenced by the public API
(e.g., CherrishButtonType, ButtonState) are at least internal/public as needed
to avoid access-level conflicts.

Comment on lines 41 to 58
struct CherrishButtonStyle: ButtonStyle {
let state: ButtonState
let type: CherrishButtonType

func makeBody(configuration: Configuration) -> some View {
configuration.label
.frame(
width: configuration.isPressed ? type.width * 0.95 : type.width,
height: configuration.isPressed ? type.height * 0.95 : type.height
)
.background(type.backgroundColor(for: state))
.cornerRadius(
configuration.isPressed
? type.cornerRadius * 0.95
: type.cornerRadius
)
}
}
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

접근 제어 수정자를 추가하고 햅틱 피드백을 고려하세요.

CherrishButtonStylepublic 접근 제어 수정자가 필요합니다. 또한 더 나은 사용자 경험을 위해 버튼을 눌렀을 때 햅틱 피드백 추가를 고려해보세요.

♻️ 제안하는 개선사항
-struct CherrishButtonStyle: ButtonStyle {
+public struct CherrishButtonStyle: ButtonStyle {
     let state: ButtonState
     let type: CherrishButtonType
     
     func makeBody(configuration: Configuration) -> some View {
         configuration.label
             .frame(
                 width: configuration.isPressed ? type.width * 0.95 : type.width,
                 height: configuration.isPressed ? type.height * 0.95 : type.height
             )
             .background(type.backgroundColor(for: state))
             .cornerRadius(
                 configuration.isPressed
                 ? type.cornerRadius * 0.95
                 : type.cornerRadius
         )
+        .onChange(of: configuration.isPressed) { oldValue, newValue in
+            if newValue {
+                let generator = UIImpactFeedbackGenerator(style: .light)
+                generator.impactOccurred()
+            }
+        }
     }
 }
🤖 Prompt for AI Agents
In
@Cherrish-iOS/Cherrish-iOS/Presentation/Global/Components/CherrishButton.swift
around lines 41 - 58, Make CherrishButtonStyle public and add light haptic
feedback when the button is pressed: change the declaration to public struct
CherrishButtonStyle and inside makeBody observe configuration.isPressed (e.g.,
.onChange(of: configuration.isPressed) or equivalent) to call a
UIImpactFeedbackGenerator(style: .light).impactOccurred() when it becomes true;
also add import UIKit at the top so haptics compile. Reference:
CherrishButtonStyle, makeBody, configuration.isPressed.

Comment on lines 61 to 86
extension CherrishButtonType {

var width: CGFloat {
switch self {
case .next: return 326
case .confirm: return 126
case .save: return 278
case .addEvent: return 196
}
}

var height: CGFloat {
switch self {
case .save: return 44
default:
return 50
}
}

var cornerRadius: CGFloat {
switch self {
case .save: return 10
default: return 12
}
}
}
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

하드코딩된 치수 값의 확장성을 고려하세요.

고정된 CGFloat 값들은 다양한 디바이스 크기와 Dynamic Type에 대응하지 못합니다. 디자인 시스템을 통한 상대적 크기 또는 화면 너비 기반 계산을 고려해보세요.

♻️ 더 확장 가능한 접근 방식 제안

화면 너비를 기준으로 상대적 크기를 사용하는 방법:

extension CherrishButtonType {
    
    func width(for screenWidth: CGFloat) -> CGFloat {
        switch self {
        case .next: return screenWidth - 48  // 좌우 패딩 24
        case .confirm: return 126
        case .save: return screenWidth * 0.75
        case .addEvent: return 196
        }
    }
    
    // 또는 디자인 토큰 시스템 사용:
    var width: CGFloat {
        switch self {
        case .next: return DesignSystem.Layout.buttonWidthLarge
        case .confirm: return DesignSystem.Layout.buttonWidthSmall
        case .save: return DesignSystem.Layout.buttonWidthMedium
        case .addEvent: return DesignSystem.Layout.buttonWidthCompact
        }
    }
}

이렇게 하면 다양한 디바이스와 화면 크기에 더 잘 대응할 수 있습니다.

🤖 Prompt for AI Agents
In
@Cherrish-iOS/Cherrish-iOS/Presentation/Global/Components/CherrishButton.swift
around lines 61 - 86, The extension on CherrishButtonType currently hardcodes
CGFloat sizes in the width, height, and cornerRadius properties which breaks
responsiveness; change these to compute sizes from the environment (e.g., add
width(for screenWidth: CGFloat) and height(for traitCollection:
UITraitCollection or screenScale) methods or return values that reference
DesignSystem.Layout tokens) and replace direct numeric literals for
.next/.save/.confirm/.addEvent with either screen-width based calculations
(percentages or inset-based like screenWidth - x) or constants from a
centralized DesignSystem (e.g.,
DesignSystem.Layout.buttonWidthLarge/Medium/Small and
DesignSystem.CornerRadius.button) so the button scales across devices and
respects Dynamic Type.

Comment on lines 88 to 120
extension CherrishButtonType {

func backgroundColor(for state: ButtonState) -> Color {
switch self {
case .next:
return state == .active ? .red700 : .gray200
case .confirm, .save:
return .red700
case .addEvent:
return .gray400
}
}

func textColor(for state: ButtonState) -> Color {
switch self {
case .next:
return state == .active ? .gray0 : .gray600
case .confirm, .save:
return .gray0
case .addEvent:
return .gray700
}
}

func isDisabled(for state: ButtonState) -> Bool {
switch self {
case .next:
return state == .normal
default:
return false
}
}
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for Color extension definitions
echo "=== Searching for Color extensions ==="
rg -n "extension Color" --type swift -A 15

echo -e "\n=== Searching for specific color definitions ==="
rg -n "(red700|gray200|gray0|gray600|gray400|gray700)" --type swift -B 2 -A 2

echo -e "\n=== Searching for ButtonState definition ==="
rg -n "enum ButtonState" --type swift -A 10

echo -e "\n=== Checking if CherrishButton.swift has documentation ==="
rg -n "///" cherrish-ios/Cherrish-iOS/Presentation/Global/Components/CherrishButton.swift || echo "No documentation comments found"

Repository: TEAM-Cherrish/Cherrish-iOS

Length of output: 3383


🏁 Script executed:

#!/bin/bash
# More comprehensive search for color definitions

echo "=== Search for Color-related files ==="
fd "Color" --type f --extension swift | head -20

echo -e "\n=== Search for 'red700' definition anywhere ==="
rg -n "red700" --type swift -B 5 -A 1

echo -e "\n=== Search for Color assignments/definitions ==="
rg -n "\.red|\.gray" --type swift -B 2 -A 2 | head -50

echo -e "\n=== Check for DesignSystem or Token files ==="
fd -e swift | xargs grep -l "DesignSystem\|Token\|Color" | head -10

echo -e "\n=== List all files in Presentation/Global ==="
fd --type f --extension swift "Presentation/Global" | head -20

Repository: TEAM-Cherrish/Cherrish-iOS

Length of output: 3300


🏁 Script executed:

#!/bin/bash
# Broader search for color definitions

echo "=== List repository structure ==="
find . -type f -name "*.swift" | grep -i color | head -20

echo -e "\n=== Search for Color definitions across all files ==="
rg -n "static.*red700|let.*red700|var.*red700" -A 2 -B 2

echo -e "\n=== Search for extension Color in all content ==="
rg -n "extension Color" -A 20

echo -e "\n=== Look for imports in CherrishButton.swift ==="
head -30 Cherrish-iOS/Cherrish-iOS/Presentation/Global/Components/CherrishButton.swift

echo -e "\n=== Search for where Color comes from ==="
rg -n "import.*Color|from.*Color" --type swift

echo -e "\n=== Find all Color usage patterns ==="
rg -n "Color\." --type swift | head -30

Repository: TEAM-Cherrish/Cherrish-iOS

Length of output: 810


🏁 Script executed:

#!/bin/bash
# Final comprehensive search

echo "=== List all Swift files to understand structure ==="
find . -name "*.swift" -type f 2>/dev/null | head -30

echo -e "\n=== Search in all Swift files for Color extension ==="
find . -name "*.swift" -type f -exec grep -l "extension Color" {} \;

echo -e "\n=== Grep all files for 'red700' ==="
grep -r "red700" . --include="*.swift" 2>/dev/null | head -20

echo -e "\n=== Check if Presentation/Global/Colors or similar exists ==="
find . -type d -name "*[Cc]olor*" 2>/dev/null

echo -e "\n=== Look for any xcassets or color assets ==="
find . -type d -name "*.xcassets" 2>/dev/null

echo -e "\n=== Search entire codebase for Color with + or static ==="
grep -r "Color.*+\|Color.*static" . --include="*.swift" 2>/dev/null | head -20

Repository: TEAM-Cherrish/Cherrish-iOS

Length of output: 3329


🏁 Script executed:

#!/bin/bash
# Check Font+ pattern and confirm Color extension is missing

echo "=== Check Font+ extension pattern ==="
cat ./Cherrish-iOS/Cherrish-iOS/Presentation/Global/Extension/Font+.swift

echo -e "\n=== Look for Color extension file ==="
find . -name "*Color*" -type f | grep -i swift

echo -e "\n=== Check Extension directory for all files ==="
ls -la ./Cherrish-iOS/Cherrish-iOS/Presentation/Global/Extension/

echo -e "\n=== Search for Color+ or similar ==="
find . -name "*olor*" -type f 2>/dev/null | grep -v xcassets

Repository: TEAM-Cherrish/Cherrish-iOS

Length of output: 2635


Color 확장이 누락되어 컴파일 오류가 발생합니다.

Assets.xcassets에 색상 자산(red_700.colorset, gray_0.colorset 등)이 정의되어 있지만, 코드에서 사용하는 .red700, .gray0 등의 Color 확장이 정의되지 않았습니다. Font+ 확장과 같은 패턴으로 Color 확장을 추가해야 합니다:

extension Color {
    static let red700 = Color("red_700")
    static let gray0 = Color("gray_0")
    static let gray200 = Color("gray_200")
    static let gray400 = Color("gray_400")
    static let gray600 = Color("gray_600")
    static let gray700 = Color("gray_700")
}

Presentation/Global/Extension/ 디렉토리에 Color+ 파일을 추가하여 구현하세요.

🤖 Prompt for AI Agents
In
@Cherrish-iOS/Cherrish-iOS/Presentation/Global/Components/CherrishButton.swift
around lines 88 - 120, Add a Color extension that defines the missing static
color properties used by CherrishButtonType (e.g., .red700, .gray0, .gray200,
.gray400, .gray600, .gray700) so the calls in backgroundColor(for:) and
textColor(for:) compile; implement a new extension on Color with static lets
mapping each property to the corresponding asset name (e.g., "red_700",
"gray_0", etc.) and add that file to the project alongside other UI extensions.

@y-eonee y-eonee requested review from a team, soseoyo12, wotjs020708 and y-eonee and removed request for a team January 10, 2026 07:58
@y-eonee y-eonee added 수민🐶 Feature 새로운 기능 구현 및 API 연결 labels Jan 10, 2026
Copy link
Contributor

@soseoyo12 soseoyo12 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

@y-eonee y-eonee left a comment

Choose a reason for hiding this comment

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

좋아요!! 훨씬 좋은 컴포넌트가 되었습니다 굿 ㅎㅎ

}
}

extension CherrishButtonType {
Copy link
Contributor

Choose a reason for hiding this comment

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

이거 굳이 익스텐션 나눈 이유가 있나요 ?! 한번에 써도 될것 같아요

Copy link

@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: 4

🤖 Fix all issues with AI agents
In
@Cherrish-iOS/Cherrish-iOS/Presentation/Global/Components/CherrishButton.swift:
- Around line 63-70: The fixed-width switch in var width (inside
CherrishButton.swift) uses hardcoded values for cases .next, .confirm, .save,
.addEvent which won’t adapt to different screen sizes or Dynamic Type; change
the implementation to compute widths relative to available space (e.g., use
UIScreen.main.bounds.width or, preferably, pass a parent width via
GeometryReader/parent view and calculate widths as screenWidth minus desired
horizontal margins for cases like .next and .save while keeping small controls
like .confirm/.addEvent either a fixed min/max or a percentage); update the var
width logic to reference the calculated screenWidth and apply safe min/max
constraints so buttons remain accessible on all devices.
- Around line 10-13: Rename the enum ButtonState to CherrishButtonState to avoid
naming collisions; update all references/usages (e.g., the declaration "enum
ButtonState" and every place that types/constructs or switches on ButtonState)
to use CherrishButtonState and adjust any associated cases or imports
accordingly to maintain compilation and clarity.
- Around line 29-37: The Button in CherrishButton's body is missing VoiceOver
support; add accessibility metadata on the Button (the var body view) by
providing an accessibilityLabel derived from the title (or a localized label),
add an accessibilityHint when the button is disabled (use type.isDisabled(for:
state) to choose the hint text), and set appropriate traits (e.g.,
.accessibilityAddTraits(.isButton) and .accessibilityAddTraits(.isDisabled) when
disabled) so VoiceOver announces state; update the Button view (the same Button
wrapped with .buttonStyle(CherrishButtonStyle(...))) to include these
accessibility modifiers.
- Around line 45-57: In makeBody(configuration:) replace the deprecated
.cornerRadius(...) call with .clipShape(RoundedRectangle(cornerRadius: ...))
using the same corner radius expression (configuration.isPressed ?
type.cornerRadius * 0.95 : type.cornerRadius) and add an explicit animation on
the press state (e.g., .animation(.easeInOut(duration: 0.1), value:
configuration.isPressed)) so the size and corner radius transitions are
animated; update the chain on configuration.label inside the CherrishButton
style to use clipShape(RoundedRectangle(...)) and the animation modifier
referencing configuration.isPressed.
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9a11966 and 2dccca3.

📒 Files selected for processing (1)
  • Cherrish-iOS/Cherrish-iOS/Presentation/Global/Components/CherrishButton.swift
🧰 Additional context used
🧬 Code graph analysis (1)
Cherrish-iOS/Cherrish-iOS/Presentation/Global/Components/CherrishButton.swift (1)
Cherrish-iOS/Cherrish-iOS/Presentation/Global/Extension/Font+.swift (1)
  • typography (52-56)
🔇 Additional comments (2)
Cherrish-iOS/Cherrish-iOS/Presentation/Global/Components/CherrishButton.swift (2)

15-20: LGTM!

버튼 타입 정의가 명확하고 PR 목표(다음, 확인, 등록하기, 일정 추가 버튼)와 잘 일치합니다.


87-96: confirm, save, addEvent 타입에서 state 파라미터가 사용되지 않습니다.

이 타입들의 배경색과 텍스트 색상은 상태와 무관하게 고정되어 있습니다. 의도된 동작이라면 괜찮지만, 향후 상태 기반 스타일링이 필요할 경우 이 점을 고려해 주세요.

Comment on lines +10 to +13
enum ButtonState {
case normal
case active
}
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

ButtonState 네이밍이 너무 일반적입니다.

다른 모듈과의 충돌을 방지하고 일관성을 위해 CherrishButtonState로 이름을 변경하는 것을 고려해 주세요.

♻️ 제안된 수정
-enum ButtonState {
+enum CherrishButtonState {
     case normal
     case active
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
enum ButtonState {
case normal
case active
}
enum CherrishButtonState {
case normal
case active
}
🤖 Prompt for AI Agents
In
@Cherrish-iOS/Cherrish-iOS/Presentation/Global/Components/CherrishButton.swift
around lines 10 - 13, Rename the enum ButtonState to CherrishButtonState to
avoid naming collisions; update all references/usages (e.g., the declaration
"enum ButtonState" and every place that types/constructs or switches on
ButtonState) to use CherrishButtonState and adjust any associated cases or
imports accordingly to maintain compilation and clarity.

Comment on lines +29 to +37
var body: some View {
Button(action: action) {
Text(title)
.typography(.title2_sb_16)
.foregroundStyle(type.textColor(for: state))
}
.buttonStyle(CherrishButtonStyle(state: state, type: type))
.disabled(type.isDisabled(for: state))
}
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

접근성(Accessibility) 지원이 누락되었습니다.

VoiceOver 사용자를 위해 접근성 레이블을 추가하는 것이 좋습니다. 버튼이 비활성화된 경우 힌트도 제공하면 더 좋습니다.

♻️ 제안된 수정
     var body: some View {
         Button(action: action) {
             Text(title)
                 .typography(.title2_sb_16)
                 .foregroundStyle(type.textColor(for: state))
         }
         .buttonStyle(CherrishButtonStyle(state: state, type: type))
         .disabled(type.isDisabled(for: state))
+        .accessibilityLabel(title)
+        .accessibilityHint(type.isDisabled(for: state) ? "비활성화됨" : "")
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
var body: some View {
Button(action: action) {
Text(title)
.typography(.title2_sb_16)
.foregroundStyle(type.textColor(for: state))
}
.buttonStyle(CherrishButtonStyle(state: state, type: type))
.disabled(type.isDisabled(for: state))
}
var body: some View {
Button(action: action) {
Text(title)
.typography(.title2_sb_16)
.foregroundStyle(type.textColor(for: state))
}
.buttonStyle(CherrishButtonStyle(state: state, type: type))
.disabled(type.isDisabled(for: state))
.accessibilityLabel(title)
.accessibilityHint(type.isDisabled(for: state) ? "비활성화됨" : "")
}
🤖 Prompt for AI Agents
In
@Cherrish-iOS/Cherrish-iOS/Presentation/Global/Components/CherrishButton.swift
around lines 29 - 37, The Button in CherrishButton's body is missing VoiceOver
support; add accessibility metadata on the Button (the var body view) by
providing an accessibilityLabel derived from the title (or a localized label),
add an accessibilityHint when the button is disabled (use type.isDisabled(for:
state) to choose the hint text), and set appropriate traits (e.g.,
.accessibilityAddTraits(.isButton) and .accessibilityAddTraits(.isDisabled) when
disabled) so VoiceOver announces state; update the Button view (the same Button
wrapped with .buttonStyle(CherrishButtonStyle(...))) to include these
accessibility modifiers.

Comment on lines 45 to 57
func makeBody(configuration: Configuration) -> some View {
configuration.label
.frame(
width: configuration.isPressed ? type.width * 0.95 : type.width,
height: configuration.isPressed ? type.height * 0.95 : type.height
)
.background(type.backgroundColor(for: state))
.cornerRadius(
configuration.isPressed
? type.cornerRadius * 0.95
: type.cornerRadius
)
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

🌐 Web query:

SwiftUI cornerRadius deprecated iOS 17 clipShape replacement

💡 Result:

Short answer: cornerRadius was deprecated in iOS 17 (Xcode 15). Use clipShape (or fill/background APIs) with a RoundedRectangle (or new UnevenRoundedRectangle / .rect shorthands) instead.

Examples:

  • Simple replacement:
    Color.blue
    .frame(width:200, height:120)
    .clipShape(RoundedRectangle(cornerRadius: 16))
  • With overlay border:
    .clipShape(RoundedRectangle(cornerRadius:16))
    .overlay(RoundedRectangle(cornerRadius:16).stroke(Color.gray, lineWidth:2))
  • Per-corner radii (iOS 17+):
    .clipShape(.rect(topLeadingRadius:24, bottomTrailingRadius:60)) // UnevenRoundedRectangle/.rect

Notes: Apple’s implementation shows cornerRadius forwards to clipShape/fill; you can also use fill/in background to avoid double-shaping when drawing borders. [1][2][3][4]

Sources:
[1] SwiftUI interface gist showing deprecation and forwarding to clipShape. (gist.github.com)
[2] Blog posts showing replacement examples. (lukaspistrol.com)
[3] Practical notes on borders/overlay and iOS17 fill APIs. (stackoverflow.com)
[4] UnevenRoundedRectangle / .rect per-corner example (iOS 17+). (alexpaul.dev)

Citations:


.cornerRadius() 수정자는 iOS 17부터 deprecated 되었습니다.

.clipShape(RoundedRectangle(cornerRadius:))를 사용하세요. 추가적으로 부드러운 애니메이션을 위해 .animation() 수정자를 추가하는 것이 좋습니다.

♻️ 제안된 수정
     func makeBody(configuration: Configuration) -> some View {
         configuration.label
             .frame(
                 width: configuration.isPressed ? type.width * 0.95 : type.width,
                 height: configuration.isPressed ? type.height * 0.95 : type.height
             )
             .background(type.backgroundColor(for: state))
-            .cornerRadius(
-                configuration.isPressed
-                ? type.cornerRadius * 0.95
-                : type.cornerRadius
-        )
+            .clipShape(
+                RoundedRectangle(
+                    cornerRadius: configuration.isPressed
+                        ? type.cornerRadius * 0.95
+                        : type.cornerRadius
+                )
+            )
+            .animation(.easeInOut(duration: 0.1), value: configuration.isPressed)
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func makeBody(configuration: Configuration) -> some View {
configuration.label
.frame(
width: configuration.isPressed ? type.width * 0.95 : type.width,
height: configuration.isPressed ? type.height * 0.95 : type.height
)
.background(type.backgroundColor(for: state))
.cornerRadius(
configuration.isPressed
? type.cornerRadius * 0.95
: type.cornerRadius
)
}
func makeBody(configuration: Configuration) -> some View {
configuration.label
.frame(
width: configuration.isPressed ? type.width * 0.95 : type.width,
height: configuration.isPressed ? type.height * 0.95 : type.height
)
.background(type.backgroundColor(for: state))
.clipShape(
RoundedRectangle(
cornerRadius: configuration.isPressed
? type.cornerRadius * 0.95
: type.cornerRadius
)
)
.animation(.easeInOut(duration: 0.1), value: configuration.isPressed)
}
🤖 Prompt for AI Agents
In
@Cherrish-iOS/Cherrish-iOS/Presentation/Global/Components/CherrishButton.swift
around lines 45 - 57, In makeBody(configuration:) replace the deprecated
.cornerRadius(...) call with .clipShape(RoundedRectangle(cornerRadius: ...))
using the same corner radius expression (configuration.isPressed ?
type.cornerRadius * 0.95 : type.cornerRadius) and add an explicit animation on
the press state (e.g., .animation(.easeInOut(duration: 0.1), value:
configuration.isPressed)) so the size and corner radius transitions are
animated; update the chain on configuration.label inside the CherrishButton
style to use clipShape(RoundedRectangle(...)) and the animation modifier
referencing configuration.isPressed.

Copy link
Contributor

Choose a reason for hiding this comment

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

요내용 확인하면 좋을 거 같아욤

Comment on lines +63 to +70
var width: CGFloat {
switch self {
case .next: return 326
case .confirm: return 126
case .save: return 278
case .addEvent: return 196
}
}
Copy link

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

고정 너비 값은 다양한 화면 크기에 적응하지 못할 수 있습니다.

하드코딩된 너비 값(326, 126, 278, 196)은 다른 기기나 Dynamic Type 설정에서 문제가 될 수 있습니다. 유연한 레이아웃이나 상대적인 크기를 고려해 보세요.

♻️ 예시: 화면 너비 기반 상대적 크기
var width: CGFloat {
    let screenWidth = UIScreen.main.bounds.width
    switch self {
    case .next: return screenWidth - 48  // 양쪽 24pt 마진
    case .confirm: return 126
    case .save: return screenWidth - 96
    case .addEvent: return 196
    }
}
🤖 Prompt for AI Agents
In
@Cherrish-iOS/Cherrish-iOS/Presentation/Global/Components/CherrishButton.swift
around lines 63 - 70, The fixed-width switch in var width (inside
CherrishButton.swift) uses hardcoded values for cases .next, .confirm, .save,
.addEvent which won’t adapt to different screen sizes or Dynamic Type; change
the implementation to compute widths relative to available space (e.g., use
UIScreen.main.bounds.width or, preferably, pass a parent width via
GeometryReader/parent view and calculate widths as screenWidth minus desired
horizontal margins for cases like .next and .save while keeping small controls
like .confirm/.addEvent either a fixed min/max or a percentage); update the var
width logic to reference the calculated screenWidth and apply safe min/max
constraints so buttons remain accessible on all devices.

Copy link
Contributor

@wotjs020708 wotjs020708 left a comment

Choose a reason for hiding this comment

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

enum 활용을 잘하시네욤

Comment on lines 45 to 57
func makeBody(configuration: Configuration) -> some View {
configuration.label
.frame(
width: configuration.isPressed ? type.width * 0.95 : type.width,
height: configuration.isPressed ? type.height * 0.95 : type.height
)
.background(type.backgroundColor(for: state))
.cornerRadius(
configuration.isPressed
? type.cornerRadius * 0.95
: type.cornerRadius
)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

요내용 확인하면 좋을 거 같아욤

@sum130 sum130 merged commit c4f8a47 into develop Jan 12, 2026
1 check was pending
@sum130 sum130 deleted the feat/#19-buttoncomponent branch January 12, 2026 06:25
Kimgyuilli pushed a commit that referenced this pull request Jan 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feature 새로운 기능 구현 및 API 연결 수민🐶

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feat] 버튼 컴포넌트

4 participants