Skip to content

Design/#17 - DVTextField/DVTextContainer 컴포넌트 구현#20

Merged
doyeonk429 merged 4 commits into
developfrom
design/#17
May 24, 2026
Merged

Design/#17 - DVTextField/DVTextContainer 컴포넌트 구현#20
doyeonk429 merged 4 commits into
developfrom
design/#17

Conversation

@doyeonk429

@doyeonk429 doyeonk429 commented May 24, 2026

Copy link
Copy Markdown
Contributor

✨ What’s this PR?

📌 관련 이슈 (Related Issue)


🧶 주요 변경 내용 (Summary)

공통 토큰Projects/DVDesign/Sources/Foundations/Sizing/DVComponentSize.swift

  • xs / sm / md / lg 4단계 enum, width 프로퍼티로 Figma 스펙 너비 노출 (180 / 330 / 380 / 700pt)
  • 입력/표시 계열 컴포넌트가 공유하도록 Foundations 레이어로 분리

DVTextField — 시스템 TextField 최대 활용

  • SwiftUI TextField + .textFieldStyle(.plain) 위에 디자인 토큰만 덧입힘 — IME(한글), 접근성, 키보드 단축키, .onSubmit / .focused / .disabled
    모든 시스템 modifier 호환
  • .tint(Color.dv(.vaultGreen))으로 커서 색만 디자인 시스템에 맞춤
  • prompt: 파라미터로 placeholder 색(gray400) 적용
  • Figma의 4가지 variant(Empty/Placeholder/Active/Focus)는 시스템 TextField의 자연스러운 상태 변화로 표현 (border는 모든 상태에서 gray300 유지)

DVTextContainer — read-only 표시 + 인터랙티브 액세서리

  • 4가지 init 패턴:
Init 용도
init(_:size:) 액세서리 없음 (좌우 8pt 대칭 padding)
init(secured:isRevealed:size:) 비밀번호 마스킹 + 눈 토글 (Figma의 PW_Visability)
init(copyable:size:onCopy:) 복사 버튼 (클립보드 로직은 호출자 책임 — 레이어 분리)
init(_:size:onTap:icon:) 임의 아이콘 + 액션 쌍 주입
init(_:size:accessories:) 멀티 액세서리 등 자유 구성
  • 액세서리는 항상 인터랙티브(Button 기반)로 사용한다는 전제 — 정적 장식 아이콘은 설계에서 제외
  • 오버플로우 시 잘리지 않고 가로 스크롤(ScrollView(.horizontal, showsIndicators: false)) — 트랙패드/마우스 휠로 가려진 부분 확인 가능
  • 텍스트와 액세서리 사이 최소 8pt 간격 보장 (HStack spacing 8)
  • .textSelection(.enabled) — 마우스 드래그로 텍스트 선택 + ⌘+C 복사

SampleApp 프리뷰

  • TextFieldPreviewView — Placeholder/Active 상태 + XS/SM/MD/LG 사이즈
  • TextContainerPreviewView — Filled/Empty + 인터랙티브(secured/copyable/onTap/멀티) + 가로 스크롤 케이스 + 사이즈
  • copyable 케이스는 NSPasteboard 호출 + 피드백 라벨(컨테이너별 state 분리)
  • onTap 케이스는 SwiftUI openURL environment로 실제 브라우저 호출
  • ContentView 라우팅에 DVTextField / DVTextContainer 연결

문서화

  • Swift DocC 한국어 상세 주석 — 시각 상태/오버플로우/액세서리/텍스트 선택 섹션, 4가지 init 패턴 비교 표, 코드 예제
  • 토큰 간 크로스 레퍼런스(DVColor/gray900, DVFont/bodyLG, DVComponentSize/md)

📸 스크린샷 (Optional)

2026-05-24.5.03.58.mov

