Skip to content

Commit

Permalink
Merge pull request #131 from adevinta/feature/component/badge
Browse files Browse the repository at this point in the history
[Badge] Implemented Badge component
  • Loading branch information
alex-vecherov authored Jun 8, 2023
2 parents 87df024 + 9beb992 commit 1e2883a
Show file tree
Hide file tree
Showing 21 changed files with 1,835 additions and 1 deletion.
142 changes: 142 additions & 0 deletions core/Demo/Classes/BadgeUIView_Previews.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
//
// BadgeUIView_Previews.swift
// SparkCoreDemo
//
// Created by alex.vecherov on 22.05.23.
// Copyright © 2023 Adevinta. All rights reserved.
//

import SwiftUI
import SparkCore

private struct BadgePreviewFormatter: BadgeFormatting {
func formatText(for value: Int?) -> String {
guard let value else {
return "_"
}
return "\(value)"
}
}

struct UIBadgeView: UIViewRepresentable {

var views: [BadgeUIView]

func makeUIView(context: Context) -> some UIView {
let badgesStackView = UIStackView()
views.enumerated().forEach { index, badgeView in
let containerView = UIView()
containerView.translatesAutoresizingMaskIntoConstraints = false
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.text = "badge_\(index)"
containerView.addSubview(label)
containerView.addSubview(badgeView)
containerView.backgroundColor = .blue

NSLayoutConstraint.activate([
label.leadingAnchor.constraint(greaterThanOrEqualTo: containerView.leadingAnchor),
label.topAnchor.constraint(equalTo: containerView.topAnchor),
label.bottomAnchor.constraint(equalTo: containerView.bottomAnchor)
])
if index >= 3 && index <= 6 {
NSLayoutConstraint.activate([
badgeView.centerXAnchor.constraint(equalTo: label.trailingAnchor, constant: 5),
badgeView.centerYAnchor.constraint(equalTo: label.topAnchor, constant: -5)
])
} else {
NSLayoutConstraint.activate([
badgeView.leadingAnchor.constraint(equalTo: label.trailingAnchor, constant: 5),
badgeView.centerYAnchor.constraint(equalTo: label.centerYAnchor, constant: 0)
])
}

badgesStackView.addArrangedSubview(containerView)
}
badgesStackView.axis = .vertical
badgesStackView.alignment = .leading
badgesStackView.spacing = 30
badgesStackView.distribution = .fill

return badgesStackView
}

func updateUIView(_ uiView: UIViewType, context: Context) {
}
}

struct BadgeUIView_Previews: PreviewProvider {

struct BadgeUIViewBridge: View {
private var views = [
BadgeUIView(
theme: SparkTheme.shared,
badgeType: .alert,
value: 6
),
BadgeUIView(
theme: SparkTheme.shared,
badgeType: .primary,
badgeSize: .normal,
value: 22,
format: .overflowCounter(maxValue: 20)
),
BadgeUIView(
theme: SparkTheme.shared,
badgeType: .danger,
value: 10,
format: .custom(
formatter: BadgePreviewFormatter()
)
),
BadgeUIView(
theme: SparkTheme.shared,
badgeType: .info,
value: 20
),
BadgeUIView(
theme: SparkTheme.shared,
badgeType: .primary
),
BadgeUIView(
theme: SparkTheme.shared,
badgeType: .neutral,
isBadgeOutlined: false
),
BadgeUIView(
theme: SparkTheme.shared,
badgeType: .secondary,
value: 23
),
BadgeUIView(
theme: SparkTheme.shared,
badgeType: .success
)
]

var body: some View {
List {
Button("Change UIKit Badge 0 Type") {
views[0].setBadgeType(BadgeIntentType.allCases.randomElement() ?? .alert)
}
Button("Change UIKit Badge 1 Value") {
views[1].setBadgeValue(2)
}
Button("Change UIKit Badge 2 Outline") {
views[2].setBadgeOutlineEnabled(false)
}
Button("Change UIKit Badge 3 Size") {
views[3].setBadgeSize(.small)
}
UIBadgeView(views: views)
.frame(height: 400)
.listRowBackground(Color.gray.opacity(0.3))
}
}
}

static var previews: some View {
BadgeUIViewBridge()
.background(Color.gray.opacity(0.4))
}
}
149 changes: 149 additions & 0 deletions core/Demo/Classes/BadgeView_Previews.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
//
// BadgeView_Previews.swift
// SparkCoreDemo
//
// Created by alex.vecherov on 22.05.23.
// Copyright © 2023 Adevinta. All rights reserved.
//

import SwiftUI
import SparkCore

private struct BadgePreviewFormatter: BadgeFormatting {
func formatText(for value: Int?) -> String {
guard let value else {
return "_"
}
return "\(value)"
}
}

