Skip to content

Commit

Permalink
feat: Create ScrollView
Browse files Browse the repository at this point in the history
  • Loading branch information
Mercen-Lee committed Apr 1, 2024
1 parent 97bda6b commit bbe7406
Show file tree
Hide file tree
Showing 6 changed files with 359 additions and 122 deletions.
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
}
144 changes: 144 additions & 0 deletions Source/DDS/Component/NavigationBar/NavigationBar.swift
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()
}
}
84 changes: 16 additions & 68 deletions Source/DDS/Component/NavigationView/NavigationView.swift
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 Source/DDS/Component/NavigationView/NavigationViewProtocol.swift
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
}
}
}
Loading

0 comments on commit bbe7406

Please sign in to comment.