Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[MOB-2007] BezierProgressBar 구현 #76

Open
wants to merge 4 commits into
base: feature/redesign_bezier
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions BezierSwift/Sources/Components/Progress/BezierProgressBar.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
//
// BezierProgressBar.swift
//
//
// Created by Tom on 9/16/24.
//

import SwiftUI

private enum Constant {
static let maxProgress: CGFloat = 1.0
}

// - MARK: BezierProgressBar
public struct BezierProgressBar: View {
// MARK: Size
public enum Size {
case small
case medium
}

// MARK: Variant
public enum Variant {
case primary
case secondary
case overBackground
}

// MARK: Properties
private let progress: CGFloat
private let size: Size
private let variant: Variant

// MARK: Initializer
/// - Parameters:
/// - progress: 진행 상태를 나타내는 값으로, 0.0에서 1.0 사이의 값을 사용합니다.
/// - size: 일반적으로 `medium` 사이즈를 사용하되, 영역이 좁은 경우 `small` 을 사용합니다.
/// - badge: `primary`을 일반적으로 사용하나, 중요도가 이보다 낮거나 시각적으로 너무 튀는 경우에는 `secondary` 를 사용할 수 있습니다. dimmed layer 와 함께 조합해서 사용되는 경우에는 bg 컬러가 다른 `overBackground`를 사용합니다.
public init(
progress: CGFloat,
size: Size = .small,
variant: Variant = .primary
) {
self.progress = progress
self.size = size
self.variant = variant
}

// MARK: Body
public var body: some View {
GeometryReader { proxy in
ZStack(alignment: .leading) {
Capsule(style: .circular)
.fill(self.trackColor.color)
.frame(maxWidth: .infinity)
.frame(height: self.height)
Capsule(style: .circular)
.fill(self.fillStyle)
.frame(height: self.height)
.frame(minWidth: self.minWidth)
.frame(
width: (proxy.size.width) * min(self.progress, Constant.maxProgress),
alignment: .leading
)
.animation(self.animation, value: self.progress)
}
}
}
}

// - MARK: Style
extension BezierProgressBar {
private var fillStyle: some ShapeStyle {
switch self.variant {
case .primary: BezierGradient.fgGreen.leadingToTrailing
case .secondary: BezierGradient.fgBlack.leadingToTrailing
case .overBackground: BezierGradient.fgGreen.leadingToTrailing
}
}

private var trackColor: BezierColor {
switch self.variant {
case .primary: .bgBlackLight
case .secondary: .bgBlackLight
case .overBackground: .bgAbsoluteWhiteNormal
}
}

private var height: CGFloat {
switch self.size {
case .small: 4
case .medium: 6
}
}

private var minWidth: CGFloat {
self.progress.isZero ? 0 : self.height
}

private var animation: Animation {
Animation.timingCurve(0.24, 0.1, 0.24, 1.0, duration: 1.0)
}
}

#Preview {
BezierProgressBar(progress: 0.2, size: .medium)
}
50 changes: 50 additions & 0 deletions BezierSwift/Sources/Foundation/Color/BezierGradient.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//
// BezierGradient.swift
//
//
// Created by Tom on 9/16/24.
//

import SwiftUI