🧪 테스트 / 검증 내역

  • tuist generate 정상 완료
  • xcodebuild -scheme DVDesign 빌드 성공
  • xcodebuild -scheme DVDesignSampleApp 빌드 성공
  • DVTextField #Preview 3개(Placeholder/Active/Sizes) 렌더링 확인
  • DVTextContainer #Preview 6개(Filled/Empty/Secured/Copyable/Interactive/Sizes) 렌더링 확인
  • SampleApp 실행 → TextField/TextContainer 페이지 진입 후:
    • Tab/Space 키 입력 동작
    • 가로 스크롤 (긴 텍스트 케이스 트랙패드 두 손가락)
    • 마우스 드래그 선택 + ⌘+C 복사
    • secured 토글, copyable 클립보드+피드백, onTap 브라우저 열기 동작
  • My Mac, macOS 14+ 환경에서 정상 동작

💬 기타 공유 사항

  • 시스템 컴포넌트 활용 정책: 이슈에 명시된 "System Textfield 최대 활용" 요구사항에 따라 입력 동작·접근성·IME·키보드 단축키를 시스템 TextField가 그대로 제공하도록 두고, 시각 속성만 디자인 토큰으로 덧입혔습니다. 호출자는 .onSubmit, .focused, .disabled 등 모든 SwiftUI modifier를 그대로 사용할 수 있습니다.
  • 레이어 분리: DVTextContainer(copyable:)doc.on.doc 아이콘과 버튼 styling만 제공하고, 실제 NSPasteboard 호출은 호출자 책임으로 둬서 DVDesign 모듈이 AppKit에 의존하지 않도록 했습니다.
  • 액세서리 설계 의도: 정적 장식 아이콘 케이스는 사실상 사용되지 않으므로 설계와 프리뷰에서 의도적으로 제외했습니다. 모든 액세서리는 인터랙티브(Button 기반) 전제.

🙇🏻‍♀️ 리뷰 가이드 (선택)

  • DVComponentSize.swift: 다른 컴포넌트에서도 재사용할 공통 토큰. 추후 fontSize/height 등 다른 메트릭이 추가될 때 확장 방향에 대한 의견
  • DVTextField.swift: .textFieldStyle(.plain) + 외부 시각 wrapping 패턴이 시스템 modifier 호환성을 해치지 않는지 (특히 .font/.foregroundStyle
    내부에서 강제 적용되는 점)
  • DVTextContainer.swift: 4가지 init 분기 구조(AnyView 기반 편의 init vs generic 기본 init). 그리고 trailing padding 분기(액세서리 유무에 따른 4/8pt)가
    stored property로 처리되는 방식
  • 오버플로우 + 가로 스크롤 + 8pt 최소 간격 + .textSelection 조합이 의도대로 동작하는지 (SampleApp의 긴 텍스트 케이스 참고)

Summary by CodeRabbit

릴리스 노트

  • New Features
    • 텍스트 입력 필드 컴포넌트 추가 (다양한 상태 및 크기 지원)
    • 읽기 전용 텍스트 표시 컴포넌트 추가 (클립보드 복사, 텍스트 마스킹, 커스텀 액세서리 기능 포함)
    • 컴포넌트 사이즈 옵션 추가 (XS, SM, MD, LG)
    • 각 컴포넌트별 인터랙티브 프리뷰 추가

Review Change Stack

