refactor: Blueprint 프리뷰 옵션 행 공용 컴포넌트화#517
Conversation
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
Walkthrough
ChangesPreviewLayout 인프라 및 프로젝트/라우팅 갱신
콘텐츠·스타일 프리뷰 전환
선택·입력·내비게이션 프리뷰 전환
Montage API와 메타데이터 정리
추정 코드 리뷰 노력🎯 4 (Complex) | ⏱️ ~60 minutes 연관 가능성이 있는 PR
제안된 리뷰어
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 12
Note
Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
Sources/Blueprint/Sources/Scene/Previews/ColorPreview.swift (1)
27-45: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win원자 색상으로 바뀔 때 체커 상태도 함께 초기화해 주세요.
Line 37처럼 버튼만 비활성화하면, semantic/all에서 켜 둔
showTransparentChecker가 그대로 남아서 atomic 섹션에도 체커가 계속 렌더링됩니다. 세그먼트 선택이.atomic으로 바뀌는 순간showTransparentChecker = false까지 같이 처리해야 옵션 상태와 실제 프리뷰가 맞습니다.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/Blueprint/Sources/Scene/Previews/ColorPreview.swift` around lines 27 - 45, When the selected color type changes to .atomic in ColorPreview, the transparent checker state must be reset as well. Update the selection handling around selectedColorTypeIndex so that switching to the atomic case also sets showTransparentChecker to false, instead of only disabling the checkerboard Button. Use the existing ColorPreview, selectedColorTypeIndex, showTransparentChecker, and ColorType.allCases references to locate the logic and keep the preview state aligned with the active segment.
🟡 Minor comments (12)
Sources/Montage/1 Components/5 Loading/Skeleton.swift-222-226 (1)
222-226: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win라인 수 계산에
round대신floor를 사용해 주세요.현재 높이가 1.5줄보다 조금만 커도 2줄로 반올림되어 컨테이너보다 큰 스켈레톤이 그려질 수 있습니다.
수정 제안
- : max(1, Int(round(proxy.size.height / scaledLineHeight))) + : max(1, Int(floor(proxy.size.height / scaledLineHeight)))🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/Montage/1` Components/5 Loading/Skeleton.swift around lines 222 - 226, The line count calculation in Skeleton’s layout logic should not round up, because `round` can produce an extra line and make the skeleton taller than its container. Update the `effectiveLineCount` computation in the sizing path that uses `proxy.size.height` and `scaledLineHeight` to use `floor` instead of `round`, while keeping the `kind.lineNumber` override and the `max(1, ...)` minimum intact.Sources/Blueprint/Sources/Scene/Previews/TextFieldPreview.swift-143-199 (1)
143-199: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
autoComplete토글이 현재 제안 상태를 즉시 반영하지 않습니다.제안 계산이
text변경에만 묶여 있어서, 이미 제안이 떠 있는 상태에서 Line 214의 토글을 끄면autoCompletionDataSource가 남고, 반대로 non-empty 텍스트에서 켜도 바로 다시 계산되지 않습니다.usingSuggestions변경에도 datasource를 nil/재계산하도록 동기화해야 옵션과 화면이 맞습니다.Also applies to: 213-219
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/Blueprint/Sources/Scene/Previews/TextFieldPreview.swift` around lines 143 - 199, The suggestion datasource is only refreshed from the text change handler, so toggling usingSuggestions does not immediately clear or rebuild autoCompletionDataSource. Update the TextFieldPreview logic around the .onChange(of: text) flow to also observe usingSuggestions and synchronize the datasource whenever the toggle changes, clearing it when disabled and recalculating it when enabled with non-empty text. Use the existing autoCompletionDataSource, usingSuggestions, and candidates logic so the preview state always matches the toggle.Sources/Blueprint/Sources/Scene/Previews/LoadingPreview.swift-13-18 (1)
13-18: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win변경된
@State는private로 제한해 주세요.이 상태들은 뷰 내부 구현 세부사항인데 현재
private_swiftui_state경고가 나고 있습니다. 외부 노출을 막아두는 쪽이 맞습니다.제안된 수정
- `@State` var typeOption: TypeOption = .circular + `@State` private var typeOption: TypeOption = .circular // .clear이면 기본 색(circular spinner 기본 색)을 쓴다. - `@State` var color: SwiftUI.Color = .clear + `@State` private var color: SwiftUI.Color = .clear // .clear이면 dimmer를 적용하지 않는다. - `@State` var dimmerColor: SwiftUI.Color = .semantic(.materialDimmer) - `@State` var timeout: TimeInterval = 3 + `@State` private var dimmerColor: SwiftUI.Color = .semantic(.materialDimmer) + `@State` private var timeout: TimeInterval = 3🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/Blueprint/Sources/Scene/Previews/LoadingPreview.swift` around lines 13 - 18, The LoadingPreview state properties are internal view implementation details but are currently publicly exposed, triggering the private_swiftui_state warning. Update the `@State` properties in LoadingPreview to be private, keeping the existing behavior unchanged while limiting access to typeOption, color, dimmerColor, and timeout.Source: Linters/SAST tools
Sources/Blueprint/Sources/Scene/Previews/PageCounterPreview.swift-30-33 (1)
30-33: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
totalPages를 줄일 때selectedPage도 같이 보정해 주세요.지금은
selectedPage = 5인 상태에서totalPages를 1로 낮추면PageCounter가 범위를 벗어난 상태로 렌더링됩니다. 같은 프리뷰 스택의 다른 파일처럼 setter에서 현재 페이지를 clamp해 두는 편이 안전합니다.제안 코드
SliderOptionRow("totalPages", value: Binding( get: { Double(totalPages) }, - set: { totalPages = Int($0) } + set: { + totalPages = Int($0) + selectedPage = min(selectedPage, totalPages) + } ), in: 1...10, step: 1)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/Blueprint/Sources/Scene/Previews/PageCounterPreview.swift` around lines 30 - 33, The totalPages slider binding in PageCounterPreview only updates totalPages, so selectedPage can remain out of range when the page count is reduced. Update the setter in the SliderOptionRow binding to clamp selectedPage whenever totalPages changes, using the same preview-state pattern already used elsewhere in the PageCounter preview stack. Keep the fix localized to PageCounterPreview and make sure selectedPage never exceeds the new totalPages value.Sources/Blueprint/Sources/Scene/Previews/TopNavigationPreview.swift-123-134 (1)
123-134: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
searchvariant에서는 trailing 옵션을 그대로 노출하면 상태가 어긋납니다.일반 variant에서 아이콘/텍스트 trailing을 추가한 뒤
search로 바꾸면, 현재 코드는focused가 다시 바뀌기 전까지 이전 trailing 구성이 남습니다.search에서는 이 옵션을 숨기거나, variant 전환 시[.text] / []로 즉시 정규화하는 쪽이 맞습니다.제안 코드
- HStack { - Text("trailingContents") - Button(variant: .outlined, size: .small, text: "TextButton") { - trailing.append(.text) - } - Button(variant: .outlined, size: .small, text: "IconButton") { - trailing.append(.icon) - } - IconButton(variant: .outlined(size: .small), icon: .reset) { - trailing = [] - } - } + if !isSearchVariant { + HStack { + Text("trailingContents") + Button(variant: .outlined, size: .small, text: "TextButton") { + trailing.append(.text) + } + Button(variant: .outlined, size: .small, text: "IconButton") { + trailing.append(.icon) + } + IconButton(variant: .outlined(size: .small), icon: .reset) { + trailing = [] + } + } + }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/Blueprint/Sources/Scene/Previews/TopNavigationPreview.swift` around lines 123 - 134, The trailing controls in TopNavigationPreview keep stale state when switching to the search variant, so update the preview state handling around the trailing HStack and variant toggles to hide trailing options for search or immediately normalize trailing when variant changes. Use the existing TopNavigationPreview state symbols such as trailing, focused, and the variant switch logic to ensure search always resets to the correct trailing configuration instead of preserving prior text/icon selections.documentation/utilities/ios-utility-components/typography.md-223-226 (1)
223-226: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
uiTextStyle설명 문장이 어색하게 끊겨 있습니다.Line 226의
과 동일한 논리이며는 앞 대상이 빠져 의미가 모호합니다.textStyle과 동일한 논리이며처럼 주어를 넣어 문장을 완결해 주세요.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@documentation/utilities/ios-utility-components/typography.md` around lines 223 - 226, `uiTextStyle` 설명 문장이 주어 없이 끊겨 있어 의미가 모호합니다. `typography.md`의 `uiTextStyle` 항목 설명을 다듬어, `textStyle`을 명시적으로 앞에 두는 형태로 문장을 완결하세요. 이 설명은 Dynamic Type 기준과 UIKit 케이스 이름 차이를 함께 전달해야 하므로, `uiTextStyle` 서술문 전체를 자연스럽게 이어지도록 수정하면 됩니다.packages/montage-mcp/data/components.json-1033-1036 (1)
1033-1036: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
interactionColor(_:)설명 문자열이 깨져 있습니다.
기본값:뒤가 비어 있어서 생성 문서에 그대로 노출되면 설명이 어색합니다. 실제 기본값을 채우거나, 모르면 괄호 구문 자체를 제거하는 편이 낫습니다.✏️ 제안 수정
- "summary": "hover / press 시 인터랙션 영역에 사용할 색상을 설정합니다(기본값: ).", + "summary": "hover / press 시 인터랙션 영역에 사용할 색상을 설정합니다.",🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/montage-mcp/data/components.json` around lines 1033 - 1036, The documentation summary for interactionColor(_:) is malformed because the default value text is empty, so update the summary in components.json to either include the actual default Color.Semantic value used by the IconButton API or remove the "(기본값: ...)" fragment entirely if no default should be advertised. Keep the wording in sync with the interactionColor(Color.Semantic) method so generated docs render cleanly.Sources/Blueprint/Sources/Scene/Previews/ButtonPreview.swift-104-110 (1)
104-110: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
iconOnly모드에서는fillWidth토글을 숨겨 주세요.현재 아이콘 전용 분기에서는
.fillWidth(...)를 적용하지 않아서, 이 토글이 켜져도 미리보기에 아무 변화가 없습니다. 옵션이 동작하지 않는 상태라 프리뷰가 오해를 줍니다.🩹 제안 수정
HStack { if !iconOnly { ToggleOption("leadingIcon", isOn: $leadingIcon) ToggleOption("trailingIcon", isOn: $trailingIcon) + ToggleOption("fillWidth", isOn: $fillWidth) } - ToggleOption("fillWidth", isOn: $fillWidth) }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/Blueprint/Sources/Scene/Previews/ButtonPreview.swift` around lines 104 - 110, `ButtonPreview`의 옵션 UI에서 `iconOnly`일 때도 `fillWidth` 토글이 보이는 문제가 있습니다. `ButtonPreview`의 토글 구성(HStack)에서 `iconOnly` 분기와 함께 `fillWidth`도 조건부로 숨기도록 수정해, 아이콘 전용 미리보기에서는 동작하지 않는 옵션이 표시되지 않게 하세요. `ToggleOption("fillWidth", isOn: $fillWidth)`와 `iconOnly` 상태를 함께 사용하는 부분을 기준으로 위치를 찾으면 됩니다.Sources/Blueprint/Sources/Scene/Previews/PushBadgePreview.swift-55-57 (1)
55-57: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win숫자 슬라이더가 값을 한 단계 낮게 확정할 수 있습니다.
Int(number)는 반올림이 아니라 버림이라서, 드래그가9.9처럼 끝나면 편집 종료 후9로 고정됩니다. 이 옵션은step: 1로 제한하거나rounded()를 써야 배지 숫자와 조작감이 맞습니다.🩹 제안 수정
- SliderOptionRow("number", value: $number, in: 1...110, onEditingEnded: { - number = Double(Int(number)) - }) + SliderOptionRow("number", value: $number, in: 1...110, step: 1)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/Blueprint/Sources/Scene/Previews/PushBadgePreview.swift` around lines 55 - 57, The number slider in PushBadgePreview’s SliderOptionRow is truncating the value on edit end because Int(number) floors instead of rounds, so a value like 9.9 can be fixed as 9. Update the onEditingEnded handling to preserve the intended whole-number behavior by using rounding or by constraining the control to whole-number steps (for example, via the SliderOptionRow configuration around the "number" binding and number assignment).Sources/Blueprint/Sources/Scene/Previews/TooltipPreview.swift-66-76 (1)
66-76: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Adjust zIndex를 숨길 때 상태도 같이 정리해 주세요.always 모드에서 이 토글을 꺼둔 뒤 click 모드로 바꾸면, 옵션은 사라지지만
adjustZIndex == false는 그대로 남아서 click 모드 프리뷰도 낮은 zIndex 설정으로 렌더링됩니다. 모드가 always가 아닐 때는 상태를true로 되돌리거나, 실제 적용 조건을modeIndex == 1 && adjustZIndex로 묶는 편이 안전합니다.🔧 제안 수정안
- SegmentedIndexRow("Mode", index: $modeIndex, labels: ["click", "always"]) + SegmentedIndexRow("Mode", index: $modeIndex, labels: ["click", "always"]) { index in + if index == 0 { + adjustZIndex = true + } + }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/Blueprint/Sources/Scene/Previews/TooltipPreview.swift` around lines 66 - 76, The `Adjust zIndex` option in `TooltipPreview` is only shown in `modeIndex == 1`, but its `adjustZIndex` state can stay false after switching back to click mode and keep affecting the preview. Update the `TooltipPreview` mode handling so the hidden option is reset when the mode changes away from always, or gate the actual zIndex behavior with both `modeIndex == 1` and `adjustZIndex`. Keep the fix localized around the `HStack`/`ToggleOption("Adjust zIndex", ...)` logic and the `modeIndex` state flow.Sources/Blueprint/Sources/Scene/Previews/AvatarGroupPreview.swift-63-63 (1)
63-63: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win원격 이미지 모드에서
item count가 실제 표시 개수와 어긋납니다.지금은 슬라이더가 10까지 올라가지만, 같은 파일의
imageUrls는allUrls.count(5개)까지만 반환해서useLocalImage == false일 때는 6 이상을 선택해도 프리뷰가 더 늘어나지 않습니다. 옵션 값과 실제 렌더링 결과가 달라서 프리뷰 해석이 헷갈립니다.🔧 제안 수정안
- SliderOptionRow("item count", value: $itemCount, in: 1...10) + SliderOptionRow( + "item count", + value: $itemCount, + in: CGFloat(1)...CGFloat(useLocalImage ? 10 : allUrls.count) + )🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/Blueprint/Sources/Scene/Previews/AvatarGroupPreview.swift` at line 63, `AvatarGroupPreview`의 `item count` 슬라이더 범위가 원격 이미지 모드의 실제 표시 개수와 맞지 않습니다. `SliderOptionRow`에서 `itemCount`의 상한을 `imageUrls`가 반환하는 실제 원격 URL 개수와 동일하게 맞추거나, `imageUrls`/렌더링 로직이 `useLocalImage` 값에 따라 같은 기준을 쓰도록 조정하세요. 특히 `imageUrls`, `itemCount`, `useLocalImage`, `SliderOptionRow`를 함께 확인해 옵션 값과 프리뷰 결과가 일치하게 만드세요.Sources/Blueprint/Sources/Scene/Previews/ContentBadgePreview.swift-61-71 (1)
61-71: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
usesTemplate토글 라벨을 분리하세요.두 아이콘을 모두 켜면 옵션 패널에
usesTemplate토글이 두 개 생겨서 어떤 아이콘을 제어하는지 구분되지 않습니다. VoiceOver와 UI 테스트에서도 식별이 모호해집니다.🔧 제안 수정
HStack { ToggleOption("leadingIcon", isOn: $leadingIcon) if leadingIcon { - ToggleOption("usesTemplate", isOn: $leadingIconUsesTemplate) + ToggleOption("leading usesTemplate", isOn: $leadingIconUsesTemplate) } } HStack { ToggleOption("trailingIcon", isOn: $trailingIcon) if trailingIcon { - ToggleOption("usesTemplate", isOn: $trailingIconUsesTemplate) + ToggleOption("trailing usesTemplate", isOn: $trailingIconUsesTemplate) } }As per path instructions, "VoiceOver 지원 - 적절한 accessibilityLabel과 accessibilityHint 제공".
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/Blueprint/Sources/Scene/Previews/ContentBadgePreview.swift` around lines 61 - 71, The `usesTemplate` toggle in `ContentBadgePreview` is duplicated for both `leadingIcon` and `trailingIcon`, so the labels are ambiguous. Update the `ToggleOption` calls inside the two `HStack` blocks to use distinct labels that identify whether they control the leading or trailing icon, and add the appropriate accessibility label/hint so VoiceOver and UI tests can tell them apart.Source: Path instructions
🧹 Nitpick comments (3)
Sources/Blueprint/Sources/Scene/Previews/ActionAreaPreview.swift (1)
37-40: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win옵션 노출 조건을 표시 문자열에 의존하지 마세요.
isStrongOrNeutral가selectableTitle의 prefix로 분기해서, 제목 문구를 바꾸거나 현지화하면 caption 토글 노출 조건도 같이 깨집니다. 여기서는 표시용 문자열이 아니라VariantKindcase 자체를 기준으로 판별하는 편이 안전합니다.제안된 수정
var isStrongOrNeutral: Bool { - selectableTitle.starts(with: "Strong") || - selectableTitle.starts(with: "Neutral") || - selectableTitle.starts(with: "Custom") + switch self { + case .strongOne, .strongTwo, .strongAll, + .neutralOne, .neutralTwo, .neutralAll, + .custom: + true + case .cancel: + false + } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/Blueprint/Sources/Scene/Previews/ActionAreaPreview.swift` around lines 37 - 40, `isStrongOrNeutral` is currently using `selectableTitle` string prefixes to decide caption toggle visibility, which makes the logic fragile when titles change or are localized. Update the `ActionAreaPreview` logic to derive this condition from the underlying `VariantKind` case instead of the display text, and keep `selectableTitle` only for presentation. Use the existing `VariantKind`-based flow around `isStrongOrNeutral` to locate the change.Sources/Blueprint/Sources/Scene/Previews/TopNavigationPreview.swift (1)
36-40: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
@State는private로 닫아두는 편이 좋겠습니다.이 상태값들은 파일 외부에서 접근할 이유가 없어 보입니다. SwiftLint도 Line 36-40을 같은 규칙으로 경고하고 있습니다.
제안 코드
- `@State` var variantIndex: Int = 0 - `@State` var leading = false - `@State` var trailing: [TrailingButton] = [] - `@State` var toast: Toast.Model? - `@State` var backgroundColor: SwiftUI.Color = .clear + `@State` private var variantIndex: Int = 0 + `@State` private var leading = false + `@State` private var trailing: [TrailingButton] = [] + `@State` private var toast: Toast.Model? + `@State` private var backgroundColor: SwiftUI.Color = .clear🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/Blueprint/Sources/Scene/Previews/TopNavigationPreview.swift` around lines 36 - 40, The preview state properties in TopNavigationPreview should be private. Update the `@State` declarations for variantIndex, leading, trailing, toast, and backgroundColor to use private access so these internal preview-only values are not exposed outside the view and satisfy the SwiftLint rule.Source: Linters/SAST tools
Sources/Blueprint/Sources/Scene/Previews/IconButtonPreview.swift (1)
119-137: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win강제 언래핑 대신 옵셔널 바인딩으로 바꿔 주세요.
nil체크 바로 뒤에서iconColor!/backgroundColor!/borderColor!를 다시 꺼내고 있어서, 조건식이 바뀌면 즉시 크래시 경로가 됩니다.if let으로 같은 동작을 더 안전하게 표현하는 편이 낫습니다.♻️ 제안 수정
.modifying { - if iconColor != nil { - $0.iconColor(iconColor!) + if let iconColor { + $0.iconColor(iconColor) } else { $0 } } .modifying { - if isOutlinedOrSolid && backgroundColor != nil { - $0.backgroundColor(backgroundColor!) + if isOutlinedOrSolid, let backgroundColor { + $0.backgroundColor(backgroundColor) } else { $0 } } .modifying { - if isOutlined && borderColor != nil { - $0.borderColor(borderColor!) + if isOutlined, let borderColor { + $0.borderColor(borderColor) } else { $0 } }As per path instructions,
**/*.swift:옵셔널 처리: force unwrapping (!) 사용 최소화, guard 문 활용.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/Blueprint/Sources/Scene/Previews/IconButtonPreview.swift` around lines 119 - 137, `IconButtonPreview`의 `.modifying` 체인에서 `iconColor!`, `backgroundColor!`, `borderColor!`를 강제 언래핑하고 있어 안전하지 않습니다. 각 조건문을 `if let` 옵셔널 바인딩으로 바꿔서, `iconColor`, `backgroundColor`, `borderColor`가 존재할 때만 `iconColor(...)`, `backgroundColor(...)`, `borderColor(...)`를 호출하도록 수정해 주세요. `isOutlinedOrSolid`와 `isOutlined` 분기 로직은 유지하되, `modifying` 블록 내부에서 옵셔널을 직접 꺼내지 않도록 정리하면 됩니다.Source: Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@Sources/Blueprint/Sources/Scene/Previews/FlowLayoutPreview.swift`:
- Around line 17-31: `PreviewLayout` inside `FlowLayoutPreview` currently wraps
the content in an extra `ScrollView`, which causes nested vertical scrolling and
gesture conflicts. Remove the inner `ScrollView` and keep the `ZStack` and
`FlowLayout` content directly inside `PreviewLayout` so the preview uses only
the outer scrolling behavior. Use `PreviewLayout` and `FlowLayout` as the key
spots to update.
In `@Sources/Blueprint/Sources/Scene/Previews/LoadingPreview.swift`:
- Around line 53-56: The LoadingPreview timeout logic in onChange(of: isLoading)
is using uncancelled asyncAfter callbacks and toggle(), so older timers can
mutate a newer loading cycle. Update the loading timeout handling to keep a
cancellable reference or token for each cycle, cancel any previous pending
timeout when isLoading changes, and only clear the matching loading session
instead of toggling the current value. Use the onChange(of: isLoading) block and
the timeout callback around isLoading to locate the fix.
In `@Sources/Blueprint/Sources/Scene/Previews/PullToRefreshPreview.swift`:
- Around line 45-50: The `PullToRefreshPreview` refresh-time input currently
accepts arbitrary text, which can allow negative or non-numeric values that
later break the `Task.sleep` path when converting `seconds` to `UInt64`. Update
the `TextField` bound to `seconds` in this preview to restrict input to numeric,
non-negative values only, and add validation/sanitization at the point where the
value is edited so invalid values cannot be entered or persisted. Keep the fix
focused around the `seconds` state and the preview UI that exposes it.
In `@Sources/Blueprint/Sources/Scene/Previews/TabPreview.swift`:
- Around line 46-50: The count change handler in TabPreview’s onChange(of:
count) rebuilds items but leaves selectedIndex unchanged, so shrinking the tab
count can leave the selection out of bounds. After regenerating items, clamp
selectedIndex to the last valid index for the new items array, or reset it to 0
when the previous selection is no longer valid, using the existing selectedIndex
state in TabPreview.
In
`@Sources/Blueprint/Sources/Scene/Previews/VerticalProgressTrackerPreview.swift`:
- Around line 75-76: The progress range in VerticalProgressTrackerPreview is too
wide for the available stepContents and can produce an invalid progress state.
Update the PrevNextOptionRow binding in the preview so the allowed range matches
the actual number of steps defined by stepContents, preventing progress from
reaching a non-existent step and avoiding incorrect rendering or asserts.
In `@Sources/Blueprint/Sources/Utilities/PreviewLayout.swift`:
- Around line 100-101: The new hasOptions check in PreviewLayout should be
applied consistently across the .upsideDown and .floating rendering branches,
not just the main layout path. Update the PreviewLayout body so the “Options”
header and its panel are conditionally omitted whenever Options.self is
EmptyView, reusing hasOptions in the affected branches and preserving the
existing behavior for non-empty options.
- Around line 256-260: 아이콘만 있는 버튼에 VoiceOver용 접근성 정보가 빠져 있습니다. PreviewLayout의
showChecker를 토글하는 Button과 함께 동일 파일의 뒤로가기 버튼에도 accessibilityLabel과
accessibilityHint를 추가해, SF Symbol만 보이더라도 의미 있는 이름으로 읽히도록 수정하세요. 버튼의 label 역할을 하는
Image(systemName:)는 유지하되, 각 버튼이 무엇을 하는지 명확히 드러나게 접근성 속성을 보강하면 됩니다.
In `@Sources/Blueprint/Sources/Utilities/PreviewOption.swift`:
- Around line 46-60: The option row controls currently render the title
separately from the interactive control, so the SegmentedControl and similar
inputs end up without an accessible label. Update PreviewOption’s body so the
actual control receives the row title as its accessibility label, or combine the
row into a single accessibility element; apply the same pattern to the other
affected option-row views referenced in this change so each interactive control
exposes a meaningful VoiceOver label and hint.
In `@Sources/Montage/1` Components/2 Actions/IconButton.swift:
- Around line 262-305: The public Variant API in IconButton has a breaking
signature change because normal, outlined, and solid now use different
associated value types, which will break existing callers. Keep the current
Int-based path compatible by preserving the old Variant cases or adding a
deprecated compatibility layer in IconButton.Variant, and migrate internal call
sites like Category, Tab, SnackBar, Popover, and Card to the new shape only if
this is a major-version change. If this release is non-major, mark the old API
deprecated with `@available` and avoid removing the existing contract.
In `@Sources/Montage/1` Components/3 Selection And Input/TextArea.swift:
- Around line 124-133: 아이콘-only segmentedControl은 현재 각 항목의 의미와 상태를 VoiceOver가
구분할 수 없으므로, `TextArea.Segment`의
`segmentedControl(selectedIndex:icons:onSelect:)`와 해당 렌더링 로직에서 접근성 정보를 추가하도록
수정하세요. `icons: [Icon]`만으로는 부족하니 각 세그먼트에 `accessibilityLabel`과
`accessibilityHint`를 전달할 수 있는 구조를 보완하고, `Image` + `onTapGesture` 대신 버튼 의미론이
유지되도록 `segmentedControl`/세그먼트 뷰의 접근성 설정을 적용하세요.
In `@Sources/Montage/1` Components/3 Selection And Input/TextField.swift:
- Around line 162-170: The public backgroundColor(_:) modifier is currently a
no-op because it only sets customBackgroundColor and the new fieldBackground
path never reads that value. Update TextField’s background rendering logic to
consume customBackgroundColor when building the field background, and ensure the
modifier still overrides the default background in the main TextField view path
and any related background helper used by the refactor.
- Around line 372-382: The TextField accessibility setup is overriding the real
input value with a status string, so VoiceOver cannot read what the user typed.
Update TextField.swift in the TextField view to stop using accessibilityValue
for the error/empty state alone; instead keep the actual text exposed and move
the status into accessibilityHint or accessibilityLabel, or combine the status
with the current text in accessibilityValue. Apply the same fix in the other
matching TextField accessibility block referenced by the review so both paths
preserve the typed value.
---
Outside diff comments:
In `@Sources/Blueprint/Sources/Scene/Previews/ColorPreview.swift`:
- Around line 27-45: When the selected color type changes to .atomic in
ColorPreview, the transparent checker state must be reset as well. Update the
selection handling around selectedColorTypeIndex so that switching to the atomic
case also sets showTransparentChecker to false, instead of only disabling the
checkerboard Button. Use the existing ColorPreview, selectedColorTypeIndex,
showTransparentChecker, and ColorType.allCases references to locate the logic
and keep the preview state aligned with the active segment.
---
Minor comments:
In `@documentation/utilities/ios-utility-components/typography.md`:
- Around line 223-226: `uiTextStyle` 설명 문장이 주어 없이 끊겨 있어 의미가 모호합니다.
`typography.md`의 `uiTextStyle` 항목 설명을 다듬어, `textStyle`을 명시적으로 앞에 두는 형태로 문장을
완결하세요. 이 설명은 Dynamic Type 기준과 UIKit 케이스 이름 차이를 함께 전달해야 하므로, `uiTextStyle` 서술문
전체를 자연스럽게 이어지도록 수정하면 됩니다.
In `@packages/montage-mcp/data/components.json`:
- Around line 1033-1036: The documentation summary for interactionColor(_:) is
malformed because the default value text is empty, so update the summary in
components.json to either include the actual default Color.Semantic value used
by the IconButton API or remove the "(기본값: ...)" fragment entirely if no default
should be advertised. Keep the wording in sync with the
interactionColor(Color.Semantic) method so generated docs render cleanly.
In `@Sources/Blueprint/Sources/Scene/Previews/AvatarGroupPreview.swift`:
- Line 63: `AvatarGroupPreview`의 `item count` 슬라이더 범위가 원격 이미지 모드의 실제 표시 개수와 맞지
않습니다. `SliderOptionRow`에서 `itemCount`의 상한을 `imageUrls`가 반환하는 실제 원격 URL 개수와 동일하게
맞추거나, `imageUrls`/렌더링 로직이 `useLocalImage` 값에 따라 같은 기준을 쓰도록 조정하세요. 특히
`imageUrls`, `itemCount`, `useLocalImage`, `SliderOptionRow`를 함께 확인해 옵션 값과 프리뷰
결과가 일치하게 만드세요.
In `@Sources/Blueprint/Sources/Scene/Previews/ButtonPreview.swift`:
- Around line 104-110: `ButtonPreview`의 옵션 UI에서 `iconOnly`일 때도 `fillWidth` 토글이
보이는 문제가 있습니다. `ButtonPreview`의 토글 구성(HStack)에서 `iconOnly` 분기와 함께 `fillWidth`도
조건부로 숨기도록 수정해, 아이콘 전용 미리보기에서는 동작하지 않는 옵션이 표시되지 않게 하세요.
`ToggleOption("fillWidth", isOn: $fillWidth)`와 `iconOnly` 상태를 함께 사용하는 부분을 기준으로
위치를 찾으면 됩니다.
In `@Sources/Blueprint/Sources/Scene/Previews/ContentBadgePreview.swift`:
- Around line 61-71: The `usesTemplate` toggle in `ContentBadgePreview` is
duplicated for both `leadingIcon` and `trailingIcon`, so the labels are
ambiguous. Update the `ToggleOption` calls inside the two `HStack` blocks to use
distinct labels that identify whether they control the leading or trailing icon,
and add the appropriate accessibility label/hint so VoiceOver and UI tests can
tell them apart.
In `@Sources/Blueprint/Sources/Scene/Previews/LoadingPreview.swift`:
- Around line 13-18: The LoadingPreview state properties are internal view
implementation details but are currently publicly exposed, triggering the
private_swiftui_state warning. Update the `@State` properties in LoadingPreview to
be private, keeping the existing behavior unchanged while limiting access to
typeOption, color, dimmerColor, and timeout.
In `@Sources/Blueprint/Sources/Scene/Previews/PageCounterPreview.swift`:
- Around line 30-33: The totalPages slider binding in PageCounterPreview only
updates totalPages, so selectedPage can remain out of range when the page count
is reduced. Update the setter in the SliderOptionRow binding to clamp
selectedPage whenever totalPages changes, using the same preview-state pattern
already used elsewhere in the PageCounter preview stack. Keep the fix localized
to PageCounterPreview and make sure selectedPage never exceeds the new
totalPages value.
In `@Sources/Blueprint/Sources/Scene/Previews/PushBadgePreview.swift`:
- Around line 55-57: The number slider in PushBadgePreview’s SliderOptionRow is
truncating the value on edit end because Int(number) floors instead of rounds,
so a value like 9.9 can be fixed as 9. Update the onEditingEnded handling to
preserve the intended whole-number behavior by using rounding or by constraining
the control to whole-number steps (for example, via the SliderOptionRow
configuration around the "number" binding and number assignment).
In `@Sources/Blueprint/Sources/Scene/Previews/TextFieldPreview.swift`:
- Around line 143-199: The suggestion datasource is only refreshed from the text
change handler, so toggling usingSuggestions does not immediately clear or
rebuild autoCompletionDataSource. Update the TextFieldPreview logic around the
.onChange(of: text) flow to also observe usingSuggestions and synchronize the
datasource whenever the toggle changes, clearing it when disabled and
recalculating it when enabled with non-empty text. Use the existing
autoCompletionDataSource, usingSuggestions, and candidates logic so the preview
state always matches the toggle.
In `@Sources/Blueprint/Sources/Scene/Previews/TooltipPreview.swift`:
- Around line 66-76: The `Adjust zIndex` option in `TooltipPreview` is only
shown in `modeIndex == 1`, but its `adjustZIndex` state can stay false after
switching back to click mode and keep affecting the preview. Update the
`TooltipPreview` mode handling so the hidden option is reset when the mode
changes away from always, or gate the actual zIndex behavior with both
`modeIndex == 1` and `adjustZIndex`. Keep the fix localized around the
`HStack`/`ToggleOption("Adjust zIndex", ...)` logic and the `modeIndex` state
flow.
In `@Sources/Blueprint/Sources/Scene/Previews/TopNavigationPreview.swift`:
- Around line 123-134: The trailing controls in TopNavigationPreview keep stale
state when switching to the search variant, so update the preview state handling
around the trailing HStack and variant toggles to hide trailing options for
search or immediately normalize trailing when variant changes. Use the existing
TopNavigationPreview state symbols such as trailing, focused, and the variant
switch logic to ensure search always resets to the correct trailing
configuration instead of preserving prior text/icon selections.
In `@Sources/Montage/1` Components/5 Loading/Skeleton.swift:
- Around line 222-226: The line count calculation in Skeleton’s layout logic
should not round up, because `round` can produce an extra line and make the
skeleton taller than its container. Update the `effectiveLineCount` computation
in the sizing path that uses `proxy.size.height` and `scaledLineHeight` to use
`floor` instead of `round`, while keeping the `kind.lineNumber` override and the
`max(1, ...)` minimum intact.
---
Nitpick comments:
In `@Sources/Blueprint/Sources/Scene/Previews/ActionAreaPreview.swift`:
- Around line 37-40: `isStrongOrNeutral` is currently using `selectableTitle`
string prefixes to decide caption toggle visibility, which makes the logic
fragile when titles change or are localized. Update the `ActionAreaPreview`
logic to derive this condition from the underlying `VariantKind` case instead of
the display text, and keep `selectableTitle` only for presentation. Use the
existing `VariantKind`-based flow around `isStrongOrNeutral` to locate the
change.
In `@Sources/Blueprint/Sources/Scene/Previews/IconButtonPreview.swift`:
- Around line 119-137: `IconButtonPreview`의 `.modifying` 체인에서 `iconColor!`,
`backgroundColor!`, `borderColor!`를 강제 언래핑하고 있어 안전하지 않습니다. 각 조건문을 `if let` 옵셔널
바인딩으로 바꿔서, `iconColor`, `backgroundColor`, `borderColor`가 존재할 때만
`iconColor(...)`, `backgroundColor(...)`, `borderColor(...)`를 호출하도록 수정해 주세요.
`isOutlinedOrSolid`와 `isOutlined` 분기 로직은 유지하되, `modifying` 블록 내부에서 옵셔널을 직접 꺼내지
않도록 정리하면 됩니다.
In `@Sources/Blueprint/Sources/Scene/Previews/TopNavigationPreview.swift`:
- Around line 36-40: The preview state properties in TopNavigationPreview should
be private. Update the `@State` declarations for variantIndex, leading, trailing,
toast, and backgroundColor to use private access so these internal preview-only
values are not exposed outside the view and satisfy the SwiftLint rule.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 6dfd73f0-5192-4332-ad2e-c59634618b97
📒 Files selected for processing (113)
.gitignoreSources/Blueprint/Blueprint.xcodeproj/project.pbxprojSources/Blueprint/Sources/Scene/ComponentList/ComponentListNavigationCoordinator.swiftSources/Blueprint/Sources/Scene/ComponentList/ComponentListView.swiftSources/Blueprint/Sources/Scene/ComponentList/ComponentSection.swiftSources/Blueprint/Sources/Scene/Previews/AccordionPreview.swiftSources/Blueprint/Sources/Scene/Previews/ActionAreaPreview.swiftSources/Blueprint/Sources/Scene/Previews/AvatarGroupPreview.swiftSources/Blueprint/Sources/Scene/Previews/AvatarPreview.swiftSources/Blueprint/Sources/Scene/Previews/BottomSheetPreview.swiftSources/Blueprint/Sources/Scene/Previews/ButtonPreview.swiftSources/Blueprint/Sources/Scene/Previews/CardPreview.swiftSources/Blueprint/Sources/Scene/Previews/CategoryPreview.swiftSources/Blueprint/Sources/Scene/Previews/ChipPreview.swiftSources/Blueprint/Sources/Scene/Previews/ColorPreview.swiftSources/Blueprint/Sources/Scene/Previews/ContentBadgePreview.swiftSources/Blueprint/Sources/Scene/Previews/ControlPreview.swiftSources/Blueprint/Sources/Scene/Previews/DateTimePickerPreview.swiftSources/Blueprint/Sources/Scene/Previews/FallbackViewPreview.swiftSources/Blueprint/Sources/Scene/Previews/FilterButtonPreview.swiftSources/Blueprint/Sources/Scene/Previews/FlowLayoutPreview.swiftSources/Blueprint/Sources/Scene/Previews/FramedStylePreview.swiftSources/Blueprint/Sources/Scene/Previews/HorizontalProgressTrackerPreview.swiftSources/Blueprint/Sources/Scene/Previews/IconButtonPreview.swiftSources/Blueprint/Sources/Scene/Previews/IconPreview.swiftSources/Blueprint/Sources/Scene/Previews/ListCardPreview.swiftSources/Blueprint/Sources/Scene/Previews/ListCellPreview.swiftSources/Blueprint/Sources/Scene/Previews/LoadingPreview.swiftSources/Blueprint/Sources/Scene/Previews/ModalNavigationPreview.swiftSources/Blueprint/Sources/Scene/Previews/PageCounterPreview.swiftSources/Blueprint/Sources/Scene/Previews/PaginationDotsPreview.swiftSources/Blueprint/Sources/Scene/Previews/PaginationPreview.swiftSources/Blueprint/Sources/Scene/Previews/PlayBadgePreview.swiftSources/Blueprint/Sources/Scene/Previews/PopoverPreview.swiftSources/Blueprint/Sources/Scene/Previews/PopupPreview.swiftSources/Blueprint/Sources/Scene/Previews/ProgressIndicatorPreview.swiftSources/Blueprint/Sources/Scene/Previews/ProgressTrackerPreview.swiftSources/Blueprint/Sources/Scene/Previews/PullToRefreshPreview.swiftSources/Blueprint/Sources/Scene/Previews/PushBadgePreview.swiftSources/Blueprint/Sources/Scene/Previews/SectionHeaderPreview.swiftSources/Blueprint/Sources/Scene/Previews/SegmentedControlPreview.swiftSources/Blueprint/Sources/Scene/Previews/SelectPreview.swiftSources/Blueprint/Sources/Scene/Previews/ShadowPreview.swiftSources/Blueprint/Sources/Scene/Previews/SkeletonPreview.swiftSources/Blueprint/Sources/Scene/Previews/SliderPreview.swiftSources/Blueprint/Sources/Scene/Previews/SnackBarPreview.swiftSources/Blueprint/Sources/Scene/Previews/TabPreview.swiftSources/Blueprint/Sources/Scene/Previews/TextAreaPreview.swiftSources/Blueprint/Sources/Scene/Previews/TextButtonPreview.swiftSources/Blueprint/Sources/Scene/Previews/TextFieldPreview.swiftSources/Blueprint/Sources/Scene/Previews/ThumbnailPreview.swiftSources/Blueprint/Sources/Scene/Previews/ToastPreview.swiftSources/Blueprint/Sources/Scene/Previews/TooltipPreview.swiftSources/Blueprint/Sources/Scene/Previews/TopNavigationPreview.swiftSources/Blueprint/Sources/Scene/Previews/TypographyPreview.swiftSources/Blueprint/Sources/Scene/Previews/VerticalProgressTrackerPreview.swiftSources/Blueprint/Sources/Utilities/PreviewLayout.swiftSources/Blueprint/Sources/Utilities/PreviewOption.swiftSources/Montage/1 Components/2 Actions/Button.swiftSources/Montage/1 Components/2 Actions/IconButton.swiftSources/Montage/1 Components/2 Actions/OutlinedUIButton.swiftSources/Montage/1 Components/2 Actions/SolidUIButton.swiftSources/Montage/1 Components/3 Selection And Input/Control.swiftSources/Montage/1 Components/3 Selection And Input/Select.swiftSources/Montage/1 Components/3 Selection And Input/Slider.swiftSources/Montage/1 Components/3 Selection And Input/TextArea.swiftSources/Montage/1 Components/3 Selection And Input/TextField.swiftSources/Montage/1 Components/4 Contents/Accordion.swiftSources/Montage/1 Components/4 Contents/Card.swiftSources/Montage/1 Components/4 Contents/ContentBadgeUIView.swiftSources/Montage/1 Components/4 Contents/Thumbnail.swiftSources/Montage/1 Components/5 Loading/Skeleton.swiftSources/Montage/1 Components/6 Navigations/Category.swiftSources/Montage/1 Components/6 Navigations/Tab.swiftSources/Montage/1 Components/6 Navigations/TopNavigation.swiftSources/Montage/1 Components/7 Feedback/SnackBar.swiftSources/Montage/1 Components/8 Presentation/Popover.swiftSources/Montage/1 Components/9 Utilities/Color.swiftSources/Montage/1 Components/9 Utilities/Dimension.swiftSources/Montage/1 Components/9 Utilities/InteractionUIView.swiftSources/Montage/1 Components/9 Utilities/ModalNavigation.swiftSources/Montage/1 Components/9 Utilities/Opacity.swiftSources/Montage/1 Components/9 Utilities/Primitive.swiftSources/Montage/1 Components/9 Utilities/Radius.swiftSources/Montage/1 Components/9 Utilities/Spacing.swiftSources/Montage/1 Components/9 Utilities/Typography.swiftSources/Montage/2 Utilities/Extension/SwiftUI/SwiftUI+Debug.swiftSources/Montage/2 Utilities/Extension/UIKit/NSAttributedString+.swiftSources/Montage/Asset/Color.xcassets/Pink/pink100.colorset/Contents.jsonSources/Montage/Asset/Color.xcassets/Violet/violet0.colorset/Contents.jsonSources/Montage/Asset/Color.xcassets/Violet/violet100.colorset/Contents.jsonSources/Montage/Asset/Localizable.xcstringsdocumentation/components/actions/button/ios.mddocumentation/components/actions/iconbutton/ios.mddocumentation/components/contents/accordion/ios.mddocumentation/components/loading/skeleton/ios.mddocumentation/components/selection and input/textarea/ios.mddocumentation/components/selection and input/textfield/ios.mddocumentation/utilities/ios-extensions/corefoundation.mddocumentation/utilities/ios-extensions/swift.mddocumentation/utilities/ios-utility-components/color.mddocumentation/utilities/ios-utility-components/dimension.mddocumentation/utilities/ios-utility-components/modalnavigation.mddocumentation/utilities/ios-utility-components/opacity.mddocumentation/utilities/ios-utility-components/primitive.mddocumentation/utilities/ios-utility-components/radius.mddocumentation/utilities/ios-utility-components/spacing.mddocumentation/utilities/ios-utility-components/typography.mdpackages/montage-mcp/data/components.jsonpackages/montage-mcp/data/markdown/coding-guidelines.mdpackages/montage-mcp/data/markdown/color-usage.mdpackages/montage-mcp/data/tokens.jsonscripts/build_mcp_data.js
💤 Files with no reviewable changes (11)
- documentation/components/contents/accordion/ios.md
- Sources/Blueprint/Sources/Scene/Previews/PaginationPreview.swift
- documentation/utilities/ios-extensions/swift.md
- Sources/Blueprint/Sources/Scene/Previews/ProgressTrackerPreview.swift
- Sources/Montage/1 Components/2 Actions/SolidUIButton.swift
- documentation/components/loading/skeleton/ios.md
- Sources/Montage/1 Components/4 Contents/ContentBadgeUIView.swift
- Sources/Montage/1 Components/4 Contents/Accordion.swift
- documentation/utilities/ios-utility-components/modalnavigation.md
- Sources/Montage/1 Components/2 Actions/OutlinedUIButton.swift
- Sources/Montage/1 Components/9 Utilities/InteractionUIView.swift
|
@coderabbitai 타겟이 잘못 설정되어 있었어 리뷰 처음부터 다시 해줘 |
|
✅ Action performedFull review finished. |
There was a problem hiding this comment.
Actionable comments posted: 13
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
Sources/Blueprint/Sources/Scene/Previews/ColorPreview.swift (1)
27-52: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winAtomic으로 바꿔도 체커 상태가 남습니다.
여기서는 토글만 비활성화하고
showTransparentChecker값은 그대로 유지해서, semantic/all에서 체커를 켠 뒤 atomic으로 전환하면AtomicColorSections(showTransparentChecker: showTransparentChecker)가 계속true를 받습니다. atomic 선택 시 값을false로 리셋하거나, atomic 분기에는 항상false를 넘겨서 상태를 같이 정리해 주세요.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/Blueprint/Sources/Scene/Previews/ColorPreview.swift` around lines 27 - 52, `ColorPreview`의 `showTransparentChecker` 상태가 atomic 선택 시에도 유지되어 `AtomicColorSections`에 true가 전달되는 문제가 있습니다. `selectedColorTypeIndex`를 기준으로 분기하는 `Button`/`ScrollView` 흐름에서 atomic로 전환될 때 `showTransparentChecker`를 false로 리셋하거나, `AtomicColorSections(showTransparentChecker:)`에는 항상 false를 넘기도록 수정해 상태가 섞이지 않게 정리하세요.Sources/Blueprint/Sources/Scene/Previews/TextAreaPreview.swift (1)
169-174: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winresize를 바꾸면 현재 입력값이 지워집니다.
높이 갱신용 workaround가
text를 강제로" "→""로 바꿔서, 사용자가 입력한 내용을 resize 전환마다 잃게 만듭니다. 프리뷰 상태를 유지한 채 레이아웃만 새로 고치도록TextArea에 별도 refresh key를 주거나.id(resize)같은 방식으로 분리하는 편이 안전합니다.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/Blueprint/Sources/Scene/Previews/TextAreaPreview.swift` around lines 169 - 174, The resize workaround in TextAreaPreview is mutating the bound text value, which clears the user’s input whenever resize changes. Update the .onChange(of: resize) handling in TextAreaPreview to refresh the layout without changing text, and use a separate refresh trigger for TextArea such as a dedicated refresh key or an .id(resize)-style split so the preview state stays intact while only the layout is re-rendered.
🧹 Nitpick comments (1)
Sources/Blueprint/Sources/Scene/Previews/IconButtonPreview.swift (1)
119-135: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win강제 언래핑을 없애는 편이 안전합니다.
iconColor!,backgroundColor!,borderColor!는 지금은 앞선 분기에 기대고 있지만, 조건식이 조금만 바뀌어도 바로 크래시 포인트가 됩니다.if let iconColor,if let backgroundColor,if let borderColor처럼 지역 바인딩으로 바꾸면 같은 동작을 더 안전하게 유지할 수 있습니다. As per path instructions, "옵셔널 처리: force unwrapping (!) 사용 최소화".제안된 수정
.modifying { - if iconColor != nil { - $0.iconColor(iconColor!) + if let iconColor { + $0.iconColor(iconColor) } else { $0 } } .modifying { - if isOutlinedOrSolid && backgroundColor != nil { - $0.backgroundColor(backgroundColor!) + if isOutlinedOrSolid, let backgroundColor { + $0.backgroundColor(backgroundColor) } else { $0 } } .modifying { - if isOutlined && borderColor != nil { - $0.borderColor(borderColor!) + if isOutlined, let borderColor { + $0.borderColor(borderColor) } else { $0 } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/Blueprint/Sources/Scene/Previews/IconButtonPreview.swift` around lines 119 - 135, In IconButtonPreview’s modifying chain, replace the force-unwrapped optional uses for iconColor, backgroundColor, and borderColor with safe local binding. Update each conditional block in the preview builder to use if let-style unwrapping before calling iconColor(...), backgroundColor(...), and borderColor(...) so the behavior stays the same without relying on `!`. Keep the changes scoped to the existing `.modifying` closures in IconButtonPreview.Source: Path instructions
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/montage-mcp/data/components.json`:
- Around line 2410-2426: `TextArea.Resource`의 MCP 메타데이터에서 public instance
property인 `isLeadingAllowed`가 빠져 있습니다. `components.json`에서 `TextArea.Resource`
항목을 찾아 `cases`와 `staticMethods` 옆에 `instanceProperties`를 추가하고, 그 안에
`isLeadingAllowed`를 노출하도록 맞춰 주세요. 이렇게 하면 Swift 코드와 DocC에 있는 `isLeadingAllowed`
계약이 MCP 메타데이터와 일치합니다.
In `@Sources/Blueprint/Sources/Scene/Previews/AvatarGroupPreview.swift`:
- Line 63: `AvatarGroupPreview`의 `SliderOptionRow("item count", value:
$itemCount, in: 1...10)`는 연속값을 허용해 실제 렌더링에서 `Int(itemCount)`로 잘리는 값과 불일치가 생깁니다.
`itemCount`가 항상 정수로만 바뀌도록 이 슬라이더에 step 1을 적용하고, 관련 렌더링 로직(아바타 개수를
`Int(itemCount)`로 쓰는 부분)과 값이 일치하도록 유지하세요.
In
`@Sources/Blueprint/Sources/Scene/Previews/HorizontalProgressTrackerPreview.swift`:
- Around line 20-24: `HorizontalProgressTrackerPreview`에서 `stepCount`가 바뀔 때
`ProgressTracker`의 `labels`와 `PrevNextOptionRow`의 범위가 잠깐 불일치합니다. `progress`와
`labels`를 함께 관리하는 정규화 지점을 만들어 `stepCount` 변경 시 현재 `progress`를 새 범위에 맞게 보정하고,
`labels`도 같은 시점에 새 개수에 맞춰 갱신한 뒤 `ProgressTracker`와 `PrevNextOptionRow`가 동일한 상태를
보도록 조정하세요.
In `@Sources/Blueprint/Sources/Scene/Previews/PageCounterPreview.swift`:
- Around line 30-33: `PageCounterPreview`의 `SliderOptionRow("totalPages",
value:)` setter는 `totalPages`만 갱신해서 `selectedPage`가 범위를 벗어날 수 있습니다.
`totalPages`를 변경할 때 `selectedPage`도 함께 보정하도록 수정하고,
`PageCounter(selectedPage:totalPages:)`에 항상 유효한 조합이 들어가도록 `selectedPage`를 새
`totalPages` 범위로 클램프하세요.
In `@Sources/Blueprint/Sources/Scene/Previews/PaginationDotsPreview.swift`:
- Around line 36-44: `PaginationDotsPreview`의 `SliderOptionRow("totalPages",
...)`는 `totalPages`가 Int인데도 정수 step이 없어 드래그 중 연속값이 잘리는 문제가 있습니다. 이 바인딩의 슬라이더 설정을
정수 도메인에 맞게 고정하도록 `step: 1`을 추가하고, `selectedPage`를 `totalPages`로 clamp하는 기존 로직은
그대로 유지하세요.
In `@Sources/Blueprint/Sources/Scene/Previews/PushBadgePreview.swift`:
- Around line 55-57: The PushBadgePreview slider is still allowing continuous
values while the badge logic expects integers, so the displayed option can drift
from the actual value. Update SliderOptionRow in PushBadgePreview so the number
control is constrained to integer steps by using step 1 instead of rounding in
onEditingEnded, and keep the value aligned with the Int-based badge state.
In `@Sources/Blueprint/Sources/Scene/Previews/SelectPreview.swift`:
- Around line 77-92: When `customMenu` is turned off, make sure `showSheet` is
also reset so the `.bottomSheet(isPresented: $showSheet)` bound in
`SelectPreview` does not stay open or get reused unexpectedly. Update the
toggle/option handling around `menuPresented` and the `.bottomSheet` binding to
clear `showSheet` whenever the custom menu is disabled, using the existing
`showSheet`, `customMenu`, and `SelectPreview` state flow.
In `@Sources/Blueprint/Sources/Scene/Previews/TextAreaPreview.swift`:
- Around line 129-157: The preview menu in TextAreaPreview is keeping the wrong
slice type and order when updating leadingResources and trailingResources.
Update the resource trimming logic in the MenuOptionRow button actions so the
arrays are reassigned from the first three items, matching bottomResources(...)
and avoiding the ArraySlice mismatch; use the existing leadingResources and
trailingResources handling as the place to fix it.
In `@Sources/Blueprint/Sources/Scene/Previews/TextFieldPreview.swift`:
- Around line 143-219: The autoComplete toggle state is only reflected from the
text change handler, so the suggestion list can become stale when
`usingSuggestions` changes. Update the `TextFieldPreview` logic in the
`onChange(of: text)` flow and add an `onChange(of: usingSuggestions)` handler to
immediately clear `autoCompletionDataSource` when disabled and recompute it from
the current `text` when enabled, keeping the datasource in sync with the toggle.
In `@Sources/Blueprint/Sources/Scene/Previews/ThumbnailPreview.swift`:
- Around line 37-39: The ForEach in ThumbnailPreview is using ratio.hashValue as
the identifier, which is not stable and can break SwiftUI diffing. Update the
ForEach over ratios to use a stable identity such as id: \.self for
Thumbnail.Ratio, and keep the Button selection logic unchanged so selectedRatio
still updates correctly.
In `@Sources/Blueprint/Sources/Utilities/PreviewLayout.swift`:
- Around line 408-429: The card-level DragGesture on the preview layout is
intercepting drag input from inner controls like SliderOptionRow and
TextAreaOptionRow. Move the drag handling out of the main card container in
PreviewLayout and attach it only to the handle area (the Capsule/header section)
so floating-mode option controls can receive their own gestures without
competing with card movement.
In `@Sources/Montage/1` Components/3 Selection And Input/TextArea.swift:
- Around line 429-432: The TextArea accessibility setup is overwriting the
field’s accessible value with only an error string or empty string, which can
prevent VoiceOver from reading the actual input text. Update the TextArea
modifier chain near the onTapGesture/accessibilityValue logic so the current
text remains exposed as the accessibilityValue, and move the error state into a
separate accessibilityHint or accessibilityLabel using the relevant TextArea
state such as negative.
- Around line 391-392: The TextAreaView onAppear handler is triggering
onTextChange(text) during the initial render, which violates the “only when
changed” contract. Update the TextArea.swift implementation around the
onAppear/onTextChange flow so the callback is not fired on first display, and
only invoke it from actual text-change handling paths; if this behavior is
intentional, make the contract explicit in the relevant API/documentation.
---
Outside diff comments:
In `@Sources/Blueprint/Sources/Scene/Previews/ColorPreview.swift`:
- Around line 27-52: `ColorPreview`의 `showTransparentChecker` 상태가 atomic 선택 시에도
유지되어 `AtomicColorSections`에 true가 전달되는 문제가 있습니다. `selectedColorTypeIndex`를 기준으로
분기하는 `Button`/`ScrollView` 흐름에서 atomic로 전환될 때 `showTransparentChecker`를 false로
리셋하거나, `AtomicColorSections(showTransparentChecker:)`에는 항상 false를 넘기도록 수정해 상태가
섞이지 않게 정리하세요.
In `@Sources/Blueprint/Sources/Scene/Previews/TextAreaPreview.swift`:
- Around line 169-174: The resize workaround in TextAreaPreview is mutating the
bound text value, which clears the user’s input whenever resize changes. Update
the .onChange(of: resize) handling in TextAreaPreview to refresh the layout
without changing text, and use a separate refresh trigger for TextArea such as a
dedicated refresh key or an .id(resize)-style split so the preview state stays
intact while only the layout is re-rendered.
---
Nitpick comments:
In `@Sources/Blueprint/Sources/Scene/Previews/IconButtonPreview.swift`:
- Around line 119-135: In IconButtonPreview’s modifying chain, replace the
force-unwrapped optional uses for iconColor, backgroundColor, and borderColor
with safe local binding. Update each conditional block in the preview builder to
use if let-style unwrapping before calling iconColor(...), backgroundColor(...),
and borderColor(...) so the behavior stays the same without relying on `!`. Keep
the changes scoped to the existing `.modifying` closures in IconButtonPreview.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: b03d4b42-36f6-42be-aaac-1c60d9c462c8
📒 Files selected for processing (64)
Sources/Blueprint/Blueprint.xcodeproj/project.pbxprojSources/Blueprint/Sources/Scene/ComponentList/ComponentListNavigationCoordinator.swiftSources/Blueprint/Sources/Scene/ComponentList/ComponentSection.swiftSources/Blueprint/Sources/Scene/Previews/AccordionPreview.swiftSources/Blueprint/Sources/Scene/Previews/ActionAreaPreview.swiftSources/Blueprint/Sources/Scene/Previews/AvatarGroupPreview.swiftSources/Blueprint/Sources/Scene/Previews/AvatarPreview.swiftSources/Blueprint/Sources/Scene/Previews/BottomSheetPreview.swiftSources/Blueprint/Sources/Scene/Previews/ButtonPreview.swiftSources/Blueprint/Sources/Scene/Previews/CardPreview.swiftSources/Blueprint/Sources/Scene/Previews/CategoryPreview.swiftSources/Blueprint/Sources/Scene/Previews/ChipPreview.swiftSources/Blueprint/Sources/Scene/Previews/ColorPreview.swiftSources/Blueprint/Sources/Scene/Previews/ContentBadgePreview.swiftSources/Blueprint/Sources/Scene/Previews/ControlPreview.swiftSources/Blueprint/Sources/Scene/Previews/DateTimePickerPreview.swiftSources/Blueprint/Sources/Scene/Previews/FallbackViewPreview.swiftSources/Blueprint/Sources/Scene/Previews/FilterButtonPreview.swiftSources/Blueprint/Sources/Scene/Previews/FlowLayoutPreview.swiftSources/Blueprint/Sources/Scene/Previews/FramedStylePreview.swiftSources/Blueprint/Sources/Scene/Previews/HorizontalProgressTrackerPreview.swiftSources/Blueprint/Sources/Scene/Previews/IconButtonPreview.swiftSources/Blueprint/Sources/Scene/Previews/IconPreview.swiftSources/Blueprint/Sources/Scene/Previews/ListCardPreview.swiftSources/Blueprint/Sources/Scene/Previews/ListCellPreview.swiftSources/Blueprint/Sources/Scene/Previews/LoadingPreview.swiftSources/Blueprint/Sources/Scene/Previews/ModalNavigationPreview.swiftSources/Blueprint/Sources/Scene/Previews/PageCounterPreview.swiftSources/Blueprint/Sources/Scene/Previews/PaginationDotsPreview.swiftSources/Blueprint/Sources/Scene/Previews/PaginationPreview.swiftSources/Blueprint/Sources/Scene/Previews/PlayBadgePreview.swiftSources/Blueprint/Sources/Scene/Previews/PopoverPreview.swiftSources/Blueprint/Sources/Scene/Previews/PopupPreview.swiftSources/Blueprint/Sources/Scene/Previews/ProgressIndicatorPreview.swiftSources/Blueprint/Sources/Scene/Previews/ProgressTrackerPreview.swiftSources/Blueprint/Sources/Scene/Previews/PullToRefreshPreview.swiftSources/Blueprint/Sources/Scene/Previews/PushBadgePreview.swiftSources/Blueprint/Sources/Scene/Previews/SectionHeaderPreview.swiftSources/Blueprint/Sources/Scene/Previews/SegmentedControlPreview.swiftSources/Blueprint/Sources/Scene/Previews/SelectPreview.swiftSources/Blueprint/Sources/Scene/Previews/ShadowPreview.swiftSources/Blueprint/Sources/Scene/Previews/SkeletonPreview.swiftSources/Blueprint/Sources/Scene/Previews/SliderPreview.swiftSources/Blueprint/Sources/Scene/Previews/SnackBarPreview.swiftSources/Blueprint/Sources/Scene/Previews/TabPreview.swiftSources/Blueprint/Sources/Scene/Previews/TextAreaPreview.swiftSources/Blueprint/Sources/Scene/Previews/TextButtonPreview.swiftSources/Blueprint/Sources/Scene/Previews/TextFieldPreview.swiftSources/Blueprint/Sources/Scene/Previews/ThumbnailPreview.swiftSources/Blueprint/Sources/Scene/Previews/ToastPreview.swiftSources/Blueprint/Sources/Scene/Previews/TooltipPreview.swiftSources/Blueprint/Sources/Scene/Previews/TopNavigationPreview.swiftSources/Blueprint/Sources/Scene/Previews/VerticalProgressTrackerPreview.swiftSources/Blueprint/Sources/Utilities/PreviewLayout.swiftSources/Blueprint/Sources/Utilities/PreviewOption.swiftSources/Montage/1 Components/3 Selection And Input/Slider.swiftSources/Montage/1 Components/3 Selection And Input/TextArea.swiftSources/Montage/1 Components/3 Selection And Input/TextField.swiftSources/Montage/1 Components/4 Contents/Thumbnail.swiftSources/Montage/1 Components/6 Navigations/TopNavigation.swiftSources/Montage/Asset/Localizable.xcstringsdocumentation/components/selection and input/textarea/ios.mddocumentation/components/selection and input/textfield/ios.mdpackages/montage-mcp/data/components.json
💤 Files with no reviewable changes (2)
- Sources/Blueprint/Sources/Scene/Previews/PaginationPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/ProgressTrackerPreview.swift
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@scripts/build_mcp_data.js`:
- Around line 175-179: The Instance Properties collection in build_mcp_data.js
is including inherited members such as body and description, so filter
extractMembers output to keep only properties declared on the current symbol.
Update the logic around instanceProps before assigning record.instanceProperties
so entries summarized with “Inherited from” are excluded, while keeping direct
members from the current type only.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: c3e15d5d-d77c-4203-bf91-d1da9a9927bb
📒 Files selected for processing (14)
Sources/Blueprint/Sources/Scene/Previews/AvatarGroupPreview.swiftSources/Blueprint/Sources/Scene/Previews/HorizontalProgressTrackerPreview.swiftSources/Blueprint/Sources/Scene/Previews/PageCounterPreview.swiftSources/Blueprint/Sources/Scene/Previews/PaginationDotsPreview.swiftSources/Blueprint/Sources/Scene/Previews/PushBadgePreview.swiftSources/Blueprint/Sources/Scene/Previews/SelectPreview.swiftSources/Blueprint/Sources/Scene/Previews/TextAreaPreview.swiftSources/Blueprint/Sources/Scene/Previews/TextFieldPreview.swiftSources/Blueprint/Sources/Scene/Previews/ThumbnailPreview.swiftSources/Blueprint/Sources/Utilities/PreviewLayout.swiftSources/Montage/1 Components/3 Selection And Input/TextArea.swiftpackages/montage-mcp/data/components.jsonpackages/montage-mcp/data/tokens.jsonscripts/build_mcp_data.js
🚧 Files skipped from review as they are similar to previous changes (10)
- Sources/Blueprint/Sources/Scene/Previews/PushBadgePreview.swift
- Sources/Blueprint/Sources/Scene/Previews/AvatarGroupPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/PageCounterPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/HorizontalProgressTrackerPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/ThumbnailPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/TextFieldPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/TextAreaPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/SelectPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/PaginationDotsPreview.swift
- Sources/Blueprint/Sources/Utilities/PreviewLayout.swift
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/montage-mcp/data/components.json (1)
2302-2307: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win요약 문자열이 잘려 MCP 설명 계약이 깨졌습니다.
Line 2302와 Line 2522의
summary가 각각infinity/trailing 전용 리소스 이름을 잃어서 의미가 불완전합니다. 생성기에서abstract의codeVoice같은 비-textfragment도 함께 합쳐 재생성해야 합니다.Also applies to: 2522-2527
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/montage-mcp/data/components.json` around lines 2302 - 2307, The `summary` text for the affected component entries is being truncated and loses meaning because non-text fragments are not being merged into the final MCP description. Update the generator that builds `components.json` so the `summary` for `rawValue` and the related `abstract` entry preserves all fragments, including `codeVoice` and other non-text pieces like `infinity`/trailing resource names, when composing the final string.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@packages/montage-mcp/data/components.json`:
- Around line 2302-2307: The `summary` text for the affected component entries
is being truncated and loses meaning because non-text fragments are not being
merged into the final MCP description. Update the generator that builds
`components.json` so the `summary` for `rawValue` and the related `abstract`
entry preserves all fragments, including `codeVoice` and other non-text pieces
like `infinity`/trailing resource names, when composing the final string.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: e3517e5d-4d1c-42d3-ac28-bffdf4e4c4d3
📒 Files selected for processing (2)
packages/montage-mcp/data/components.jsonscripts/build_mcp_data.js
PreviewLayout(stacked/overlay/pinnedTop)·PreviewOption 행 컴포넌트 신설, 6개 프리뷰 마이그레이션, ProgressTracker·Pagination 분기메뉴 제거 후 자식 프리뷰 직접 노출. # Conflicts: # Sources/Blueprint/Sources/Scene/Previews/TextFieldPreview.swift
stacked 다수 + overlay(Toast/Popup/Popover/BottomSheet/Select/DateTimePicker/ActionArea) + pinnedTop(ModalNavigation) 전환. Color/Icon 카탈로그·Loading·Typography는 bespoke 유지.
하단 고정 액션 바가 화면 하단에 floating되도록 .overlay 적용. overlayBody의 끝 Spacer를 제거해 greedy 미리보기가 남은 공간을 채우게 함(Toast/SnackBar는 EmptyView라 영향 없음).
패딩을 옵션 블록에만 적용하고 미리보기는 화면 너비를 채우도록 함. ActionArea 등 전체화면 컴포넌트의 배경·그래디언트·하단 바가 좌우 여백 없이 그려진다.
이미지 로더를 URL로 식별되는 내부 뷰(ThumbnailImageLoader)로 분리하고 .id(urlString) 적용. URL이 바뀌면 ImageManager가 새로 생성돼, 직전 로드의 stale 이미지/에러를 우선 표시하던 회귀(거꾸로/한 박자 지연)를 해결.
PreviewLayout이 미리보기 슬롯을 .frame(maxWidth: .infinity)로 가운데 정렬하고, 개별 프리뷰의 HStack { Spacer … Spacer } 래퍼를 제거.
PreviewLayout에 .floating 모드 신설: 미리보기를 전체화면으로 채우고 체커를 컨테이너가 자동 적용(previewCheckered 불필요), 옵션을 드래그로 옮길 수 있는 floating material 카드(DraggableCard)로 띄움. TopNavigation 프리뷰를 .floating으로 전환해 프로토타입 적용.
Blueprint 프리뷰: - TextAreaPreview: leading/trailing 리소스 제한을 suffix(3)→Array(prefix(3))로 수정 (타입 불일치·동작 정합) - 정수 도메인 슬라이더(Avatar/Pagination/PushBadge)에 step:1 명시 - PageCounter: totalPages 축소 시 selectedPage 클램프 - HorizontalProgressTracker: stepCount 변경 시 labels·progress를 함께 정규화해 모델 불일치 제거 - SelectPreview: customMenu 끌 때 열린 bottomSheet 정리 - TextFieldPreview: autoComplete 토글 시 자동완성 즉시 동기화 (helper 분리) - ThumbnailPreview: ForEach 식별자 hashValue→\.self - PreviewLayout: floating 옵션 카드 드래그를 핸들에만 적용해 내부 컨트롤과 충돌 방지 Montage: - TextArea: onTextChange 초기 렌더 호출 제거 (변경 시에만 호출 계약 준수) - TextArea: 오류 상태를 accessibilityValue 대신 accessibilityHint로 분리해 실제 입력값 노출 유지 MCP 데이터 생성기: - nested 타입의 Instance Properties를 추출하도록 보완 (TextArea.Resource.isLeadingAllowed 등 누락 해소) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D8gTT3K3Hci759WS9qMf8r
이전 커밋에서 nested 타입의 instanceProperties를 추출하면서 프로토콜 상속 멤버 (ModalNavigation.Variant.description, *.body 등)가 'Inherited from .' 요약으로 함께 노출되던 문제를 수정. DocC 상속 마커(abstract가 'Inherited from'으로 시작)를 가진 멤버를 extractMembers에서 건너뛴다. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D8gTT3K3Hci759WS9qMf8r
80c0a86 to
fc31f89
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (2)
Sources/Blueprint/Sources/Scene/Previews/TopNavigationPreview.swift (1)
36-40: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win프리뷰 로컬
@State는private으로 닫아 주세요.이 값들도 모두 뷰 내부 상태라 공개 범위를 넓힐 필요가 없습니다. 현재 변경분만으로도 SwiftLint 경고가 남습니다.
🔧 제안된 수정
- `@State` var variantIndex: Int = 0 + `@State` private var variantIndex: Int = 0 - `@State` var leading = false + `@State` private var leading = false - `@State` var trailing: [TrailingButton] = [] + `@State` private var trailing: [TrailingButton] = [] - `@State` var toast: Toast.Model? + `@State` private var toast: Toast.Model? - `@State` var backgroundColor: SwiftUI.Color = .clear + `@State` private var backgroundColor: SwiftUI.Color = .clear🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/Blueprint/Sources/Scene/Previews/TopNavigationPreview.swift` around lines 36 - 40, The preview-only `@State` properties in TopNavigationPreview should be scoped privately to avoid unnecessary exposure and the remaining SwiftLint warning. Update the local state declarations in the preview view by making the state members private while keeping their current behavior unchanged; focus on the TopNavigationPreview view’s variantIndex, leading, trailing, toast, and backgroundColor state.Source: Linters/SAST tools
Sources/Blueprint/Sources/Scene/Previews/LoadingPreview.swift (1)
13-18: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
@State는private으로 제한해 주세요.이 상태들은 모두
LoadingPreview내부 구현 세부사항이라 외부로 열어둘 이유가 없습니다. 지금 상태로는 SwiftLint 경고도 계속 남습니다.🔧 제안된 수정
- `@State` var typeOption: TypeOption = .circular + `@State` private var typeOption: TypeOption = .circular - `@State` var color: SwiftUI.Color = .clear + `@State` private var color: SwiftUI.Color = .clear - `@State` var dimmerColor: SwiftUI.Color = .semantic(.materialDimmer) + `@State` private var dimmerColor: SwiftUI.Color = .semantic(.materialDimmer) - `@State` var timeout: TimeInterval = 3 + `@State` private var timeout: TimeInterval = 3🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/Blueprint/Sources/Scene/Previews/LoadingPreview.swift` around lines 13 - 18, The stored properties in LoadingPreview are implementation details and should not be publicly exposed; update the `@State` declarations for typeOption, color, dimmerColor, and timeout to be private so they remain internal to the view and satisfy SwiftLint. Keep the change localized to LoadingPreview and preserve the existing default values and behavior.Source: Linters/SAST tools
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/montage-mcp/data/components.json`:
- Around line 2302-2307: The summary text for the affected component entries is
missing placeholder content, resulting in broken Korean sentences in the
generated MCP metadata. Update the source DocC or the generation path used for
components.json so that the summaries for rawValue and the other affected item
preserve the original placeholders and produce完整 문장, then regenerate the JSON to
ensure the published summary strings are correct.
In `@Sources/Blueprint/Sources/Scene/Previews/TextFieldPreview.swift`:
- Around line 143-145: Inside the Task closure in TextFieldPreview, the property
is being referenced without an explicit instance, which will not compile in this
context. Update the Task block to assign through self by using the
autoCompletionDataSource property on self, and keep the change localized to the
Task in TextFieldPreview so the compiler can resolve the member access
correctly.
In `@Sources/Blueprint/Sources/Scene/Previews/TopNavigationPreview.swift`:
- Around line 38-40: The TopNavigationPreview state is mixing manually
configured trailing buttons with the search-only trailing state, causing focus
changes to overwrite user-selected options. Split the state in
TopNavigationPreview so the options panel updates only the configured trailing
value, keep search-specific trailing behavior separate, and have
trailingContents derive from an effectiveTrailing value instead of sharing one
mutable array. Use the existing TopNavigationPreview, trailing, and
trailingContents symbols to locate and update the state flow consistently across
the affected sections.
---
Nitpick comments:
In `@Sources/Blueprint/Sources/Scene/Previews/LoadingPreview.swift`:
- Around line 13-18: The stored properties in LoadingPreview are implementation
details and should not be publicly exposed; update the `@State` declarations for
typeOption, color, dimmerColor, and timeout to be private so they remain
internal to the view and satisfy SwiftLint. Keep the change localized to
LoadingPreview and preserve the existing default values and behavior.
In `@Sources/Blueprint/Sources/Scene/Previews/TopNavigationPreview.swift`:
- Around line 36-40: The preview-only `@State` properties in TopNavigationPreview
should be scoped privately to avoid unnecessary exposure and the remaining
SwiftLint warning. Update the local state declarations in the preview view by
making the state members private while keeping their current behavior unchanged;
focus on the TopNavigationPreview view’s variantIndex, leading, trailing, toast,
and backgroundColor state.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 862246d3-df2f-4e7e-8ccf-b9f4cc25f2c7
📒 Files selected for processing (63)
Sources/Blueprint/Blueprint.xcodeproj/project.pbxprojSources/Blueprint/Sources/Scene/ComponentList/ComponentListNavigationCoordinator.swiftSources/Blueprint/Sources/Scene/ComponentList/ComponentSection.swiftSources/Blueprint/Sources/Scene/Previews/AccordionPreview.swiftSources/Blueprint/Sources/Scene/Previews/ActionAreaPreview.swiftSources/Blueprint/Sources/Scene/Previews/AvatarGroupPreview.swiftSources/Blueprint/Sources/Scene/Previews/AvatarPreview.swiftSources/Blueprint/Sources/Scene/Previews/BottomSheetPreview.swiftSources/Blueprint/Sources/Scene/Previews/ButtonPreview.swiftSources/Blueprint/Sources/Scene/Previews/CardPreview.swiftSources/Blueprint/Sources/Scene/Previews/CategoryPreview.swiftSources/Blueprint/Sources/Scene/Previews/ChipPreview.swiftSources/Blueprint/Sources/Scene/Previews/ColorPreview.swiftSources/Blueprint/Sources/Scene/Previews/ContentBadgePreview.swiftSources/Blueprint/Sources/Scene/Previews/ControlPreview.swiftSources/Blueprint/Sources/Scene/Previews/DateTimePickerPreview.swiftSources/Blueprint/Sources/Scene/Previews/FallbackViewPreview.swiftSources/Blueprint/Sources/Scene/Previews/FilterButtonPreview.swiftSources/Blueprint/Sources/Scene/Previews/FlowLayoutPreview.swiftSources/Blueprint/Sources/Scene/Previews/FramedStylePreview.swiftSources/Blueprint/Sources/Scene/Previews/HorizontalProgressTrackerPreview.swiftSources/Blueprint/Sources/Scene/Previews/IconButtonPreview.swiftSources/Blueprint/Sources/Scene/Previews/IconPreview.swiftSources/Blueprint/Sources/Scene/Previews/ListCardPreview.swiftSources/Blueprint/Sources/Scene/Previews/ListCellPreview.swiftSources/Blueprint/Sources/Scene/Previews/LoadingPreview.swiftSources/Blueprint/Sources/Scene/Previews/ModalNavigationPreview.swiftSources/Blueprint/Sources/Scene/Previews/PageCounterPreview.swiftSources/Blueprint/Sources/Scene/Previews/PaginationDotsPreview.swiftSources/Blueprint/Sources/Scene/Previews/PaginationPreview.swiftSources/Blueprint/Sources/Scene/Previews/PlayBadgePreview.swiftSources/Blueprint/Sources/Scene/Previews/PopoverPreview.swiftSources/Blueprint/Sources/Scene/Previews/PopupPreview.swiftSources/Blueprint/Sources/Scene/Previews/ProgressIndicatorPreview.swiftSources/Blueprint/Sources/Scene/Previews/ProgressTrackerPreview.swiftSources/Blueprint/Sources/Scene/Previews/PullToRefreshPreview.swiftSources/Blueprint/Sources/Scene/Previews/PushBadgePreview.swiftSources/Blueprint/Sources/Scene/Previews/SectionHeaderPreview.swiftSources/Blueprint/Sources/Scene/Previews/SegmentedControlPreview.swiftSources/Blueprint/Sources/Scene/Previews/SelectPreview.swiftSources/Blueprint/Sources/Scene/Previews/ShadowPreview.swiftSources/Blueprint/Sources/Scene/Previews/SkeletonPreview.swiftSources/Blueprint/Sources/Scene/Previews/SliderPreview.swiftSources/Blueprint/Sources/Scene/Previews/SnackBarPreview.swiftSources/Blueprint/Sources/Scene/Previews/TabPreview.swiftSources/Blueprint/Sources/Scene/Previews/TextAreaPreview.swiftSources/Blueprint/Sources/Scene/Previews/TextButtonPreview.swiftSources/Blueprint/Sources/Scene/Previews/TextFieldPreview.swiftSources/Blueprint/Sources/Scene/Previews/ThumbnailPreview.swiftSources/Blueprint/Sources/Scene/Previews/ToastPreview.swiftSources/Blueprint/Sources/Scene/Previews/TooltipPreview.swiftSources/Blueprint/Sources/Scene/Previews/TopNavigationPreview.swiftSources/Blueprint/Sources/Scene/Previews/VerticalProgressTrackerPreview.swiftSources/Blueprint/Sources/Utilities/PreviewLayout.swiftSources/Blueprint/Sources/Utilities/PreviewOption.swiftSources/Montage/1 Components/3 Selection And Input/Slider.swiftSources/Montage/1 Components/3 Selection And Input/TextArea.swiftSources/Montage/1 Components/4 Contents/Thumbnail.swiftSources/Montage/1 Components/6 Navigations/TopNavigation.swiftSources/Montage/Asset/Localizable.xcstringspackages/montage-mcp/data/components.jsonpackages/montage-mcp/data/tokens.jsonscripts/build_mcp_data.js
💤 Files with no reviewable changes (2)
- Sources/Blueprint/Sources/Scene/Previews/ProgressTrackerPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/PaginationPreview.swift
✅ Files skipped from review due to trivial changes (1)
- Sources/Montage/1 Components/3 Selection And Input/TextArea.swift
🚧 Files skipped from review as they are similar to previous changes (55)
- Sources/Blueprint/Sources/Scene/ComponentList/ComponentListNavigationCoordinator.swift
- Sources/Blueprint/Sources/Scene/Previews/ProgressIndicatorPreview.swift
- Sources/Montage/Asset/Localizable.xcstrings
- Sources/Montage/1 Components/3 Selection And Input/Slider.swift
- Sources/Blueprint/Sources/Scene/Previews/FlowLayoutPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/ShadowPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/AccordionPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/FilterButtonPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/ListCardPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/ToastPreview.swift
- Sources/Blueprint/Sources/Scene/ComponentList/ComponentSection.swift
- Sources/Blueprint/Sources/Scene/Previews/PaginationDotsPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/FallbackViewPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/PushBadgePreview.swift
- packages/montage-mcp/data/tokens.json
- Sources/Blueprint/Sources/Scene/Previews/SegmentedControlPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/SkeletonPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/PopoverPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/AvatarGroupPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/FramedStylePreview.swift
- Sources/Blueprint/Sources/Scene/Previews/PlayBadgePreview.swift
- scripts/build_mcp_data.js
- Sources/Blueprint/Sources/Scene/Previews/PageCounterPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/IconPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/ContentBadgePreview.swift
- Sources/Blueprint/Sources/Scene/Previews/VerticalProgressTrackerPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/ColorPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/PopupPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/ListCellPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/SectionHeaderPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/TabPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/ControlPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/SliderPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/TooltipPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/AvatarPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/BottomSheetPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/CategoryPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/ModalNavigationPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/SnackBarPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/PullToRefreshPreview.swift
- Sources/Montage/1 Components/6 Navigations/TopNavigation.swift
- Sources/Blueprint/Sources/Scene/Previews/SelectPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/ThumbnailPreview.swift
- Sources/Blueprint/Sources/Utilities/PreviewOption.swift
- Sources/Blueprint/Blueprint.xcodeproj/project.pbxproj
- Sources/Blueprint/Sources/Scene/Previews/ChipPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/IconButtonPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/DateTimePickerPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/CardPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/ActionAreaPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/HorizontalProgressTrackerPreview.swift
- Sources/Montage/1 Components/4 Contents/Thumbnail.swift
- Sources/Blueprint/Sources/Utilities/PreviewLayout.swift
- Sources/Blueprint/Sources/Scene/Previews/ButtonPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/TextAreaPreview.swift
There was a problem hiding this comment.
Caution
Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.
Actionable comments posted: 3
🧹 Nitpick comments (2)
Sources/Blueprint/Sources/Scene/Previews/TopNavigationPreview.swift (1)
36-40: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win프리뷰 로컬
@State는private으로 닫아 주세요.이 값들도 모두 뷰 내부 상태라 공개 범위를 넓힐 필요가 없습니다. 현재 변경분만으로도 SwiftLint 경고가 남습니다.
🔧 제안된 수정
- `@State` var variantIndex: Int = 0 + `@State` private var variantIndex: Int = 0 - `@State` var leading = false + `@State` private var leading = false - `@State` var trailing: [TrailingButton] = [] + `@State` private var trailing: [TrailingButton] = [] - `@State` var toast: Toast.Model? + `@State` private var toast: Toast.Model? - `@State` var backgroundColor: SwiftUI.Color = .clear + `@State` private var backgroundColor: SwiftUI.Color = .clear🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/Blueprint/Sources/Scene/Previews/TopNavigationPreview.swift` around lines 36 - 40, The preview-only `@State` properties in TopNavigationPreview should be scoped privately to avoid unnecessary exposure and the remaining SwiftLint warning. Update the local state declarations in the preview view by making the state members private while keeping their current behavior unchanged; focus on the TopNavigationPreview view’s variantIndex, leading, trailing, toast, and backgroundColor state.Source: Linters/SAST tools
Sources/Blueprint/Sources/Scene/Previews/LoadingPreview.swift (1)
13-18: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
@State는private으로 제한해 주세요.이 상태들은 모두
LoadingPreview내부 구현 세부사항이라 외부로 열어둘 이유가 없습니다. 지금 상태로는 SwiftLint 경고도 계속 남습니다.🔧 제안된 수정
- `@State` var typeOption: TypeOption = .circular + `@State` private var typeOption: TypeOption = .circular - `@State` var color: SwiftUI.Color = .clear + `@State` private var color: SwiftUI.Color = .clear - `@State` var dimmerColor: SwiftUI.Color = .semantic(.materialDimmer) + `@State` private var dimmerColor: SwiftUI.Color = .semantic(.materialDimmer) - `@State` var timeout: TimeInterval = 3 + `@State` private var timeout: TimeInterval = 3🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/Blueprint/Sources/Scene/Previews/LoadingPreview.swift` around lines 13 - 18, The stored properties in LoadingPreview are implementation details and should not be publicly exposed; update the `@State` declarations for typeOption, color, dimmerColor, and timeout to be private so they remain internal to the view and satisfy SwiftLint. Keep the change localized to LoadingPreview and preserve the existing default values and behavior.Source: Linters/SAST tools
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/montage-mcp/data/components.json`:
- Around line 2302-2307: The summary text for the affected component entries is
missing placeholder content, resulting in broken Korean sentences in the
generated MCP metadata. Update the source DocC or the generation path used for
components.json so that the summaries for rawValue and the other affected item
preserve the original placeholders and produce完整 문장, then regenerate the JSON to
ensure the published summary strings are correct.
In `@Sources/Blueprint/Sources/Scene/Previews/TextFieldPreview.swift`:
- Around line 143-145: Inside the Task closure in TextFieldPreview, the property
is being referenced without an explicit instance, which will not compile in this
context. Update the Task block to assign through self by using the
autoCompletionDataSource property on self, and keep the change localized to the
Task in TextFieldPreview so the compiler can resolve the member access
correctly.
In `@Sources/Blueprint/Sources/Scene/Previews/TopNavigationPreview.swift`:
- Around line 38-40: The TopNavigationPreview state is mixing manually
configured trailing buttons with the search-only trailing state, causing focus
changes to overwrite user-selected options. Split the state in
TopNavigationPreview so the options panel updates only the configured trailing
value, keep search-specific trailing behavior separate, and have
trailingContents derive from an effectiveTrailing value instead of sharing one
mutable array. Use the existing TopNavigationPreview, trailing, and
trailingContents symbols to locate and update the state flow consistently across
the affected sections.
---
Nitpick comments:
In `@Sources/Blueprint/Sources/Scene/Previews/LoadingPreview.swift`:
- Around line 13-18: The stored properties in LoadingPreview are implementation
details and should not be publicly exposed; update the `@State` declarations for
typeOption, color, dimmerColor, and timeout to be private so they remain
internal to the view and satisfy SwiftLint. Keep the change localized to
LoadingPreview and preserve the existing default values and behavior.
In `@Sources/Blueprint/Sources/Scene/Previews/TopNavigationPreview.swift`:
- Around line 36-40: The preview-only `@State` properties in TopNavigationPreview
should be scoped privately to avoid unnecessary exposure and the remaining
SwiftLint warning. Update the local state declarations in the preview view by
making the state members private while keeping their current behavior unchanged;
focus on the TopNavigationPreview view’s variantIndex, leading, trailing, toast,
and backgroundColor state.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 862246d3-df2f-4e7e-8ccf-b9f4cc25f2c7
📒 Files selected for processing (63)
Sources/Blueprint/Blueprint.xcodeproj/project.pbxprojSources/Blueprint/Sources/Scene/ComponentList/ComponentListNavigationCoordinator.swiftSources/Blueprint/Sources/Scene/ComponentList/ComponentSection.swiftSources/Blueprint/Sources/Scene/Previews/AccordionPreview.swiftSources/Blueprint/Sources/Scene/Previews/ActionAreaPreview.swiftSources/Blueprint/Sources/Scene/Previews/AvatarGroupPreview.swiftSources/Blueprint/Sources/Scene/Previews/AvatarPreview.swiftSources/Blueprint/Sources/Scene/Previews/BottomSheetPreview.swiftSources/Blueprint/Sources/Scene/Previews/ButtonPreview.swiftSources/Blueprint/Sources/Scene/Previews/CardPreview.swiftSources/Blueprint/Sources/Scene/Previews/CategoryPreview.swiftSources/Blueprint/Sources/Scene/Previews/ChipPreview.swiftSources/Blueprint/Sources/Scene/Previews/ColorPreview.swiftSources/Blueprint/Sources/Scene/Previews/ContentBadgePreview.swiftSources/Blueprint/Sources/Scene/Previews/ControlPreview.swiftSources/Blueprint/Sources/Scene/Previews/DateTimePickerPreview.swiftSources/Blueprint/Sources/Scene/Previews/FallbackViewPreview.swiftSources/Blueprint/Sources/Scene/Previews/FilterButtonPreview.swiftSources/Blueprint/Sources/Scene/Previews/FlowLayoutPreview.swiftSources/Blueprint/Sources/Scene/Previews/FramedStylePreview.swiftSources/Blueprint/Sources/Scene/Previews/HorizontalProgressTrackerPreview.swiftSources/Blueprint/Sources/Scene/Previews/IconButtonPreview.swiftSources/Blueprint/Sources/Scene/Previews/IconPreview.swiftSources/Blueprint/Sources/Scene/Previews/ListCardPreview.swiftSources/Blueprint/Sources/Scene/Previews/ListCellPreview.swiftSources/Blueprint/Sources/Scene/Previews/LoadingPreview.swiftSources/Blueprint/Sources/Scene/Previews/ModalNavigationPreview.swiftSources/Blueprint/Sources/Scene/Previews/PageCounterPreview.swiftSources/Blueprint/Sources/Scene/Previews/PaginationDotsPreview.swiftSources/Blueprint/Sources/Scene/Previews/PaginationPreview.swiftSources/Blueprint/Sources/Scene/Previews/PlayBadgePreview.swiftSources/Blueprint/Sources/Scene/Previews/PopoverPreview.swiftSources/Blueprint/Sources/Scene/Previews/PopupPreview.swiftSources/Blueprint/Sources/Scene/Previews/ProgressIndicatorPreview.swiftSources/Blueprint/Sources/Scene/Previews/ProgressTrackerPreview.swiftSources/Blueprint/Sources/Scene/Previews/PullToRefreshPreview.swiftSources/Blueprint/Sources/Scene/Previews/PushBadgePreview.swiftSources/Blueprint/Sources/Scene/Previews/SectionHeaderPreview.swiftSources/Blueprint/Sources/Scene/Previews/SegmentedControlPreview.swiftSources/Blueprint/Sources/Scene/Previews/SelectPreview.swiftSources/Blueprint/Sources/Scene/Previews/ShadowPreview.swiftSources/Blueprint/Sources/Scene/Previews/SkeletonPreview.swiftSources/Blueprint/Sources/Scene/Previews/SliderPreview.swiftSources/Blueprint/Sources/Scene/Previews/SnackBarPreview.swiftSources/Blueprint/Sources/Scene/Previews/TabPreview.swiftSources/Blueprint/Sources/Scene/Previews/TextAreaPreview.swiftSources/Blueprint/Sources/Scene/Previews/TextButtonPreview.swiftSources/Blueprint/Sources/Scene/Previews/TextFieldPreview.swiftSources/Blueprint/Sources/Scene/Previews/ThumbnailPreview.swiftSources/Blueprint/Sources/Scene/Previews/ToastPreview.swiftSources/Blueprint/Sources/Scene/Previews/TooltipPreview.swiftSources/Blueprint/Sources/Scene/Previews/TopNavigationPreview.swiftSources/Blueprint/Sources/Scene/Previews/VerticalProgressTrackerPreview.swiftSources/Blueprint/Sources/Utilities/PreviewLayout.swiftSources/Blueprint/Sources/Utilities/PreviewOption.swiftSources/Montage/1 Components/3 Selection And Input/Slider.swiftSources/Montage/1 Components/3 Selection And Input/TextArea.swiftSources/Montage/1 Components/4 Contents/Thumbnail.swiftSources/Montage/1 Components/6 Navigations/TopNavigation.swiftSources/Montage/Asset/Localizable.xcstringspackages/montage-mcp/data/components.jsonpackages/montage-mcp/data/tokens.jsonscripts/build_mcp_data.js
💤 Files with no reviewable changes (2)
- Sources/Blueprint/Sources/Scene/Previews/ProgressTrackerPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/PaginationPreview.swift
✅ Files skipped from review due to trivial changes (1)
- Sources/Montage/1 Components/3 Selection And Input/TextArea.swift
🚧 Files skipped from review as they are similar to previous changes (55)
- Sources/Blueprint/Sources/Scene/ComponentList/ComponentListNavigationCoordinator.swift
- Sources/Blueprint/Sources/Scene/Previews/ProgressIndicatorPreview.swift
- Sources/Montage/Asset/Localizable.xcstrings
- Sources/Montage/1 Components/3 Selection And Input/Slider.swift
- Sources/Blueprint/Sources/Scene/Previews/FlowLayoutPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/ShadowPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/AccordionPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/FilterButtonPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/ListCardPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/ToastPreview.swift
- Sources/Blueprint/Sources/Scene/ComponentList/ComponentSection.swift
- Sources/Blueprint/Sources/Scene/Previews/PaginationDotsPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/FallbackViewPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/PushBadgePreview.swift
- packages/montage-mcp/data/tokens.json
- Sources/Blueprint/Sources/Scene/Previews/SegmentedControlPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/SkeletonPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/PopoverPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/AvatarGroupPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/FramedStylePreview.swift
- Sources/Blueprint/Sources/Scene/Previews/PlayBadgePreview.swift
- scripts/build_mcp_data.js
- Sources/Blueprint/Sources/Scene/Previews/PageCounterPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/IconPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/ContentBadgePreview.swift
- Sources/Blueprint/Sources/Scene/Previews/VerticalProgressTrackerPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/ColorPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/PopupPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/ListCellPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/SectionHeaderPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/TabPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/ControlPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/SliderPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/TooltipPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/AvatarPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/BottomSheetPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/CategoryPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/ModalNavigationPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/SnackBarPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/PullToRefreshPreview.swift
- Sources/Montage/1 Components/6 Navigations/TopNavigation.swift
- Sources/Blueprint/Sources/Scene/Previews/SelectPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/ThumbnailPreview.swift
- Sources/Blueprint/Sources/Utilities/PreviewOption.swift
- Sources/Blueprint/Blueprint.xcodeproj/project.pbxproj
- Sources/Blueprint/Sources/Scene/Previews/ChipPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/IconButtonPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/DateTimePickerPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/CardPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/ActionAreaPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/HorizontalProgressTrackerPreview.swift
- Sources/Montage/1 Components/4 Contents/Thumbnail.swift
- Sources/Blueprint/Sources/Utilities/PreviewLayout.swift
- Sources/Blueprint/Sources/Scene/Previews/ButtonPreview.swift
- Sources/Blueprint/Sources/Scene/Previews/TextAreaPreview.swift
🛑 Comments failed to post (3)
packages/montage-mcp/data/components.json (1)
2302-2307: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash GEN="$(fd -HI '^build_mcp_data\.js$' . | head -n1)" echo "generator: ${GEN:-not found}" rg -n '인 경우|trailing 전용|rawValue|isLeadingAllowed' \ packages/montage-mcp/data/components.json \ "${GEN:-/dev/null}"Repository: wanteddev/montage-ios
Length of output: 889
🏁 Script executed:
#!/bin/bash set -euo pipefail echo '--- generator outline ---' ast-grep outline scripts/build_mcp_data.js --view expanded | sed -n '1,220p' echo echo '--- search generator for summary/doc handling ---' rg -n 'summary|doc|comment|trim|normalize|sanitize|rawValue|isLeadingAllowed|trailing 전용|인 경우' scripts/build_mcp_data.js echo echo '--- locate source definitions/usages ---' rg -n 'rawValue|isLeadingAllowed' packages scripts | sed -n '1,120p'Repository: wanteddev/montage-ios
Length of output: 2974
🏁 Script executed:
#!/bin/bash set -euo pipefail echo '--- exact summary strings in repo ---' rg -n '스낵바가 표시되는 시간\(초\)\. 인 경우 를 반환합니다\.|leading\(왼쪽\)에 배치할 수 있는 리소스인지 여부\. ·은 trailing 전용입니다\.' . echo echo '--- nearby generator implementation ---' sed -n '60,180p' scripts/build_mcp_data.jsRepository: wanteddev/montage-ios
Length of output: 4548
요약 문자열의 자리표시자가 유실됐습니다.
packages/montage-mcp/data/components.json:2306과packages/montage-mcp/data/components.json:2526의 summary에인 경우 를 반환합니다./·은 trailing 전용입니다.같은 깨진 문장이 들어가 있습니다. MCP 소비자에게 잘못된 설명이 노출되니, 이 두 항목의 원문 DocC 또는 생성 경로에서 placeholder가 빠지지 않도록 보정해 주세요.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/montage-mcp/data/components.json` around lines 2302 - 2307, The summary text for the affected component entries is missing placeholder content, resulting in broken Korean sentences in the generated MCP metadata. Update the source DocC or the generation path used for components.json so that the summaries for rawValue and the other affected item preserve the original placeholders and produce完整 문장, then regenerate the JSON to ensure the published summary strings are correct.Sources/Blueprint/Sources/Scene/Previews/TextFieldPreview.swift (1)
143-145: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash rg -n -C 2 'Task\s*\{' Sources/Blueprint/Sources/Scene/Previews/TextFieldPreview.swiftRepository: wanteddev/montage-ios
Length of output: 404
Task안에서는self를 명시해 주세요.
143-145의Task {}안에서autoCompletionDataSource를 그대로 참조하면 컴파일되지 않습니다.self.autoCompletionDataSource = nil로 바꿔 주세요.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/Blueprint/Sources/Scene/Previews/TextFieldPreview.swift` around lines 143 - 145, Inside the Task closure in TextFieldPreview, the property is being referenced without an explicit instance, which will not compile in this context. Update the Task block to assign through self by using the autoCompletionDataSource property on self, and keep the change localized to the Task in TextFieldPreview so the compiler can resolve the member access correctly.Source: Path instructions
Sources/Blueprint/Sources/Scene/Previews/TopNavigationPreview.swift (1)
38-40: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
수동 trailing 옵션과 search 전용 trailing 상태를 같은 배열로 관리하면 상태가 깨집니다.
지금은 옵션 패널에서 추가한
trailing값과.searchvariant의 포커스 연동 값이 같은 상태를 공유합니다. 그래서 사용자가 옵션에서 추가한 버튼이 포커스 변화로 덮어써지고, search variant를 다녀온 뒤 비-search variant의 trailing 구성이 이전 포커스 이력에 따라 달라집니다. 수동 설정 상태와 search 전용 표시 상태를 분리해서, 최종trailingContents만 계산해서 만드는 편이 안전합니다.🔧 방향 제안
- `@State` private var trailing: [TrailingButton] = [] + `@State` private var configuredTrailing: [TrailingButton] = [] + + private var effectiveTrailing: [TrailingButton] { + isSearchVariant && focused ? [.text] : configuredTrailing + }옵션 패널은
configuredTrailing만 수정하고,trailingContents는effectiveTrailing을 기준으로 만들면 포커스 변화가 사용자 설정을 덮어쓰지 않게 됩니다.Also applies to: 123-133, 178-183
🧰 Tools
🪛 SwiftLint (0.64.0)
[Warning] 38-38: SwiftUI state properties should be private
(private_swiftui_state)
[Warning] 39-39: SwiftUI state properties should be private
(private_swiftui_state)
[Warning] 40-40: SwiftUI state properties should be private
(private_swiftui_state)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Sources/Blueprint/Sources/Scene/Previews/TopNavigationPreview.swift` around lines 38 - 40, The TopNavigationPreview state is mixing manually configured trailing buttons with the search-only trailing state, causing focus changes to overwrite user-selected options. Split the state in TopNavigationPreview so the options panel updates only the configured trailing value, keep search-specific trailing behavior separate, and have trailingContents derive from an effectiveTrailing value instead of sharing one mutable array. Use the existing TopNavigationPreview, trailing, and trailingContents symbols to locate and update the state flow consistently across the affected sections.
- MCP 데이터 생성기: abstractText가 codeVoice·reference·중첩 inline까지 포함하도록 보완. 기존엔 text 세그먼트만 이어붙여 'スナックバ... .infinity인 경우 ...' 처럼 placeholder가 빠진 깨진 한국어 요약이 생성되던 문제를 수정하고 components.json/tokens.json 재생성 - TextFieldPreview: Task 클로저 내 autoCompletionDataSource를 self로 명시 - LoadingPreview·TopNavigationPreview: 프리뷰 로컬 @State를 private으로 제한 (SwiftLint) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D8gTT3K3Hci759WS9qMf8r
|
리뷰(pullrequestreview-4589975454) 반영 완료 (124eff8). 인라인 코멘트가 GitHub 오류로 등록 실패해 본문에만 남아, 항목별로 여기에 정리합니다. Actionable (3)
Nitpick (2)
검증: Montage(docc)·Blueprint 빌드 통과, |
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D8gTT3K3Hci759WS9qMf8r
…y-faraday-ac366a # Conflicts: # Sources/Blueprint/Sources/Scene/Previews/TextAreaPreview.swift
개요
Blueprint 샘플 앱의 각 프리뷰가 제각각 작성하던 옵션 행(raw
Switch/SegmentedControl/Slider/TextField/ColorPicker/Menu등)을 공용 OptionRow 컴포넌트로 통합했습니다.수정사항
공용 헬퍼 (
PreviewOption.swift)SegmentedOptionRow/SegmentedIndexRow:title옵셔널화(라벨 없이 다른 컨트롤 옆 인라인 배치 가능),onSelect콜백 추가SliderOptionRow:onEditingEnded콜백 추가TextFieldOptionRow:placeholder추가ColorPickerOptionRow,MenuOptionRow(+ accessory),TextAreaOptionRow,PrevNextOptionRowPreviewLayout:options가EmptyView이면 "Options" 헤더를 그리지 않음적용
PrevNextOptionRow로 통합TextAreaOptionRow로 교체기타 (별도 커밋)
fix: 단일SliderheadingLabel을 highValue만 표시하도록 정정refactor:TopNavigation미사용 navigationBar 코드 제거 및 기본 배경 정리미리보기