diff --git a/Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/alert.imageset/Contents.json b/Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/alert.imageset/Contents.json new file mode 100644 index 0000000..9ff81e4 --- /dev/null +++ b/Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/alert.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "alert.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "alert@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "alert@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/alert.imageset/alert.png b/Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/alert.imageset/alert.png new file mode 100644 index 0000000..d3638d1 Binary files /dev/null and b/Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/alert.imageset/alert.png differ diff --git a/Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/alert.imageset/alert@2x.png b/Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/alert.imageset/alert@2x.png new file mode 100644 index 0000000..5725d11 Binary files /dev/null and b/Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/alert.imageset/alert@2x.png differ diff --git a/Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/alert.imageset/alert@3x.png b/Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/alert.imageset/alert@3x.png new file mode 100644 index 0000000..089bbe9 Binary files /dev/null and b/Projects/DesignSystem/DesignCore/Resources/Images/Images.xcassets/alert.imageset/alert@3x.png differ diff --git a/Projects/DesignSystem/DesignCore/Sources/Toast/ToastView.swift b/Projects/DesignSystem/DesignCore/Sources/Toast/ToastView.swift new file mode 100644 index 0000000..42c93fe --- /dev/null +++ b/Projects/DesignSystem/DesignCore/Sources/Toast/ToastView.swift @@ -0,0 +1,87 @@ +// +// ToastView.swift +// ComponentsKit +// +// Created by 김지수 on 9/22/24. +// Copyright © 2024 com.weave. All rights reserved. +// + +import SwiftUI + +struct ToastViewModifier: ViewModifier { + let message: String + @Binding var isPresented: Bool + let bottomPadding: CGFloat + + func body(content: Content) -> some View { + content + .overlay { + ZStack { + VStack { + Spacer() + Toast( + message: message, + isPresent: $isPresented + ) + .offset(y: -(bottomPadding + Device.bottomInset)) + } + } + } + } +} + +extension View { + public func toast( + message: String, + isPresent: Binding, + bottomPadding: CGFloat = 0 + ) -> some View { + modifier( + ToastViewModifier( + message: message, + isPresented: isPresent, + bottomPadding: bottomPadding + ) + ) + } +} + +struct Toast: View { + let message: String + @Binding var isPresent: Bool + + var body: some View { + ZStack { + RoundedRectangle(cornerRadius: 14) + .inset(by: 1) + .stroke( + DesignCore.Colors.red300.opacity(0.5), + lineWidth: 1 + ) + .background(DesignCore.Colors.red300.opacity(0.08)) + .clipShape(RoundedRectangle(cornerRadius: 14)) + .shadow(.alert) + + HStack(spacing: 6) { + DesignCore.Images.alert.image! + .resizable() + .frame(width: 20, height: 20) + Text(message) + .typography(.medium_16) + .foregroundStyle(DesignCore.Colors.red300) + } + } + .frame(height: 52) + .padding(.horizontal, 28) + .offset(y: isPresent ? 0 : 100) + .opacity(isPresent ? 1 : 0) + .animation(.bouncy(duration: 0.25), value: isPresent) + .onChange(of: isPresent) { + if isPresent { + DispatchQueue.main.asyncAfter(deadline: .now() + 2) { + isPresent = false + } + } + } + } +} diff --git a/Projects/Features/DesignPreview/Sources/DesignPreview.swift b/Projects/Features/DesignPreview/Sources/DesignPreview.swift index 01bcad8..a7949f0 100644 --- a/Projects/Features/DesignPreview/Sources/DesignPreview.swift +++ b/Projects/Features/DesignPreview/Sources/DesignPreview.swift @@ -15,6 +15,7 @@ fileprivate enum PreviewTypes: CaseIterable { case ctaButton case shadow case textInput + case toast var name: String { switch self { @@ -24,6 +25,7 @@ fileprivate enum PreviewTypes: CaseIterable { case .ctaButton: return "CTA Button" case .shadow: return "Shadow" case .textInput: return "Text Input" + case .toast: return "Toast" } } @@ -42,6 +44,8 @@ fileprivate enum PreviewTypes: CaseIterable { DesignShadowView() case .textInput: DesignTextInputPreview() + case .toast: + DesignToastView() } } } diff --git a/Projects/Features/DesignPreview/Sources/DesignToastView.swift b/Projects/Features/DesignPreview/Sources/DesignToastView.swift new file mode 100644 index 0000000..772d90f --- /dev/null +++ b/Projects/Features/DesignPreview/Sources/DesignToastView.swift @@ -0,0 +1,35 @@ +// +// DesignToastView.swift +// DesignPreview +// +// Created by 김지수 on 9/22/24. +// Copyright © 2024 com.weave. All rights reserved. +// + +import SwiftUI +import DesignCore + +struct DesignToastView: View { + @State var isPresent = false + + var body: some View { + ZStack { + DesignCore.Colors.background + CTAButton(title: "Show Toast") { + isPresent.toggle() + } + .padding(.horizontal, 36) + } + .toast( + message: "나이를 입력해주세요", + isPresent: $isPresent + ) + .ignoresSafeArea() + .navigationTitle("Toast") + .navigationBarTitleDisplayMode(.inline) + } +} + +#Preview { + DesignToastView() +}