- DVTextField/DVTextContainer 등 입력·표시 계열 컴포넌트가 공유하는 사이즈 enum
- xs/sm/md/lg 4단계, 각각 180/330/380/700pt width 매핑 (Figma 스펙)
- Foundations/Sizing 디렉토리로 분리하여 향후 다른 컴포넌트 확장 대비
- DVTextField: 시스템 SwiftUI TextField + .textFieldStyle(.plain) + .tint(.vaultGreen) 조합
- DVTextContainer: read-only 박스 + 인터랙티브 액세서리 지원
- 편의 init 3종 — secured(마스킹+눈 토글), copyable(복사), onTap:icon:(커스텀 단일)
- .textSelection(.enabled)로 마우스 드래그 선택·복사 지원
- 액세서리 없음: 좌우 8pt 대칭 padding / 있음: trailing 4pt
- Swift DocC 한국어 상세 주석
- TextFieldPreviewView: Placeholder/Active 상태 + XS/SM/MD/LG 사이즈 케이스
- TextContainerPreviewView: Filled/Empty + Interactive(secured/copyable/onTap/멀티 액세서리) + 사이즈
- 가로 스크롤 동작 확인용 긴 텍스트 케이스 포함
- copyable 케이스는 NSPasteboard 직접 호출 + 피드백 라벨 (컨테이너별 state 분리)
- onTap 케이스는 SwiftUI openURL environment로 실제 브라우저 호출
- ContentView에 DVTextField/DVTextContainer 라우팅 추가
@doyeonk429
doyeonk429 requested review from dlguszoo and yeseonglee May 24, 2026 10:04
@doyeonk429 doyeonk429 self-assigned this May 24, 2026
@doyeonk429 doyeonk429 added the 🎨 Design UI 디자인 작업 label May 24, 2026
@doyeonk429 doyeonk429 linked an issue May 24, 2026 that may be closed by this pull request
3 tasks
@coderabbitai

coderabbitai Bot commented May 24, 2026

Copy link
Copy Markdown

Walkthrough

텍스트 입출력 컴포넌트 시스템을 추가합니다. 공유 사이징 토큰 DVComponentSize를 정의한 뒤, SwiftUI 기반 DVTextField(입력)와 DVTextContainer(표시)를 구현하고, 각각의 상태/상호작용을 보여주는 프리뷰 뷰를 SampleApp에 작성하며, ContentView에서 라우팅하도록 통합합니다.

Changes

텍스트 입출력 컴포넌트 시스템

Layer / File(s) Summary
컴포넌트 사이징 토큰
Projects/DVDesign/Sources/Foundations/Sizing/DVComponentSize.swift
DVComponentSize 열거형(xs/sm/md/lg)을 추가해 입출력 컴포넌트들이 공유할 고정 너비 값을 제공합니다.
DVTextField 컴포넌트 및 프리뷰
Projects/DVDesign/Sources/Components/DVTextField.swift
SwiftUI TextField 래퍼로 prompt/스타일(폰트, 전경색, tint)/패딩/회색 외곽선을 일관되게 적용하고, placeholder/active/sizes 상태 프리뷰를 포함합니다.
DVTextContainer 컴포넌트 및 변형
Projects/DVDesign/Sources/Components/DVTextContainer.swift
가로 스크롤 단일행 텍스트와 우측 액세서리 조합 컴포넌트를 구현하며, 기본/secured(마스킹+reveal)/copyable(복사 버튼) 변형을 조건부 확장으로 제공하고, 프리뷰 케이스를 포함합니다.
TextFieldPreviewView: 프리뷰 앱
Projects/DVDesign/SampleApp/Sources/TextFieldPreviewView.swift
DVTextField의 상태(비어있음/채워짐) 및 XS~LG 사이즈를 스크롤 가능하게 표시하며, 섹션/라벨 제너릭 헬퍼(@ViewBuilder)를 제공합니다.
TextContainerPreviewView: 프리뷰 앱
Projects/DVDesign/SampleApp/Sources/TextContainerPreviewView.swift
DVTextContainer의 상태, 액세서리 상호작용(클립보드 복사+피드백, reveal 토글, URL 오픈), 사이즈를 스크롤 가능하게 표시하며, NSPasteboard 복사와 상태 바인딩을 활용합니다.
ContentView 라우팅 추가
Projects/DVDesign/SampleApp/Sources/ContentView.swift
detailView(for:)에서 "DVTextField"/"DVTextContainer" 케이스를 추가해 각 프리뷰 뷰를 분기 반환합니다.

Sequence Diagram(s)

(지표 기준: 새로운 컴포넌트 추가, 단순한 초기화 및 스타일 적용으로 제어 흐름이 자명해 다이어그램 생략)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~35 minutes

