Skip to content

Commit 0fb8520

Browse files
committed
feature: DesignSystem - Dialog
1 parent 57a5eff commit 0fb8520

File tree

3 files changed

+200
-7
lines changed

3 files changed

+200
-7
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
//
2+
// DialogDetailView.swift
3+
// DesignSystem
4+
//
5+
// Created by 김지현 on 8/17/24.
6+
// Copyright © 2024 PomoNyang. All rights reserved.
7+
//
8+
9+
import SwiftUI
10+
11+
import DesignSystem
12+
13+
struct DialogDetailView: View {
14+
@State var titleSubTitleTwoButtonDialogIsPresented: Bool = false
15+
@State var titleSubTitleOneButtonDialogIsPresented: Bool = false
16+
@State var titleTwoButtonDialogIsPresented: Bool = false
17+
@State var titleOneButtonDialogIsPresented: Bool = false
18+
19+
var body: some View {
20+
VStack(spacing: 10) {
21+
Spacer()
22+
23+
Button {
24+
titleSubTitleTwoButtonDialogIsPresented = true
25+
} label: {
26+
Text("title SubTitle & Two Button")
27+
}
28+
29+
Button {
30+
titleSubTitleOneButtonDialogIsPresented = true
31+
} label: {
32+
Text("title SubTitle & One Button")
33+
}
34+
35+
Button {
36+
titleTwoButtonDialogIsPresented = true
37+
} label: {
38+
Text("title & Two Button")
39+
}
40+
41+
Button {
42+
titleOneButtonDialogIsPresented = true
43+
} label: {
44+
Text("title & One Button")
45+
}
46+
47+
Spacer()
48+
}
49+
.dialog(
50+
title: "Dialog Title",
51+
subTitle: "Dialog Subtext를 입력해주세요.\n최대 2줄을 넘지 않도록 해요.",
52+
isPresented: $titleSubTitleTwoButtonDialogIsPresented,
53+
firstButton: DialogButtonModel(title: "Button1"),
54+
secondButton: DialogButtonModel(title: "Button2", action: { print(" PRINT !!") })
55+
)
56+
.dialog(
57+
title: "Dialog Title",
58+
subTitle: "Dialog Subtext를 입력해주세요.\n최대 2줄을 넘지 않도록 해요.",
59+
isPresented: $titleSubTitleOneButtonDialogIsPresented,
60+
firstButton: DialogButtonModel(title: "Button1")
61+
)
62+
.dialog(
63+
title: "Dialog Title",
64+
isPresented: $titleTwoButtonDialogIsPresented,
65+
firstButton: DialogButtonModel(title: "Button1"),
66+
secondButton: DialogButtonModel(title: "Button2", action: { print(" PRINT !!") })
67+
)
68+
.dialog(
69+
title: "Dialog Title",
70+
isPresented: $titleOneButtonDialogIsPresented,
71+
firstButton: DialogButtonModel(title: "Button1")
72+
)
73+
}
74+
}

Projects/Shared/DesignSystem/Example/Sources/ContentView.swift

+1-7
Original file line numberDiff line numberDiff line change
@@ -67,16 +67,10 @@ struct ContentView: View {
6767
}
6868

6969
NavigationLink {
70-
70+
DialogDetailView()
7171
} label: {
7272
Text("Dialog")
7373
}
74-
75-
NavigationLink {
76-
77-
} label: {
78-
Text("TextField")
79-
}
8074

8175
NavigationLink {
8276
InputFieldDetailView()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
//
2+
// DialogViewModifier.swift
3+
// DesignSystem
4+
//
5+
// Created by 김지현 on 8/17/24.
6+
// Copyright © 2024 PomoNyang. All rights reserved.
7+
//
8+
9+
import SwiftUI
10+
11+
public struct DialogButtonModel {
12+
let title: String
13+
let leftIcon: Image?
14+
let rightIcon: Image?
15+
let action: (() -> Void)? // 버튼 액션을 Nil로 두면 자동으로 CancelButton이 됩니다
16+
17+
public init(title: String, leftIcon: Image? = nil, rightIcon: Image? = nil, action: (() -> Void)? = nil) {
18+
self.title = title
19+
self.leftIcon = leftIcon
20+
self.rightIcon = rightIcon
21+
self.action = action
22+
}
23+
}
24+
25+
struct DialogViewModifier: ViewModifier {
26+
let title: String
27+
let subTitle: String?
28+
@Binding var isPresented: Bool
29+
let firstButton: DialogButtonModel
30+
let secondButton: DialogButtonModel?
31+
32+
func body(content: Content) -> some View {
33+
ZStack(alignment: .center) {
34+
content
35+
.frame(maxWidth: .infinity, maxHeight: .infinity)
36+
.zIndex(1)
37+
38+
if isPresented {
39+
Global.Color.black.opacity(Global.Opacity._50d)
40+
.ignoresSafeArea()
41+
.zIndex(2)
42+
43+
44+
// MARK: Title & SubTitle
45+
VStack(spacing: Alias.Spacing.large) {
46+
VStack(spacing: Alias.Spacing.small) {
47+
HStack {
48+
Text(title)
49+
.font(Typography.header4)
50+
.foregroundStyle(Alias.Color.Text.primary)
51+
Spacer()
52+
Button {
53+
self.isPresented = false
54+
} label: {
55+
DesignSystemAsset.Image._24CancelPrimary.swiftUIImage
56+
}
57+
}
58+
.padding(.top, Alias.Spacing.small)
59+
60+
if let subTitle = subTitle {
61+
HStack {
62+
Text(subTitle)
63+
.font(Typography.subBodyR)
64+
.foregroundStyle(Alias.Color.Text.secondary)
65+
Spacer()
66+
}
67+
}
68+
}
69+
70+
// MARK: Buttons
71+
HStack {
72+
Button(
73+
title: LocalizedStringKey(firstButton.title),
74+
leftIcon: firstButton.leftIcon,
75+
rightIcon: firstButton.rightIcon,
76+
action: {
77+
self.isPresented = false
78+
firstButton.action?()
79+
}
80+
)
81+
.buttonStyle(.box(level: firstButton.action == nil ? .tertiary : .primary, size: .medium, width: .low))
82+
if let secondButton = secondButton {
83+
Button(
84+
title: LocalizedStringKey(secondButton.title),
85+
leftIcon: secondButton.leftIcon,
86+
rightIcon: secondButton.rightIcon,
87+
action: {
88+
self.isPresented = false
89+
secondButton.action?()
90+
}
91+
)
92+
.buttonStyle(.box(level: secondButton.action == nil ? .tertiary : .primary, size: .medium, width: .low))
93+
}
94+
}
95+
}
96+
.padding(.all, Alias.Spacing.xLarge)
97+
.frame(width: 335)
98+
.background(Global.Color.white)
99+
.cornerRadius(Alias.BorderRadius.medium)
100+
.zIndex(3)
101+
}
102+
}
103+
.animation(.easeInOut(duration: 0.3), value: !self.isPresented)
104+
}
105+
}
106+
107+
extension View {
108+
public func dialog(
109+
title: String,
110+
subTitle: String? = nil,
111+
isPresented: Binding<Bool>,
112+
firstButton: DialogButtonModel,
113+
secondButton: DialogButtonModel? = nil
114+
) -> some View {
115+
return self.modifier(
116+
DialogViewModifier(
117+
title: title,
118+
subTitle: subTitle,
119+
isPresented: isPresented,
120+
firstButton: firstButton,
121+
secondButton: secondButton
122+
)
123+
)
124+
}
125+
}

0 commit comments

Comments
 (0)