struct BadgeView_Previews: PreviewProvider {

struct BadgeContainerView: View {

@State var theme: Theme = SparkTheme.shared

@State var standartBadgeValue: Int? = 3
@State var standartBadgeIsOutlined: Bool = true

@State var smallCustomBadgeValue: Int? = 14
@State var smallCustomBadgeSize: BadgeSize = .small
@State var smallCustomBadgeIsOutlined: Bool = true
@State var smallCustomBadgeType: BadgeIntentType = .alert
@State var badgeFormat: BadgeFormat = .default

@State var standartDangerBadgeType: BadgeIntentType = .danger

@ScaledMetric var hOffset: CGFloat
@ScaledMetric var vOffset: CGFloat

var body: some View {
List {
Section(header: Text("SwiftUI Badge")) {
Button("Change Default Badge Value") {
standartBadgeValue = 23
standartBadgeIsOutlined.toggle()
badgeFormat = .overflowCounter(maxValue: 20)
}
Button("Change Small Custom Badge") {
smallCustomBadgeValue = 18
smallCustomBadgeSize = .normal
smallCustomBadgeIsOutlined.toggle()
smallCustomBadgeType = .primary
}
Button("Change Dange Badge") {
standartDangerBadgeType = .neutral
}
VStack(spacing: 100) {
HStack(spacing: 50) {
ZStack(alignment: .leading) {
Text("Default Badge")
BadgeView(
theme: theme,
badgeType: .primary,
value: standartBadgeValue
)
.format(badgeFormat)
.outlined(standartBadgeIsOutlined)
.offset(x: 100, y: -15)
}
ZStack(alignment: .leading) {
Text("Small Custom")
BadgeView(
theme: SparkTheme.shared,
badgeType: smallCustomBadgeType,
value: 22
)
.outlined(smallCustomBadgeIsOutlined)
.size(smallCustomBadgeSize)
.offset(x: 100, y: -15)
}
}

HStack(spacing: 55) {
ZStack(alignment: .leading) {
Text("Danger Badge")
BadgeView(
theme: SparkTheme.shared,
badgeType: standartDangerBadgeType,
value: 10
)
.format(.custom(
formatter: BadgePreviewFormatter()
))
.offset(x: 100, y: -15)
}
ZStack(alignment: .leading) {
Text("Text")
BadgeView(
theme: SparkTheme.shared,
badgeType: .info
)
.offset(x: 25, y: -15)
}
ZStack(alignment: .leading) {
Text("Text")
BadgeView(
theme: SparkTheme.shared,
badgeType: .neutral
)
.offset(x: 25, y: -15)
}
}

HStack(spacing: 50) {
HStack {
Text("Text")
BadgeView(
theme: SparkTheme.shared,
badgeType: .primary
)
}
HStack {
Text("Text")
BadgeView(
theme: SparkTheme.shared,
badgeType: .secondary
)
}
HStack {
Text("Text")
BadgeView(
theme: SparkTheme.shared,
badgeType: .success
)
}
}
}
.padding(.vertical, 15)
.listRowBackground(Color.gray.opacity(0.3))
}
}
}
}

static var previews: some View {
BadgeContainerView(hOffset: SparkTheme.shared.layout.spacing.xxLarge, vOffset: SparkTheme.shared.layout.spacing.medium * 1.5)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// BadgeAccessibilityIdentifier.swift
// Spark
//
// Created by alex.vecherov on 04.05.23.
// Copyright © 2023 Adevinta. All rights reserved.
//

import Foundation


public enum BadgeAccessibilityIdentifier {

// MARK: - Properties

public static let text = "spark-badge-text"
}
13 changes: 13 additions & 0 deletions core/Sources/Components/Badge/Constants/BadgeConstants.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// BadgeConstants.swift
// SparkCoreDemo
//
// Created by alex.vecherov on 22.05.23.
// Copyright © 2023 Adevinta. All rights reserved.
//

import Foundation

enum BadgeConstants {
static let emptySize = CGSize(width: 12, height: 12)
}
20 changes: 20 additions & 0 deletions core/Sources/Components/Badge/Properties/Private/BadgeColors.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//
// BadgeColors.swift
// Spark
//
// Created by alex.vecherov on 04.05.23.
// Copyright © 2023 Adevinta. All rights reserved.
//

import Foundation

// sourcery: AutoMockable
struct BadgeColors {

// MARK: - Properties

let backgroundColor: ColorToken
let borderColor: ColorToken
let foregroundColor: ColorToken
}

29 changes: 29 additions & 0 deletions core/Sources/Components/Badge/Properties/Public/BadgeBorder.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// BadgeBorder.swift
// SparkDemo
//
// Created by alex.vecherov on 17.05.23.
// Copyright © 2023 Adevinta. All rights reserved.
//

import Foundation

/// Structure that is used for configuring border of ``BadgeView``
///
/// List of properties:
/// - width
/// - radius
/// - color returned as ColorToken
public struct BadgeBorder {
var width: CGFloat
let radius: CGFloat
var color: ColorToken

mutating func setWidth(_ width: CGFloat) {
self.width = width
}

mutating func setColor(_ color: ColorToken) {
self.color = color
}
}
Loading

0 comments on commit 1e2883a

Please sign in to comment.