Possibly related PRs

Suggested reviewers

  • yeseonglee
  • dlguszoo
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목이 주요 변경사항(DVTextField/DVTextContainer 컴포넌트 구현)을 정확하고 명확하게 요약하고 있습니다.
Linked Issues check ✅ Passed PR이 #17의 모든 코딩 요구사항을 충족합니다: System TextField 최대 활용 [DVTextField.swift], DVTextContainer 개발 [DVTextContainer.swift], SampleApp 프리뷰 제공 [TextFieldPreviewView/TextContainerPreviewView].
Out of Scope Changes check ✅ Passed 모든 변경사항이 #17 요구사항 범위 내입니다: 컴포넌트 구현, 공유 토큰(DVComponentSize), 프리뷰 화면이 주요 변경사항입니다.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch design/#17

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

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (6)
Projects/DVDesign/SampleApp/Sources/ContentView.swift (1)

3-4: 💤 Low value

임포트 그룹화 개선 제안

시스템 프레임워크(SwiftUI)와 로컬 모듈(DVDesign) 사이에 빈 줄을 추가하면 가독성이 향상됩니다.

♻️ 제안하는 수정
 import SwiftUI
+
 import DVDesign

코딩 가이드라인 기준: "모듈 임포트가 알파벳 순으로 정렬되어 있는지 확인하세요. (내장 프레임워크 먼저, 빈 줄로 서드파티 구분)"

🤖 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 `@Projects/DVDesign/SampleApp/Sources/ContentView.swift` around lines 3 - 4,
Add a blank line between the system framework import and the local module import
so imports are grouped and more readable: ensure "import SwiftUI" appears first
(system/framework imports), then a blank line, then "import DVDesign"
(local/third-party), and verify imports remain alphabetized within their groups.
Projects/DVDesign/Sources/Foundations/Sizing/DVComponentSize.swift (1)

3-3: ⚡ Quick win

Foundations 토큰 파일의 UI 프레임워크 의존성을 줄이세요.

DVComponentSizeCGFloat만 사용하므로 SwiftUI 대신 CoreGraphics를 import하면 레이어 결합도를 낮출 수 있습니다.

♻️ 제안 diff
-import SwiftUI
+import CoreGraphics
🤖 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 `@Projects/DVDesign/Sources/Foundations/Sizing/DVComponentSize.swift` at line
3, DVComponentSize currently imports SwiftUI unnecessarily; replace the SwiftUI
dependency with CoreGraphics since DVComponentSize only uses CGFloat. Open the
file containing DVComponentSize, remove the "import SwiftUI" statement and add
"import CoreGraphics" instead, and verify there are no SwiftUI types referenced
elsewhere in the DVComponentSize declaration or related helpers.
Projects/DVDesign/Sources/Components/DVTextContainer.swift (1)

118-139: ⚡ Quick win

body의 중첩 레이아웃을 private var/func로 분리해 주세요.

현재 body에 텍스트 스크롤/스타일/컨테이너 스타일이 한 번에 모여 있어 변경 지점 추적이 어렵습니다. textContent, containerBackground 같은 private 멤버로 분리하면 유지보수가 쉬워집니다.

♻️ 제안 diff
 public var body: some View {
-    // spacing 8 — 텍스트(또는 가로 스크롤된 콘텐츠)와 액세서리 사이 최소 간격.
-    // 텍스트가 오버플로우되어 ScrollView 우측 끝까지 스크롤되더라도 이 8pt가 보장됨.
     HStack(spacing: 8) {
-        ScrollView(.horizontal, showsIndicators: false) {
-            Text(text)
-                .font(DVFont.bodyLG.font)
-                .foregroundStyle(Color.dv(.gray900))
-                .lineLimit(1)
-                .fixedSize(horizontal: true, vertical: false)
-                .textSelection(.enabled)
-        }
+        textContent
         accessories()
     }
     .padding(.leading, 8)
     .padding(.trailing, trailingPadding)
     .frame(width: size.width, height: 28, alignment: .leading)
-    .background {
-        RoundedRectangle(cornerRadius: 6)
-            .fill(Color.dv(.gray300))
-    }
+    .background { containerBackground }
 }