public enum BezierGradient {
case fgGreen
case fgBlack
case bgPurple
case bgOrange
case bgGreen
case bgBlue

private var gradient: Gradient {
switch self {
case .fgGreen:
Gradient(colors: [Color(hex: GlobalColorToken.green400.hex), Color(hex: GlobalColorToken.green300.hex)])
case .fgBlack:
Gradient(colors: [BezierColor.fgBlackLightest.color, BezierColor.fgBlackLight.color])
case .bgPurple:
Gradient(colors: [Color(hex: GlobalColorToken.purple300.hex), Color(hex: GlobalColorToken.pink200.hex)])
case .bgOrange:
Gradient(colors: [Color(hex: GlobalColorToken.orange300.hex), Color(hex: GlobalColorToken.yellow200.hex)])
case .bgGreen:
Gradient(colors: [Color(hex: GlobalColorToken.green300.hex), Color(hex: GlobalColorToken.teal200.hex)])
case .bgBlue:
Gradient(colors: [Color(hex: GlobalColorToken.blue300.hex), Color(hex: GlobalColorToken.green200.hex)])
}
}

public var leadingToTrailing: LinearGradient {
LinearGradient(gradient: self.gradient, startPoint: .leading, endPoint: .trailing)
}

public var trailingToLeading: LinearGradient {
LinearGradient(gradient: self.gradient, startPoint: .trailing, endPoint: .leading)
}

public var topToBottom: LinearGradient {
LinearGradient(gradient: self.gradient, startPoint: .top, endPoint: .bottom)
}

public var bottomToTop: LinearGradient {
LinearGradient(gradient: self.gradient, startPoint: .bottom, endPoint: .top)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
E28D19612C365557009B34A2 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E28D195F2C365557009B34A2 /* SceneDelegate.swift */; };
E2A392B72C958A540015FA6F /* BezierAvatarExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2A392B62C958A540015FA6F /* BezierAvatarExample.swift */; };
E2A392B92C98169D0015FA6F /* BezierAvatarGroupExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2A392B82C98169D0015FA6F /* BezierAvatarGroupExample.swift */; };
E2A392BB2C98A0FB0015FA6F /* BezierProgressBarExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2A392BA2C98A0FB0015FA6F /* BezierProgressBarExample.swift */; };
E2EF05FC2C5A4CDC00C57676 /* BezierLoaderExample.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2EF05FB2C5A4CDC00C57676 /* BezierLoaderExample.swift */; };
/* End PBXBuildFile section */

Expand All @@ -37,6 +38,7 @@
E28D195F2C365557009B34A2 /* SceneDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
E2A392B62C958A540015FA6F /* BezierAvatarExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BezierAvatarExample.swift; sourceTree = "<group>"; };
E2A392B82C98169D0015FA6F /* BezierAvatarGroupExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BezierAvatarGroupExample.swift; sourceTree = "<group>"; };
E2A392BA2C98A0FB0015FA6F /* BezierProgressBarExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BezierProgressBarExample.swift; sourceTree = "<group>"; };
E2EF05FB2C5A4CDC00C57676 /* BezierLoaderExample.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BezierLoaderExample.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

Expand Down Expand Up @@ -70,6 +72,7 @@
E2EF05FB2C5A4CDC00C57676 /* BezierLoaderExample.swift */,
E2A392B62C958A540015FA6F /* BezierAvatarExample.swift */,
E2A392B82C98169D0015FA6F /* BezierAvatarGroupExample.swift */,
E2A392BA2C98A0FB0015FA6F /* BezierProgressBarExample.swift */,
);
path = Examples;
sourceTree = "<group>";
Expand Down Expand Up @@ -193,6 +196,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
E2A392BB2C98A0FB0015FA6F /* BezierProgressBarExample.swift in Sources */,
E258E6BE2C3D8D9C00F69680 /* BezierButtonExample.swift in Sources */,
E2EF05FC2C5A4CDC00C57676 /* BezierLoaderExample.swift in Sources */,
E2A392B92C98169D0015FA6F /* BezierAvatarGroupExample.swift in Sources */,
Expand Down
5 changes: 5 additions & 0 deletions Examples/SwiftUIExample/SwiftUIExample/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ struct ContentView: View {
} label: {
Text("Loader")
}
NavigationLink {
BezierProgressBarExample()
} label: {
Text("ProgressBar")
}
} header: {
Text("Status")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//
// BezierProgressBarExample.swift
// SwiftUIExample
//
// Created by Tom on 9/17/24.
//

import SwiftUI

import BezierSwift

struct BezierProgressBarExample: View {
@State var progress: CGFloat = 0

var body: some View {
BezierProgressBar(progress: self.progress, size: .medium, variant: .primary)
.onTapGesture {
self.progress += 0.3
}
}
}

#Preview {
BezierProgressBarExample()
}