-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
97bda6b
commit bbe7406
Showing
6 changed files
with
359 additions
and
122 deletions.
There are no files selected for viewing
5 changes: 5 additions & 0 deletions
5
Source/DDS/Component/NavigationBar/DodamNavigationBarButton.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
public struct DodamNavigationBarButton { | ||
|
||
public let icon: DodamIconography | ||
public let action: () -> Void | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
import SwiftUI | ||
|
||
@available(macOS 12, iOS 15, *) | ||
public struct DodamNavigationBar: View { | ||
|
||
private let title: String | ||
private let font: Font | ||
private let verticalSpacing: CGFloat? | ||
private let showBackButton: Bool | ||
private let buttons: [DodamNavigationBarButton] | ||
|
||
private init( | ||
title: String, | ||
font: Font = .headline(.small), | ||
verticalSpacing: CGFloat? = nil, | ||
showBackButton: Bool = true, | ||
buttons: [DodamNavigationBarButton] = .init() | ||
) { | ||
self.title = title | ||
self.font = font | ||
self.verticalSpacing = verticalSpacing | ||
self.showBackButton = showBackButton | ||
self.buttons = buttons | ||
} | ||
|
||
public static func `default`(title: String) -> Self { | ||
.init( | ||
title: title, | ||
showBackButton: false | ||
) | ||
} | ||
|
||
public static func small(title: String) -> Self { | ||
.init( | ||
title: title, | ||
font: .body(.large) | ||
) | ||
} | ||
|
||
public static func medium(title: String) -> Self { | ||
.init( | ||
title: title, | ||
verticalSpacing: 1 | ||
) | ||
} | ||
|
||
public static func large(title: String) -> Self { | ||
.init( | ||
title: title, | ||
font: .headline(.medium), | ||
verticalSpacing: 48 | ||
) | ||
} | ||
|
||
public func button( | ||
icon: DodamIconography, | ||
action: @escaping () -> Void | ||
) -> Self { | ||
.init( | ||
title: self.title, | ||
font: self.font, | ||
verticalSpacing: self.verticalSpacing, | ||
showBackButton: self.showBackButton, | ||
buttons: self.buttons + [ | ||
.init( | ||
icon: icon, | ||
action: action | ||
) | ||
] | ||
) | ||
} | ||
|
||
private var text: Text { | ||
.init(title) | ||
.font(font) | ||
} | ||
|
||
@Environment(\.dismiss) var dismiss | ||
|
||
public var body: some View { | ||
VStack(alignment: .leading, spacing: 0) { | ||
HStack(spacing: 0) { | ||
if showBackButton { | ||
Button { | ||
dismiss() | ||
} label: { | ||
Dodam.icon(.chevronLeft) | ||
.resizable() | ||
.frame(width: 24, height: 24) | ||
.frame(width: 48, height: 48) | ||
} | ||
.dodamColor(.onSurface) | ||
} | ||
if verticalSpacing == nil { | ||
text | ||
.padding( | ||
.leading, | ||
showBackButton ? 4 : 16 | ||
) | ||
} | ||
Spacer() | ||
ForEach(buttons.indices, id: \.self) { idx in | ||
let button = buttons[idx] | ||
Button(action: button.action) { | ||
Dodam.icon(button.icon) | ||
.resizable() | ||
.frame(width: 28, height: 28) | ||
.frame(width: 48, height: 48) | ||
} | ||
.dodamColor(.onSurfaceVariant) | ||
} | ||
} | ||
.padding(.trailing, 4) | ||
.frame(height: 48) | ||
if let verticalSpacing { | ||
text | ||
.padding([.horizontal, .bottom], 16) | ||
.padding(.top, verticalSpacing) | ||
} | ||
} | ||
} | ||
} | ||
|
||
#Preview { | ||
VStack { | ||
Divider() | ||
DodamNavigationBar.default(title: "Default") | ||
.button(icon: .plus) { } | ||
.button(icon: .bell) { } | ||
Divider() | ||
DodamNavigationBar.small(title: "Small") | ||
.button(icon: .plus) { } | ||
.button(icon: .bell) { } | ||
Divider() | ||
DodamNavigationBar.medium(title: "Medium") | ||
.button(icon: .plus) { } | ||
.button(icon: .bell) { } | ||
Divider() | ||
DodamNavigationBar.large(title: "Large") | ||
.button(icon: .plus) { } | ||
.button(icon: .bell) { } | ||
Divider() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,87 +1,35 @@ | ||
import SwiftUI | ||
|
||
@available(macOS 12, iOS 15, *) | ||
public struct DodamNavigationView<C: View>: View { | ||
public struct DodamNavigationView<C: View>: NavigationViewProtocol { | ||
|
||
private let title: String | ||
private let font: Font | ||
private let verticalSpacing: CGFloat? | ||
private let content: () -> C | ||
internal let navigationBar: DodamNavigationBar | ||
internal let buttons: [DodamNavigationBarButton] | ||
internal let content: () -> C | ||
|
||
private init( | ||
title: String, | ||
font: Font = .headline(.small), | ||
verticalSpacing: CGFloat? = nil, | ||
public init( | ||
navigationBar: DodamNavigationBar, | ||
buttons: [DodamNavigationBarButton] = .init(), | ||
@ViewBuilder content: @escaping () -> C | ||
) { | ||
self.title = title | ||
self.font = font | ||
self.verticalSpacing = verticalSpacing | ||
self.navigationBar = navigationBar | ||
self.buttons = buttons | ||
self.content = content | ||
} | ||
|
||
public static func `default`( | ||
title: String, | ||
@ViewBuilder content: @escaping () -> C | ||
) -> Self { | ||
.init( | ||
title: title, | ||
content: content | ||
) | ||
} | ||
|
||
public static func small( | ||
title: String, | ||
@ViewBuilder content: @escaping () -> C | ||
) -> Self { | ||
.init( | ||
title: title, | ||
font: .body(.large), | ||
content: content | ||
) | ||
} | ||
|
||
public static func medium( | ||
title: String, | ||
@ViewBuilder content: @escaping () -> C | ||
) -> Self { | ||
.init( | ||
title: title, | ||
verticalSpacing: 1, | ||
content: content | ||
) | ||
} | ||
|
||
public static func large( | ||
title: String, | ||
@ViewBuilder content: @escaping () -> C | ||
) -> Self { | ||
.init( | ||
title: title, | ||
font: .headline(.medium), | ||
verticalSpacing: 48, | ||
content: content | ||
) | ||
} | ||
|
||
private var text: Text { | ||
.init(title) | ||
.font(font) | ||
} | ||
|
||
public var body: some View { | ||
VStack { | ||
if let verticalSpacing { | ||
text | ||
.padding(.top, verticalSpacing) | ||
} | ||
VStack(spacing: 0) { | ||
applyButton(bar: navigationBar) | ||
content() | ||
.frame(maxWidth: .infinity, maxHeight: .infinity) | ||
} | ||
} | ||
} | ||
|
||
#Preview { | ||
DodamNavigationView.large(title: "Hello") { | ||
Text("a") | ||
DodamNavigationView.large(title: "Title") { | ||
Text("Hello") | ||
} | ||
.button(icon: .plus) { } | ||
.button(icon: .bell) { } | ||
} |
101 changes: 101 additions & 0 deletions
101
Source/DDS/Component/NavigationView/NavigationViewProtocol.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import SwiftUI | ||
|
||
@available(macOS 12, iOS 15, *) | ||
protocol NavigationViewProtocol: View { | ||
|
||
associatedtype C: View | ||
|
||
var navigationBar: DodamNavigationBar { get } | ||
var buttons: [DodamNavigationBarButton] { get } | ||
var content: () -> C { get } | ||
|
||
init( | ||
navigationBar: DodamNavigationBar, | ||
buttons: [DodamNavigationBarButton], | ||
@ViewBuilder content: @escaping () -> C | ||
) | ||
} | ||
|
||
extension NavigationViewProtocol { | ||
|
||
static func `default`( | ||
title: String, | ||
@ViewBuilder content: @escaping () -> C | ||
) -> Self { | ||
.init( | ||
navigationBar: .default(title: title), | ||
buttons: [], | ||
content: content | ||
) | ||
} | ||
|
||
static func small( | ||
title: String, | ||
@ViewBuilder content: @escaping () -> C | ||
) -> Self { | ||
.init( | ||
navigationBar: .small(title: title), | ||
buttons: [], | ||
content: content | ||
) | ||
} | ||
|
||
static func medium( | ||
title: String, | ||
@ViewBuilder content: @escaping () -> C | ||
) -> Self { | ||
.init( | ||
navigationBar: .medium(title: title), | ||
buttons: [], | ||
content: content | ||
) | ||
} | ||
|
||
static func large( | ||
title: String, | ||
@ViewBuilder content: @escaping () -> C | ||
) -> Self { | ||
.init( | ||
navigationBar: .large(title: title), | ||
buttons: [], | ||
content: content | ||
) | ||
} | ||
|
||
func button( | ||
icon: DodamIconography, | ||
action: @escaping () -> Void | ||
) -> Self { | ||
.init( | ||
navigationBar: self.navigationBar, | ||
buttons: self.buttons + [ | ||
.init( | ||
icon: icon, | ||
action: action | ||
) | ||
], | ||
content: self.content | ||
) | ||
} | ||
|
||
func applyButton( | ||
bar: DodamNavigationBar, | ||
index: Int = 0 | ||
) -> DodamNavigationBar { | ||
if !buttons.isEmpty { | ||
let item = buttons[index] | ||
let result = bar | ||
.button(icon: item.icon, action: item.action) | ||
if buttons.count != index + 1 { | ||
return applyButton( | ||
bar: result, | ||
index: index + 1 | ||
) | ||
} else { | ||
return result | ||
} | ||
} else { | ||
return bar | ||
} | ||
} | ||
} |
Oops, something went wrong.