+
+private var textContent: some View {
+    ScrollView(.horizontal, showsIndicators: false) {
+        Text(text)
+            .font(DVFont.bodyLG.font)
+            .foregroundStyle(Color.dv(.gray900))
+            .lineLimit(1)
+            .fixedSize(horizontal: true, vertical: false)
+            .textSelection(.enabled)
+    }
+}
+
+private var containerBackground: some View {
+    RoundedRectangle(cornerRadius: 6)
+        .fill(Color.dv(.gray300))
+}
As per coding guidelines "var body 안에 중첩 레이아웃이 직접 구현되어 있으면 extension의 private var/func로 분리를 제안하세요."
🤖 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 `@Projects/DVDesign/Sources/Components/DVTextContainer.swift` around lines 118
- 139, Split the nested layout inside the public var body into small private
members: extract the ScrollView+Text block into a private var/func named
textContent (preserve Text modifiers: .font(DVFont.bodyLG.font),
.foregroundStyle(Color.dv(.gray900)), .lineLimit(1), .fixedSize(horizontal:
true, vertical: false), .textSelection(.enabled)), extract the RoundedRectangle
background into a private var/func containerBackground, and compose the HStack
(HStack(spacing: 8) { textContent; accessories() }) plus paddings/ frame into a
private var/func (e.g., mainContent) so body simply returns
mainContent.background(containerBackground()); keep references to accessories(),
trailingPadding, and size unchanged. Ensure accessibility and modifiers are
preserved exactly when moving code to the private members.
Projects/DVDesign/SampleApp/Sources/TextFieldPreviewView.swift (1)

14-63: ⚡ Quick win

body의 중첩 레이아웃은 섹션 단위 private var/func로 분리해 주세요.

Line 14-35의 본문이 길고, Line 42-63 하위뷰 헬퍼가 본 타입 내부에 있어 읽기 흐름이 무거워졌습니다. statusSection, sizeSection 같은 private var로 쪼개고, 헬퍼는 extension TextFieldPreviewView로 이동하면 유지보수가 쉬워집니다.

As per coding guidelines "var body 안에 중첩 레이아웃이 직접 구현되어 있으면 extensionprivate var/func로 분리를 제안하세요." 및 "하위뷰가 extension 밖에 선언되어 있으면 이동을 제안하세요."

🤖 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 `@Projects/DVDesign/SampleApp/Sources/TextFieldPreviewView.swift` around lines
14 - 63, Extract the large nested layout inside var body into separate private
computed properties like private var statusSection and private var sizeSection
returning some View, move the helper view builders section(...) and labeled(...)
out of the main type into an extension TextFieldPreviewView as private
functions, and update body to compose using statusSection and sizeSection; this
keeps the DVTextField rows and VStack structure unchanged but relocates section
and labeled to the extension and replaces the inline blocks in body with the new
private vars.
Projects/DVDesign/SampleApp/Sources/TextContainerPreviewView.swift (2)

15-140: ⚡ Quick win

프리뷰 본문과 하위뷰 헬퍼를 extension 기반으로 분리해 주세요.

Line 15-113의 레이아웃이 길고, Line 120-140 하위뷰 헬퍼가 본 타입 내부에 있어 탐색 비용이 큽니다. 섹션별 private var/func 분리 + extension TextContainerPreviewView 이동을 권장합니다.

As per coding guidelines "var body 안에 중첩 레이아웃이 직접 구현되어 있으면 extensionprivate var/func로 분리를 제안하세요." 및 "하위뷰가 extension 밖에 선언되어 있으면 이동을 제안하세요."

