diff --git a/DependencyGraph/mohanyang_dev_graph.png b/DependencyGraph/mohanyang_dev_graph.png index 4e1f041..e69268f 100644 Binary files a/DependencyGraph/mohanyang_dev_graph.png and b/DependencyGraph/mohanyang_dev_graph.png differ diff --git a/DependencyGraph/mohanyang_prod_graph.png b/DependencyGraph/mohanyang_prod_graph.png index b82abad..3400ae0 100644 Binary files a/DependencyGraph/mohanyang_prod_graph.png and b/DependencyGraph/mohanyang_prod_graph.png differ diff --git a/Projects/Shared/DesignSystem/Example/Sources/ButtonDetailView.swift b/Projects/Shared/DesignSystem/Example/Sources/Component/ButtonDetailView.swift similarity index 90% rename from Projects/Shared/DesignSystem/Example/Sources/ButtonDetailView.swift rename to Projects/Shared/DesignSystem/Example/Sources/Component/ButtonDetailView.swift index f75b70e..2bb4c84 100644 --- a/Projects/Shared/DesignSystem/Example/Sources/ButtonDetailView.swift +++ b/Projects/Shared/DesignSystem/Example/Sources/Component/ButtonDetailView.swift @@ -195,29 +195,19 @@ struct ButtonDetailView: View { .disabled(false) } } - -// VStack { -// Text("Secondary") -// .frame(maxWidth: .infinity) -// .foregroundStyle(Global.Color.white) -// .background(Global.Color.black) -// HStack(spacing: 10) { -// Button( -// icon: Image(systemName: "center"), -// action: { /*action*/ } -// ) -// .buttonStyle(.round(color: .secondary)) -// -// Button( -// icon: Image(systemName: "center"), -// action: { /*action*/ } -// ) -// .buttonStyle(.round(color: .primary)) -// } -// } - - - + } + + VStack(spacing: 40) { + Text("Bottom CTA") + .font(.title) + VStack { + Button( + title: "Button", + action: { /*action*/ } + ) + .buttonStyle(.box(size: .large, color: .primary, width: .low)) + .padding(.horizontal, 20) + } } } } diff --git a/Projects/Shared/DesignSystem/Example/Sources/NavigationDetailView.swift b/Projects/Shared/DesignSystem/Example/Sources/Component/NavigationDetailView.swift similarity index 100% rename from Projects/Shared/DesignSystem/Example/Sources/NavigationDetailView.swift rename to Projects/Shared/DesignSystem/Example/Sources/Component/NavigationDetailView.swift diff --git a/Projects/Shared/DesignSystem/Example/Sources/Component/TooltipDetailView.swift b/Projects/Shared/DesignSystem/Example/Sources/Component/TooltipDetailView.swift new file mode 100644 index 0000000..90eee9d --- /dev/null +++ b/Projects/Shared/DesignSystem/Example/Sources/Component/TooltipDetailView.swift @@ -0,0 +1,115 @@ +// +// TooltipDetailView.swift +// DesignSystemExample +// +// Created by devMinseok on 8/7/24. +// Copyright © 2024 PomoNyang. All rights reserved. +// + +import SwiftUI + +import DesignSystem + +struct TooltipDetailView: View { + @State var downDirectionTooltip: DownDirectionTooltip? + @State var upDirectionTooltip: UpDirectionTooltip? + @State var downDirectionWithDimTooltip: DownDirectionWithDimTooltip? + @State var upDirectionWithDimTooltip: UpDirectionWithDimTooltip? + + let downDirectionTooltip_ = DownDirectionTooltip() + let upDirectionTooltip_ = UpDirectionTooltip() + let downDirectionWithDimTooltip_ = DownDirectionWithDimTooltip() + let upDirectionWithDimTooltip_ = UpDirectionWithDimTooltip() + + + var body: some View { + VStack { + Button( + title: "Direction: .down, Color: .white, dim: false", + action: { + downDirectionTooltip = downDirectionTooltip_ + } + ) + .buttonStyle(.box(size: .large, color: .primary)) + .setTooltipTarget(tooltip: downDirectionTooltip_) + + Button( + title: "Direction: .up, Color: .black, dim: false", + action: { + upDirectionTooltip = upDirectionTooltip_ + } + ) + .buttonStyle(.box(size: .large, color: .primary)) + .setTooltipTarget(tooltip: upDirectionTooltip_) + + Button( + title: "Direction: .down, Color: .white, dim: true", + action: { + downDirectionWithDimTooltip = downDirectionWithDimTooltip_ + } + ) + .buttonStyle(.box(size: .large, color: .primary)) + .setTooltipTarget(tooltip: downDirectionWithDimTooltip_) + + Button( + title: "Direction: .up, Color: .black, dim: true", + action: { + upDirectionWithDimTooltip = upDirectionWithDimTooltip_ + } + ) + .buttonStyle(.box(size: .large, color: .primary)) + .setTooltipTarget(tooltip: upDirectionWithDimTooltip_) + } + .frame(maxWidth: .infinity, maxHeight: .infinity) + .background(.yellow) + .tooltipDestination(tooltip: $downDirectionTooltip) + .tooltipDestination(tooltip: $upDirectionTooltip) + .tooltipDestination(tooltip: $downDirectionWithDimTooltip) + .tooltipDestination(tooltip: $upDirectionWithDimTooltip) + } +} + + + +struct DownDirectionTooltip: Tooltip { + var title: Text { Text("DownDirectionTooltip") } + var color: TooltipColor { .white } + var direction: TooltipDirection { .down } + var targetCornerRadius: CGFloat? { Alias.BorderRadius.small } + var dimEnabled: Bool { false } + var padding: CGFloat { 12 } +} + +struct UpDirectionTooltip: Tooltip { + var title: Text { Text("UpDirectionTooltip") } + var color: TooltipColor { .black } + var direction: TooltipDirection { .up } + var targetCornerRadius: CGFloat? { Alias.BorderRadius.small } + var dimEnabled: Bool { false } + var padding: CGFloat { 12 } +} + +struct DownDirectionWithDimTooltip: Tooltip { + var title: Text { Text("DownDirectionWithDimTooltip") } + var color: TooltipColor { .white } + var direction: TooltipDirection { .down } + var targetCornerRadius: CGFloat? { Alias.BorderRadius.small } + var dimEnabled: Bool { true } + var padding: CGFloat { 12 } +} + +struct UpDirectionWithDimTooltip: Tooltip { + var title: Text { Text("UpDirectionWithDimTooltip") } + var color: TooltipColor { .black } + var direction: TooltipDirection { .up } + var targetCornerRadius: CGFloat? { Alias.BorderRadius.small } + var dimEnabled: Bool { true } + var padding: CGFloat { 12 } +} + + +// Preview환경에서만 크래시 발생: +// some View와 같은 제너릭 타입은 프리뷰에서 타입 추론에 문제가 생길 수 있습니다. 특히 프리뷰의 경우, 다양한 뷰가 서로 다른 타입으로 처리될 수 있어, 뷰의 타입이 명확하지 않은 경우 문제가 발생할 수 있습니다. +//#Preview { +// TooltipDetailView() +//} diff --git a/Projects/Shared/DesignSystem/Example/Sources/ContentView.swift b/Projects/Shared/DesignSystem/Example/Sources/ContentView.swift index 2ceadc3..569cb00 100644 --- a/Projects/Shared/DesignSystem/Example/Sources/ContentView.swift +++ b/Projects/Shared/DesignSystem/Example/Sources/ContentView.swift @@ -49,7 +49,7 @@ struct ContentView: View { } NavigationLink { - + TooltipDetailView() } label: { Text("Tooltip") } @@ -71,18 +71,6 @@ struct ContentView: View { } label: { Text("Toast") } - - NavigationLink { - - } label: { - Text("System") - } - - NavigationLink { - - } label: { - Text("List") - } } } .navigationTitle("DesignSystem") diff --git a/Projects/Shared/DesignSystem/Example/Sources/AliasTokenDetailView.swift b/Projects/Shared/DesignSystem/Example/Sources/Token/AliasTokenDetailView.swift similarity index 100% rename from Projects/Shared/DesignSystem/Example/Sources/AliasTokenDetailView.swift rename to Projects/Shared/DesignSystem/Example/Sources/Token/AliasTokenDetailView.swift diff --git a/Projects/Shared/DesignSystem/Example/Sources/GlobalTokenDetailView.swift b/Projects/Shared/DesignSystem/Example/Sources/Token/GlobalTokenDetailView.swift similarity index 100% rename from Projects/Shared/DesignSystem/Example/Sources/GlobalTokenDetailView.swift rename to Projects/Shared/DesignSystem/Example/Sources/Token/GlobalTokenDetailView.swift diff --git a/Projects/Shared/DesignSystem/Example/Sources/FontDetailView.swift b/Projects/Shared/DesignSystem/Example/Sources/Typography/FontDetailView.swift similarity index 95% rename from Projects/Shared/DesignSystem/Example/Sources/FontDetailView.swift rename to Projects/Shared/DesignSystem/Example/Sources/Typography/FontDetailView.swift index 5dd6005..36d29e1 100644 --- a/Projects/Shared/DesignSystem/Example/Sources/FontDetailView.swift +++ b/Projects/Shared/DesignSystem/Example/Sources/Typography/FontDetailView.swift @@ -12,7 +12,7 @@ import DesignSystem struct FontDetailView: View { var body: some View { - VStack(alignment: .leading, spacing: 10) { + VStack(alignment: .leading, spacing: .zero) { Text("Time") .font(Typography.time) Text("Header1") diff --git a/Projects/Shared/DesignSystem/Project.swift b/Projects/Shared/DesignSystem/Project.swift index 3a7f8bc..e2ef347 100644 --- a/Projects/Shared/DesignSystem/Project.swift +++ b/Projects/Shared/DesignSystem/Project.swift @@ -20,8 +20,6 @@ let project: Project = .makeTMABasedProject( scripts: [], targets: [ .sources, - .tests, - .testing, .example ], dependencies: [:], diff --git a/Projects/Shared/DesignSystem/Sources/Component/Button/BarButtonDetail.swift b/Projects/Shared/DesignSystem/Sources/Component/Button/BarButtonDetail.swift index ce1e301..9155bc3 100644 --- a/Projects/Shared/DesignSystem/Sources/Component/Button/BarButtonDetail.swift +++ b/Projects/Shared/DesignSystem/Sources/Component/Button/BarButtonDetail.swift @@ -33,7 +33,7 @@ public struct BarButtonDetail: Vie private let leftIcon: LeftIcon private let rightIcon: RightIcon - init ( + init( @ViewBuilder title: () -> Title, @ViewBuilder leftIcon: () -> LeftIcon, @ViewBuilder rightIcon: () -> RightIcon diff --git a/Projects/Shared/DesignSystem/Sources/Component/Button/Box/BoxButtonStyle.swift b/Projects/Shared/DesignSystem/Sources/Component/Button/Box/BoxButtonStyle.swift index c4d8f91..274dcef 100644 --- a/Projects/Shared/DesignSystem/Sources/Component/Button/Box/BoxButtonStyle.swift +++ b/Projects/Shared/DesignSystem/Sources/Component/Button/Box/BoxButtonStyle.swift @@ -12,18 +12,22 @@ public struct BoxButtonStyle: ButtonStyle { @Environment(\.isEnabled) var isEnabled let size: BoxButtonStyleSize let color: BoxButtonStyleColor + let width: ButtonHuggingPriorityHorizontal public init( size: BoxButtonStyleSize, - color: BoxButtonStyleColor + color: BoxButtonStyleColor, + width: ButtonHuggingPriorityHorizontal ) { self.size = size self.color = color + self.width = width } public func makeBody(configuration: Configuration) -> some View { configuration.label .frame(height: size.buttonHeight) + .frame(maxWidth: width.width) .font(size.font) .padding(.horizontal, size.horizontalSideSpacing) .background( @@ -65,9 +69,10 @@ public struct BoxButtonStyle: ButtonStyle { extension ButtonStyle where Self == BoxButtonStyle { public static func box( size: BoxButtonStyleSize, - color: BoxButtonStyleColor + color: BoxButtonStyleColor, + width: ButtonHuggingPriorityHorizontal = .high ) -> Self { - return BoxButtonStyle(size: size, color: color) + return BoxButtonStyle(size: size, color: color, width: width) } } diff --git a/Projects/Shared/DesignSystem/Sources/Component/Button/Box/BoxButtonStyleSize.swift b/Projects/Shared/DesignSystem/Sources/Component/Button/Box/BoxButtonStyleSize.swift index d105a0f..09412b8 100644 --- a/Projects/Shared/DesignSystem/Sources/Component/Button/Box/BoxButtonStyleSize.swift +++ b/Projects/Shared/DesignSystem/Sources/Component/Button/Box/BoxButtonStyleSize.swift @@ -26,7 +26,7 @@ extension BoxButtonStyleSize { } } - var font: Font { + var font: Typography { switch self { case .large: Typography.header5 diff --git a/Projects/Shared/DesignSystem/Sources/Component/Button/ButtonHuggingPriorityHorizontal.swift b/Projects/Shared/DesignSystem/Sources/Component/Button/ButtonHuggingPriorityHorizontal.swift new file mode 100644 index 0000000..5673d14 --- /dev/null +++ b/Projects/Shared/DesignSystem/Sources/Component/Button/ButtonHuggingPriorityHorizontal.swift @@ -0,0 +1,25 @@ +// +// ButtonHuggingPriorityHorizontal.swift +// DesignSystem +// +// Created by devMinseok on 8/10/24. +// Copyright © 2024 PomoNyang. All rights reserved. +// + +import Foundation + +public enum ButtonHuggingPriorityHorizontal { + case high + case low +} + +extension ButtonHuggingPriorityHorizontal { + var width: CGFloat? { + switch self { + case .high: + return nil + case .low: + return .infinity + } + } +} diff --git a/Projects/Shared/DesignSystem/Sources/Component/Button/Text/TextButtonStyleSize.swift b/Projects/Shared/DesignSystem/Sources/Component/Button/Text/TextButtonStyleSize.swift index 7313bcf..5650277 100644 --- a/Projects/Shared/DesignSystem/Sources/Component/Button/Text/TextButtonStyleSize.swift +++ b/Projects/Shared/DesignSystem/Sources/Component/Button/Text/TextButtonStyleSize.swift @@ -26,7 +26,7 @@ extension TextButtonStyleSize { } } - var font: Font { + var font: Typography { switch self { case .large: Typography.header5 diff --git a/Projects/Shared/DesignSystem/Sources/Component/Tooltip/ExcludeRoundedRectMask.swift b/Projects/Shared/DesignSystem/Sources/Component/Tooltip/ExcludeRoundedRectMask.swift new file mode 100644 index 0000000..a23999f --- /dev/null +++ b/Projects/Shared/DesignSystem/Sources/Component/Tooltip/ExcludeRoundedRectMask.swift @@ -0,0 +1,30 @@ +// +// ExcludeRoundedRectMask.swift +// DesignSystem +// +// Created by devMinseok on 8/9/24. +// Copyright © 2024 PomoNyang. All rights reserved. +// + +import SwiftUI + +struct ExcludeRoundedRectMask: View { + let excludedRect: CGRect + let cornerRadius: CGFloat + + var body: some View { + GeometryReader { geometry in + let fullRect = geometry.frame(in: .local) + + Path { path in + path.addRect(fullRect) + + let roundedRect = RoundedRectangle(cornerRadius: cornerRadius) + .path(in: excludedRect) + path.addPath(roundedRect) + } + .fill(style: FillStyle(eoFill: true)) + } + .ignoresSafeArea() + } +} diff --git a/Projects/Shared/DesignSystem/Sources/Component/Tooltip/FrameMeasurePreferenceKey.swift b/Projects/Shared/DesignSystem/Sources/Component/Tooltip/FrameMeasurePreferenceKey.swift new file mode 100644 index 0000000..17056e4 --- /dev/null +++ b/Projects/Shared/DesignSystem/Sources/Component/Tooltip/FrameMeasurePreferenceKey.swift @@ -0,0 +1,21 @@ +// +// FrameMeasurePreferenceKey.swift +// DesignSystem +// +// Created by devMinseok on 8/9/24. +// Copyright © 2024 PomoNyang. All rights reserved. +// + +import SwiftUI + +struct FrameMeasurePreferenceKey: PreferenceKey { + typealias Value = [AnyHashable: CGRect] + + static var defaultValue: Value = Value() + + static func reduce(value: inout Value, nextValue: () -> Value) { + value.merge(nextValue()) { _, new in + new + } + } +} diff --git a/Projects/Shared/DesignSystem/Sources/Component/Tooltip/OverlayWithOnPreferenceChange.swift b/Projects/Shared/DesignSystem/Sources/Component/Tooltip/OverlayWithOnPreferenceChange.swift new file mode 100644 index 0000000..7f8c7dd --- /dev/null +++ b/Projects/Shared/DesignSystem/Sources/Component/Tooltip/OverlayWithOnPreferenceChange.swift @@ -0,0 +1,51 @@ +// +// OverlayWithOnPreferenceChange.swift +// DesignSystem +// +// Created by devMinseok on 8/9/24. +// Copyright © 2024 PomoNyang. All rights reserved. +// + +import SwiftUI + +struct OverlayWithOnPreferenceChange< + K, OverlayContent +>: ViewModifier where K: PreferenceKey, K.Value: Equatable, OverlayContent: View { + let preferenceKey: K.Type + let contentForOverlay: (K.Value) -> OverlayContent + @State var value: K.Value? + + init( + preferenceKey: K.Type, + @ViewBuilder contentForOverlay: @escaping (K.Value) -> OverlayContent + ) { + self.preferenceKey = preferenceKey + self.contentForOverlay = contentForOverlay + } + + func body(content: Content) -> some View { + content + .overlay { + if let value { + contentForOverlay(value) + } + } + .onPreferenceChange(preferenceKey) { value in + self.value = value + } + } +} + +extension View { + func overlayWithOnPreferenceChange( + _ key: K.Type, + @ViewBuilder content: @escaping (K.Value) -> Content + ) -> some View where K: PreferenceKey, K.Value: Equatable, Content: View { + modifier( + OverlayWithOnPreferenceChange( + preferenceKey: key, + contentForOverlay: content + ) + ) + } +} diff --git a/Projects/Shared/DesignSystem/Sources/Component/Tooltip/Tooltip.swift b/Projects/Shared/DesignSystem/Sources/Component/Tooltip/Tooltip.swift new file mode 100644 index 0000000..a14bcc8 --- /dev/null +++ b/Projects/Shared/DesignSystem/Sources/Component/Tooltip/Tooltip.swift @@ -0,0 +1,46 @@ +// +// Tooltip.swift +// DesignSystem +// +// Created by devMinseok on 8/9/24. +// Copyright © 2024 PomoNyang. All rights reserved. +// + +import SwiftUI + +public protocol Tooltip: Hashable { + var title: Text { get } + var color: TooltipColor { get } + var direction: TooltipDirection { get } + var dimEnabled: Bool { get } + var targetCornerRadius: CGFloat? { get } + var padding: CGFloat { get } +} + +public enum TooltipDirection { + case up + case down +} + +public enum TooltipColor { + case white + case black + + var foregroundColor: Color { + switch self { + case .white: + return Alias.Color.Text.secondary + case .black: + return Alias.Color.Text.inverse + } + } + + var backgroundColor: Color { + switch self { + case .white: + return Global.Color.white + case .black: + return Alias.Color.Background.inverse + } + } +} diff --git a/Projects/Shared/DesignSystem/Sources/Component/Tooltip/TooltipTarget.swift b/Projects/Shared/DesignSystem/Sources/Component/Tooltip/TooltipTarget.swift new file mode 100644 index 0000000..701588c --- /dev/null +++ b/Projects/Shared/DesignSystem/Sources/Component/Tooltip/TooltipTarget.swift @@ -0,0 +1,45 @@ +// +// TooltipTarget.swift +// DesignSystem +// +// Created by devMinseok on 8/9/24. +// Copyright © 2024 PomoNyang. All rights reserved. +// + +import SwiftUI + +struct TooltipTarget: View { + let identifier: AnyHashable + + var body: some View { + GeometryReader { geometry in + Color.clear + .preference( + key: FrameMeasurePreferenceKey.self, + value: [identifier: geometry.frame(in: .global)] + ) + } + } +} + +extension View { + public func setTooltipTarget(tooltip: some Tooltip) -> some View { + return self + .background( + TooltipTarget(identifier: tooltip) + ) + } + + public func tooltipDestination(tooltip: Binding<(some Tooltip)?>) -> some View { + return self + .overlayWithOnPreferenceChange(FrameMeasurePreferenceKey.self) { value in + if let content = tooltip.wrappedValue, let position = value[content] { + TooltipView(content: content, position: position) + .transition(.opacity.animation(.easeInOut)) + .onTapGesture { + tooltip.wrappedValue = nil + } + } + } + } +} diff --git a/Projects/Shared/DesignSystem/Sources/Component/Tooltip/TooltipView.swift b/Projects/Shared/DesignSystem/Sources/Component/Tooltip/TooltipView.swift new file mode 100644 index 0000000..3aea4c4 --- /dev/null +++ b/Projects/Shared/DesignSystem/Sources/Component/Tooltip/TooltipView.swift @@ -0,0 +1,60 @@ +// +// TooltipView.swift +// DesignSystem +// +// Created by devMinseok on 8/9/24. +// Copyright © 2024 PomoNyang. All rights reserved. +// + +import SwiftUI + +struct TooltipView: View { + let content: Content + let position: CGRect + + var positionY: CGFloat { + switch content.direction { + case .up: + return position.maxY + 32 + content.padding + case .down: + return position.minY - 32 - content.padding + } + } + + var arrowDirection: Triangle.Direction { + switch content.direction { + case .up: + return .up + case .down: + return .down + } + } + + var body: some View { + ZStack { + content.title + .foregroundStyle(content.color.foregroundColor) + .font(Typography.bodySB) + .padding(.horizontal, Alias.Spacing.large) + .background( + RoundedRectangle(cornerRadius: Alias.BorderRadius.xSmall) + .fill(content.color.backgroundColor) + .frame(height: 46) + ) + Triangle(direction: arrowDirection, color: content.color.backgroundColor) + .frame(width: 14, height: 9) + .padding(content.direction == .down ? .top : .bottom, 55) + } + .position(x: position.midX, y: positionY) + .ignoresSafeArea() + .background( + Global.Color.black.opacity(content.dimEnabled ? Global.Opacity._50d : 0.0) + .mask( + ExcludeRoundedRectMask( + excludedRect: position, + cornerRadius: content.targetCornerRadius ?? .zero + ) + ) + ) + } +} diff --git a/Projects/Shared/DesignSystem/Sources/Component/Tooltip/Triangle.swift b/Projects/Shared/DesignSystem/Sources/Component/Tooltip/Triangle.swift new file mode 100644 index 0000000..c8eeaed --- /dev/null +++ b/Projects/Shared/DesignSystem/Sources/Component/Tooltip/Triangle.swift @@ -0,0 +1,43 @@ +// +// Triangle.swift +// DesignSystem +// +// Created by devMinseok on 8/9/24. +// Copyright © 2024 PomoNyang. All rights reserved. +// + +import SwiftUI + +public struct Triangle: View { + public enum Direction: Double { + case down = 180 + case left = -90 + case up = 0 + case right = 90 + } + + private let direction: Direction + private let color: Color + + public init(direction: Direction, color: Color) { + self.direction = direction + self.color = color + } + + public var body: some View { + TriangleShape() + .fill(color) + .rotationEffect(Angle.degrees(direction.rawValue)) + } + + private struct TriangleShape: Shape { + func path(in rect: CGRect) -> Path { + var path = Path() + path.move(to: CGPoint(x: rect.midX, y: rect.minY)) + path.addLine(to: CGPoint(x: rect.minX, y: rect.maxY)) + path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY)) + path.addLine(to: CGPoint(x: rect.midX, y: rect.minY)) + return path + } + } +} diff --git a/Projects/Shared/DesignSystem/Sources/Font/Typography.swift b/Projects/Shared/DesignSystem/Sources/Font/Typography.swift new file mode 100644 index 0000000..83407db --- /dev/null +++ b/Projects/Shared/DesignSystem/Sources/Font/Typography.swift @@ -0,0 +1,157 @@ +// +// Typography.swift +// DesignSystem +// +// Created by devMinseok on 8/5/24. +// Copyright © 2024 PomoNyang. All rights reserved. +// + +import SwiftUI + +public enum Typography { + case time + case header1 + case header2 + case header3 + case header4 + case header5 + case bodySB + case bodyR + case subBodySB + case subBodyR + case captionSB + case captionR +} + +extension Typography { + /// swiftui font + var font: Font { + return fontWeight.swiftUIFont(size: fontSize) + } + + /// 폰트 line height + var lineHeight: CGFloat { + switch self { + case .time: + return 77 + case .header1: + return 58 + case .header2: + return 41 + case .header3: + return 28 + case .header4: + return 25 + case .header5: + return 22 + case .bodySB: + return 22 + case .bodyR: + return 22 + case .subBodySB: + return 21 + case .subBodyR: + return 21 + case .captionSB: + return 16 + case .captionR: + return 16 + } + } + + /// 폰트 고유 line height + var inherentLineHeight: CGFloat { + // swiftui의 Font는 고유 lineHeight를 못가져오기에 UIFont에서 가져옴 + return fontWeight.font(size: fontSize).lineHeight + } + + /// 폰트 letter spacing + var letterSpacing: CGFloat { + switch self { + case .time: + return -1.28 + case .header1: + return -0.96 + case .header2: + return -0.68 + case .header3: + return -0.48 + case .header4: + return -0.4 + case .header5: + return -0.36 + case .bodySB: + return -0.32 + case .bodyR: + return -0.32 + case .subBodySB: + return -0.28 + case .subBodyR: + return -0.28 + case .captionSB: + return -0.12 + case .captionR: + return -0.12 + } + } + + /// 폰트 size + private var fontSize: CGFloat { + switch self { + case .time: + return 64 + case .header1: + return 48 + case .header2: + return 34 + case .header3: + return 24 + case .header4: + return 20 + case .header5: + return 18 + case .bodySB: + return 16 + case .bodyR: + return 16 + case .subBodySB: + return 14 + case .subBodyR: + return 14 + case .captionSB: + return 12 + case .captionR: + return 12 + } + } + + /// 폰트 weight + private var fontWeight: DesignSystemFontConvertible { + switch self { + case .time: + return DesignSystemFontFamily.Pretendard.bold + case .header1: + return DesignSystemFontFamily.Pretendard.bold + case .header2: + return DesignSystemFontFamily.Pretendard.bold + case .header3: + return DesignSystemFontFamily.Pretendard.bold + case .header4: + return DesignSystemFontFamily.Pretendard.semiBold + case .header5: + return DesignSystemFontFamily.Pretendard.semiBold + case .bodySB: + return DesignSystemFontFamily.Pretendard.semiBold + case .bodyR: + return DesignSystemFontFamily.Pretendard.regular + case .subBodySB: + return DesignSystemFontFamily.Pretendard.semiBold + case .subBodyR: + return DesignSystemFontFamily.Pretendard.regular + case .captionSB: + return DesignSystemFontFamily.Pretendard.semiBold + case .captionR: + return DesignSystemFontFamily.Pretendard.regular + } + } +} diff --git a/Projects/Shared/DesignSystem/Sources/Font/View+Typography.swift b/Projects/Shared/DesignSystem/Sources/Font/View+Typography.swift new file mode 100644 index 0000000..ee42911 --- /dev/null +++ b/Projects/Shared/DesignSystem/Sources/Font/View+Typography.swift @@ -0,0 +1,19 @@ +// +// View+Typography.swift +// DesignSystem +// +// Created by devMinseok on 8/10/24. +// Copyright © 2024 PomoNyang. All rights reserved. +// + +import SwiftUI + +extension View { + public func font(_ typography: Typography) -> some View { + return self + .font(typography.font) + .kerning(typography.letterSpacing) + .lineSpacing(typography.lineHeight - typography.inherentLineHeight) + .padding(.vertical, (typography.lineHeight - typography.inherentLineHeight) / 2) + } +} diff --git a/Projects/Shared/DesignSystem/Sources/Typography.swift b/Projects/Shared/DesignSystem/Sources/Typography.swift deleted file mode 100644 index 75eeb60..0000000 --- a/Projects/Shared/DesignSystem/Sources/Typography.swift +++ /dev/null @@ -1,24 +0,0 @@ -// -// Typography.swift -// DesignSystem -// -// Created by devMinseok on 8/5/24. -// Copyright © 2024 PomoNyang. All rights reserved. -// - -import SwiftUI - -public enum Typography { - public static let time = DesignSystemFontFamily.Pretendard.bold.swiftUIFont(size: 64) - public static let header1 = DesignSystemFontFamily.Pretendard.bold.swiftUIFont(size: 48) - public static let header2 = DesignSystemFontFamily.Pretendard.bold.swiftUIFont(size: 34) - public static let header3 = DesignSystemFontFamily.Pretendard.bold.swiftUIFont(size: 24) - public static let header4 = DesignSystemFontFamily.Pretendard.bold.swiftUIFont(size: 20) - public static let header5 = DesignSystemFontFamily.Pretendard.semiBold.swiftUIFont(size: 18) - public static let bodySB = DesignSystemFontFamily.Pretendard.semiBold.swiftUIFont(size: 16) - public static let bodyR = DesignSystemFontFamily.Pretendard.regular.swiftUIFont(size: 16) - public static let subBodySB = DesignSystemFontFamily.Pretendard.semiBold.swiftUIFont(size: 14) - public static let subBodyR = DesignSystemFontFamily.Pretendard.regular.swiftUIFont(size: 14) - public static let captionSB = DesignSystemFontFamily.Pretendard.semiBold.swiftUIFont(size: 12) - public static let captionR = DesignSystemFontFamily.Pretendard.regular.swiftUIFont(size: 12) -} diff --git a/Projects/Shared/DesignSystem/Testing/DesignSystemTesting.swift b/Projects/Shared/DesignSystem/Testing/DesignSystemTesting.swift deleted file mode 100644 index f052533..0000000 --- a/Projects/Shared/DesignSystem/Testing/DesignSystemTesting.swift +++ /dev/null @@ -1,12 +0,0 @@ -// -// DesignSystemTesting.swift -// DesignSystem -// -// Created by <#T##Author name#> on 8/5/24. -// - -import Foundation - -public struct DesignSystemTesting { - public init() {} -} diff --git a/Projects/Shared/DesignSystem/Tests/DesignSystemTests.swift b/Projects/Shared/DesignSystem/Tests/DesignSystemTests.swift deleted file mode 100644 index 3429f33..0000000 --- a/Projects/Shared/DesignSystem/Tests/DesignSystemTests.swift +++ /dev/null @@ -1,33 +0,0 @@ -// -// DesignSystemTests.swift -// DesignSystem -// -// Created by <#T##Author name#> on 8/5/24. -// - -import XCTest - -final class DesignSystemTests: XCTestCase { - override func setUpWithError() throws { - // Put setup code here. This method is called before the invocation of each test method in the class. - } - - override func tearDownWithError() throws { - // Put teardown code here. This method is called after the invocation of each test method in the class. - } - - func testExample() throws { - // This is an example of a functional test case. - // Use XCTAssert and related functions to verify your tests produce the correct results. - // Any test you write for XCTest can be annotated as throws and async. - // Mark your test throws to produce an unexpected failure when your test encounters an uncaught error. - // Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards. - } - - func testPerformanceExample() throws { - // This is an example of a performance test case. - self.measure { - // Put the code you want to measure the time of here. - } - } -} diff --git a/Projects/Shared/Shared/Sources/Exports.swift b/Projects/Shared/Shared/Sources/Exports.swift index 49b3a1a..0531316 100644 --- a/Projects/Shared/Shared/Sources/Exports.swift +++ b/Projects/Shared/Shared/Sources/Exports.swift @@ -8,7 +8,6 @@ @_exported import Logger @_exported import DesignSystem -@_exported import DesignSystemInterface @_exported import Utils @_exported import UtilsInterface