Skip to content

Commit

Permalink
Merge pull request #495 from adevinta/feature/component/chip_469
Browse files Browse the repository at this point in the history
[Chip#469] Update designs to latest version
  • Loading branch information
michael-zimmermann authored Oct 19, 2023
2 parents 66828fd + a06b71c commit 885449c
Show file tree
Hide file tree
Showing 28 changed files with 1,729 additions and 1,231 deletions.
1 change: 0 additions & 1 deletion core/Sources/Components/Chip/Enum/ChipVariant.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import Foundation
/// The different variants of a chip
public enum ChipVariant: CaseIterable {
case outlined
case filled
case tinted
case dashed
}
15 changes: 0 additions & 15 deletions core/Sources/Components/Chip/Model/ChipColors.swift

This file was deleted.

27 changes: 23 additions & 4 deletions core/Sources/Components/Chip/Model/ChipIntentColors.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,27 @@ struct ChipIntentColors {

// MARK: - Properties

let principal: any ColorToken
let subordinate: any ColorToken
let tintedPrincipal: any ColorToken
let tintedSubordinate: any ColorToken
let border: any ColorToken
let text: any ColorToken
let selectedText: any ColorToken
let background: any ColorToken
let pressedBackground: any ColorToken
let selectedBackground: any ColorToken
let disabledBackground: (any ColorToken)?

init(border: any ColorToken,
text: any ColorToken,
selectedText: any ColorToken,
background: any ColorToken,
pressedBackground: any ColorToken,
selectedBackground: any ColorToken,
disabledBackground: (any ColorToken)? = nil) {
self.border = border
self.text = text
self.selectedText = selectedText
self.background = background
self.pressedBackground = pressedBackground
self.selectedBackground = selectedBackground
self.disabledBackground = disabledBackground
}
}
3 changes: 2 additions & 1 deletion core/Sources/Components/Chip/Model/ChipState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@ import Foundation

struct ChipState {

static let `default` = ChipState(isEnabled: true, isPressed: false)
static let `default` = ChipState(isEnabled: true, isPressed: false, isSelected: false)

let isEnabled: Bool
let isPressed: Bool
let isSelected: Bool

var isDisabled: Bool {
return !self.isEnabled
Expand Down
13 changes: 9 additions & 4 deletions core/Sources/Components/Chip/Model/ChipStateColors.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,28 @@ import Foundation

/// The colors definie a chip
struct ChipStateColors {
let background: any ColorToken
var background: any ColorToken
let border: any ColorToken
let foreground: any ColorToken
var foreground: any ColorToken
var opacity: CGFloat

init(background: any ColorToken, border: any ColorToken, foreground: any ColorToken, opacity: CGFloat = 1.0) {
init(background: any ColorToken = ColorTokenDefault.clear,
border: any ColorToken,
foreground: any ColorToken,
opacity: CGFloat = 1.0) {
self.background = background
self.border = border
self.foreground = foreground
self.opacity = opacity
}

}

extension ChipStateColors: Equatable {
static func == (lhs: ChipStateColors, rhs: ChipStateColors) -> Bool {
return lhs.background.equals(rhs.background) &&
lhs.border.equals(rhs.border) &&
lhs.foreground.equals(rhs.foreground) && lhs.opacity == rhs.opacity
lhs.foreground.equals(rhs.foreground) &&
lhs.opacity == rhs.opacity
}
}
5 changes: 3 additions & 2 deletions core/Sources/Components/Chip/Model/ChipStateTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ final class ChipStateTests: XCTestCase {
XCTAssertTrue(sut.isEnabled, "By default enabled should be true.")
XCTAssertFalse(sut.isDisabled, "Expected isDisabled to be the oposite of enabled.")
XCTAssertFalse(sut.isPressed, "By default, the pressed state is not set")
XCTAssertFalse(sut.isSelected, "By default, the selected state is not set")
}

func test_disabled() {
let sut = ChipState(isEnabled: false, isPressed: true)
let sut = ChipState(isEnabled: false, isPressed: true, isSelected: false)

XCTAssertFalse(sut.isEnabled, "Expeted the state not to be enabled.")
XCTAssertFalse(sut.isEnabled, "Expected the state not to be enabled.")
XCTAssertTrue(sut.isDisabled, "Expected the state to be disabled.")
XCTAssertTrue(sut.isPressed, "The pressed state should be true.")
}
Expand Down
96 changes: 96 additions & 0 deletions core/Sources/Components/Chip/UseCase/ChipGetColorsUseCase.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
//
// ChipGetColorsUseCase.swift
// SparkDemo
//
// Created by michael.zimmermann on 03.05.23.
// Copyright © 2023 Adevinta. All rights reserved.
//

import UIKit
import SwiftUI
import Foundation

/// A use case to calculate the colors of a chip depending on the theme, variant and intent
// sourcery: AutoMockable
protocol ChipGetColorsUseCasable {
/// Function `execute` calculates the chip colors
///
/// Parameters:
/// - theme: The spark theme.
/// - variant: The variant of the chip, if it is outlined, filled, etc.
/// - intent: The intent color, e.g. main, support.
/// - state: The current state of the chip
/// Returns:
/// ChipColors: all the colors used for the chip
func execute(theme: Theme,
variant: ChipVariant,
intent: ChipIntent,
state: ChipState
) -> ChipStateColors
}

/// ChipGetColorsUseCase: A use case to calculate the colors of a chip depending on the theme, variand and intent
struct ChipGetColorsUseCase: ChipGetColorsUseCasable {
// MARK: - Properties
private let outlinedIntentColorsUseCase: ChipGetIntentColorsUseCasable
private let tintedIntentColorsUseCase: ChipGetIntentColorsUseCasable

// MARK: - Initializer
/// Initializer
///
/// Parameters:
/// - outlinedIntentColorsUseCase: A use case to calculate the intent colors of outlined chips.
/// - tintedIntentColorsUseCase: A use case to calculate the intent colors of tinted chips.
init(outlinedIntentColorsUseCase: ChipGetIntentColorsUseCasable = ChipGetOutlinedIntentColorsUseCase(),
tintedIntentColorsUseCase: ChipGetIntentColorsUseCasable = ChipGetTintedIntentColorsUseCase()
) {
self.outlinedIntentColorsUseCase = outlinedIntentColorsUseCase
self.tintedIntentColorsUseCase = tintedIntentColorsUseCase

}

// MARK: - Functions

/// The funcion execute calculates the chip colors based on the parameters.
///
/// Parameters:
/// - theme: The current theme to be used
/// - variant: The variant of the chip, whether it's filled, outlined, etc.
/// - intent: The intent color of the chip, e.g. main, support
/// - state: The current state of the chip, e.g. selected, enabled, pressed
func execute(theme: Theme,
variant: ChipVariant,
intent: ChipIntent,
state: ChipState) -> ChipStateColors {

let intentUseCase: ChipGetIntentColorsUseCasable = variant == .tinted ? self.tintedIntentColorsUseCase : self.outlinedIntentColorsUseCase

let colors = intentUseCase.execute(theme: theme, intent: intent)

if state.isPressed {
return .init(
background: colors.pressedBackground,
border: colors.border,
foreground: colors.text)
}

var stateColors = ChipStateColors(
background: colors.background,
border: colors.border,
foreground: colors.text)

if state.isSelected {
stateColors.background = colors.selectedBackground
stateColors.foreground = colors.selectedText
}

if state.isDisabled {
if let backgroundColor = colors.disabledBackground {
stateColors.background = backgroundColor
}
stateColors.opacity = theme.dims.dim3
}

return stateColors
}
}
166 changes: 166 additions & 0 deletions core/Sources/Components/Chip/UseCase/ChipGetColorsUseCaseTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
//
// ChipGetColorsUseCaseTests.swift
// SparkCoreTests
//
// Created by michael.zimmermann on 08.05.23.
// Copyright © 2023 Adevinta. All rights reserved.
//

import SwiftUI
import XCTest

@testable import SparkCore

final class ChipGetColorsUseCaseTests: XCTestCase {

// MARK: - Properties
private var sut: ChipGetColorsUseCase!
private var outlinedIntentColorsUseCase: ChipGetIntentColorsUseCasableGeneratedMock!
private var tintedIntentColorsUseCase: ChipGetIntentColorsUseCasableGeneratedMock!
private var theme: ThemeGeneratedMock!

// MARK: - Setup
override func setUp() {
super.setUp()

self.outlinedIntentColorsUseCase = .init()
self.tintedIntentColorsUseCase = .init()
self.sut = .init(
outlinedIntentColorsUseCase: self.outlinedIntentColorsUseCase,
tintedIntentColorsUseCase: self.tintedIntentColorsUseCase)
self.theme = .init()

let dims = DimsGeneratedMock()
dims.dim3 = 0.33
self.theme.dims = dims
}

// MARK: - Tests

func test_outlined_variant_uses_correct_use_case() {
// Given
let chipIntentColors = ChipIntentColors.mocked()

self.outlinedIntentColorsUseCase.executeWithThemeAndIntentReturnValue = chipIntentColors

let expectedColors = ChipStateColors(
background: chipIntentColors.background,
border: chipIntentColors.border,
foreground: chipIntentColors.text,
opacity: 1.0)

// When
let colors = self.sut.execute(theme: self.theme, variant: .outlined, intent: .basic, state: .default)

XCTAssertEqual(colors, expectedColors)
}

func test_tinted_variant_uses_correct_use_case() {
// Given
let chipIntentColors = ChipIntentColors.mocked()

self.tintedIntentColorsUseCase.executeWithThemeAndIntentReturnValue = chipIntentColors

let expectedColors = ChipStateColors(
background: chipIntentColors.background,
border: chipIntentColors.border,
foreground: chipIntentColors.text,
opacity: 1.0)

// When
let colors = self.sut.execute(theme: self.theme, variant: .tinted, intent: .basic, state: .default)

XCTAssertEqual(colors, expectedColors)
}

func test_pressed_has_correct_background() {
// Given
let chipIntentColors = ChipIntentColors.mocked()

self.tintedIntentColorsUseCase.executeWithThemeAndIntentReturnValue = chipIntentColors

let expectedColors = ChipStateColors(
background: chipIntentColors.pressedBackground,
border: chipIntentColors.border,
foreground: chipIntentColors.text,
opacity: 1.0)

// When
let colors = self.sut.execute(theme: self.theme, variant: .tinted, intent: .basic, state: .pressed)

XCTAssertEqual(colors, expectedColors)
}

func test_selected_has_correct_backgorund_and_text() {
// Given
let chipIntentColors = ChipIntentColors.mocked()

self.tintedIntentColorsUseCase.executeWithThemeAndIntentReturnValue = chipIntentColors

let expectedColors = ChipStateColors(
background: chipIntentColors.selectedBackground,
border: chipIntentColors.border,
foreground: chipIntentColors.selectedText,
opacity: 1.0)

// When
let colors = self.sut.execute(theme: self.theme, variant: .tinted, intent: .basic, state: .selected)

XCTAssertEqual(colors, expectedColors)
}

func test_disabled_has_correct_opacity() {
// Given
let chipIntentColors = ChipIntentColors.mocked()

self.tintedIntentColorsUseCase.executeWithThemeAndIntentReturnValue = chipIntentColors

let expectedColors = ChipStateColors(
background: chipIntentColors.background,
border: chipIntentColors.border,
foreground: chipIntentColors.text,
opacity: self.theme.dims.dim3)

// When
let colors = self.sut.execute(theme: self.theme, variant: .tinted, intent: .basic, state: .disabled)

XCTAssertEqual(colors, expectedColors)
}

func test_selected_and_disabled_has_correct_background() {
// Given
let chipIntentColors = ChipIntentColors.mocked()

self.tintedIntentColorsUseCase.executeWithThemeAndIntentReturnValue = chipIntentColors

let expectedColors = ChipStateColors(
background: chipIntentColors.selectedBackground,
border: chipIntentColors.border,
foreground: chipIntentColors.selectedText,
opacity: self.theme.dims.dim3)

// When
let colors = self.sut.execute(theme: self.theme, variant: .tinted, intent: .basic, state: .selectedDisabled)

XCTAssertEqual(colors, expectedColors)
}
}

private extension ChipIntentColors {
static func mocked() -> ChipIntentColors {
return .init(
border: ColorTokenGeneratedMock.random(),
text: ColorTokenGeneratedMock.random(),
selectedText: ColorTokenGeneratedMock.random(),
background: ColorTokenGeneratedMock.random(),
pressedBackground: ColorTokenGeneratedMock.random(),
selectedBackground: ColorTokenGeneratedMock.random())
}
}

private extension ChipState {
static let pressed = ChipState(isEnabled: true, isPressed: true, isSelected: false)
static let disabled = ChipState(isEnabled: false, isPressed: false, isSelected: false)
static let selected = ChipState(isEnabled: true, isPressed: false, isSelected: true)
static let selectedDisabled = ChipState(isEnabled: false, isPressed: false, isSelected: true)
}
Loading

0 comments on commit 885449c

Please sign in to comment.