🤖 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 `@Projects/DVDesign/SampleApp/Sources/TextContainerPreviewView.swift` around
lines 15 - 140, The body contains large nested layout and helper methods
(section(_:content:), labeled(_:content:), copyToClipboard(_:)) defined inside
the main type; extract the helper view builders and clipboard helper into a
private extension of TextContainerPreviewView to reduce noise in var body. Move
the implementations of section(title:content:), labeled(_:content:) and
copyToClipboard(_:) out of the main type body and into an extension
TextContainerPreviewView { private func/var ... } (keeping their signatures and
access control), and update any references in var body to use these moved
helpers.

10-11: ⚡ Quick win

Bool 상태명은 is 접두사로 통일해 주세요.

manualRevealed, securedRevealed는 Bool 의미가 즉시 드러나지 않습니다. isManualRevealed, isSecuredRevealed로 바꾸면 가독성이 좋아집니다.

As per coding guidelines "Bool 프로퍼티에 is, has, can 등의 접두사가 있는지 확인하세요."

Also applies to: 52-53, 72-73, 83-85

🤖 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 `@Projects/DVDesign/SampleApp/Sources/TextContainerPreviewView.swift` around
lines 10 - 11, Rename the Bool `@State` properties manualRevealed and
securedRevealed to isManualRevealed and isSecuredRevealed respectively, and
update all references/usages (bindings, view logic, toggles) to the new names;
also apply the same is-prefixed rename to the other Bool properties noted in the
review (the ones referenced at 52-53, 72-73, 83-85) so all boolean state names
follow the is/has/can convention and preserve existing behavior.
🤖 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 `@Projects/DVDesign/SampleApp/Sources/TextContainerPreviewView.swift`:
- Line 13: The stored URL is force-unwrapped via the externalURL constant which
risks crashes; change externalURL to be Optional (e.g., private let externalURL:
URL?) and then safely unwrap it at its usage sites (the preview/initialization
code that constructs the preview) using guard let / if let or provide a sensible
fallback (??) before passing into TextContainerPreviewView or any initializer;
update references to externalURL (and any preview construction) to handle the
optional safely rather than using !.

In `@Projects/DVDesign/SampleApp/Sources/TextFieldPreviewView.swift`:
- Around line 7-25: The preview state variables are being reused across multiple
DVTextField samples (e.g., emptyValue is bound at lines where the placeholder,
focus and other samples are rendered), causing interactions to bleed between
examples; introduce distinct `@State` properties for each preview instance (e.g.,
emptyPlaceholderValue, focusValue, activeValue, xsValue, smValue, mdValue,
lgValue) and update the DVTextField bindings to use those new state names so
each labeled/section sample has its own independent state and no longer
interferes with others.

In `@Projects/DVDesign/Sources/Components/DVTextContainer.swift`:
- Around line 195-237: The copyable initializer's accessory Button (public
init(copyable:text:size:onCopy:)) has no accessibility label, making VoiceOver
unclear; add an explicit accessibility label to the Button (or its Image) such
as .accessibilityLabel(Text("Copy")) or a localized string to describe the
action, and apply the same pattern to the analogous secured initializer's
reveal/toggle Button (the Button that toggles isRevealed / shows
"eye"/"eye.slash") so screen readers announce the purpose.

---

Nitpick comments:
In `@Projects/DVDesign/SampleApp/Sources/ContentView.swift`:
- Around line 3-4: Add a blank line between the system framework import and the
local module import so imports are grouped and more readable: ensure "import
SwiftUI" appears first (system/framework imports), then a blank line, then
"import DVDesign" (local/third-party), and verify imports remain alphabetized
within their groups.

In `@Projects/DVDesign/SampleApp/Sources/TextContainerPreviewView.swift`:
- Around line 15-140: The body contains large nested layout and helper methods
(section(_:content:), labeled(_:content:), copyToClipboard(_:)) defined inside
the main type; extract the helper view builders and clipboard helper into a
private extension of TextContainerPreviewView to reduce noise in var body. Move
the implementations of section(title:content:), labeled(_:content:) and
copyToClipboard(_:) out of the main type body and into an extension
TextContainerPreviewView { private func/var ... } (keeping their signatures and
access control), and update any references in var body to use these moved
helpers.
- Around line 10-11: Rename the Bool `@State` properties manualRevealed and
securedRevealed to isManualRevealed and isSecuredRevealed respectively, and
update all references/usages (bindings, view logic, toggles) to the new names;
also apply the same is-prefixed rename to the other Bool properties noted in the
review (the ones referenced at 52-53, 72-73, 83-85) so all boolean state names
follow the is/has/can convention and preserve existing behavior.

In `@Projects/DVDesign/SampleApp/Sources/TextFieldPreviewView.swift`:
- Around line 14-63: Extract the large nested layout inside var body into
separate private computed properties like private var statusSection and private
var sizeSection returning some View, move the helper view builders section(...)
and labeled(...) out of the main type into an extension TextFieldPreviewView as
private functions, and update body to compose using statusSection and
sizeSection; this keeps the DVTextField rows and VStack structure unchanged but
relocates section and labeled to the extension and replaces the inline blocks in
body with the new private vars.

In `@Projects/DVDesign/Sources/Components/DVTextContainer.swift`:
- Around line 118-139: Split the nested layout inside the public var body into
small private members: extract the ScrollView+Text block into a private var/func
named textContent (preserve Text modifiers: .font(DVFont.bodyLG.font),
.foregroundStyle(Color.dv(.gray900)), .lineLimit(1), .fixedSize(horizontal:
true, vertical: false), .textSelection(.enabled)), extract the RoundedRectangle
background into a private var/func containerBackground, and compose the HStack
(HStack(spacing: 8) { textContent; accessories() }) plus paddings/ frame into a
private var/func (e.g., mainContent) so body simply returns
mainContent.background(containerBackground()); keep references to accessories(),
trailingPadding, and size unchanged. Ensure accessibility and modifiers are
preserved exactly when moving code to the private members.

In `@Projects/DVDesign/Sources/Foundations/Sizing/DVComponentSize.swift`:
- Line 3: DVComponentSize currently imports SwiftUI unnecessarily; replace the
SwiftUI dependency with CoreGraphics since DVComponentSize only uses CGFloat.
Open the file containing DVComponentSize, remove the "import SwiftUI" statement
and add "import CoreGraphics" instead, and verify there are no SwiftUI types
referenced elsewhere in the DVComponentSize declaration or related helpers.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 68d3e034-94db-4884-964a-e297f986fe08

📥 Commits

Reviewing files that changed from the base of the PR and between afe263a and 56f219f.

📒 Files selected for processing (6)
  • Projects/DVDesign/SampleApp/Sources/ContentView.swift
  • Projects/DVDesign/SampleApp/Sources/TextContainerPreviewView.swift
  • Projects/DVDesign/SampleApp/Sources/TextFieldPreviewView.swift
  • Projects/DVDesign/Sources/Components/DVTextContainer.swift
  • Projects/DVDesign/Sources/Components/DVTextField.swift
  • Projects/DVDesign/Sources/Foundations/Sizing/DVComponentSize.swift

Comment thread Projects/DVDesign/SampleApp/Sources/TextContainerPreviewView.swift
Comment thread Projects/DVDesign/SampleApp/Sources/TextFieldPreviewView.swift
Comment thread Projects/DVDesign/Sources/Components/DVTextContainer.swift

@yeseonglee yeseonglee left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

구현하느라 수고하셨습니다~ link 요소까지 넣어서 디테일이 더 추가된 것 같아요

@doyeonk429
doyeonk429 merged commit c681638 into develop May 24, 2026
1 check passed
@doyeonk429
doyeonk429 deleted the design/#17 branch May 24, 2026 14:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🎨 Design UI 디자인 작업

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Design: DVTextField 및 DVTextContainer 개발

2 participants