Skip to content

Commit

Permalink
Merge pull request #578 from adevinta/feature/component/chip-interact…
Browse files Browse the repository at this point in the history
…ion-577

[Chip#577] Give user possibility to enable action on extra component.
  • Loading branch information
michael-zimmermann authored Oct 26, 2023
2 parents 8f0b1e1 + 575e534 commit 34b061e
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 41 deletions.
4 changes: 4 additions & 0 deletions core/Sources/Components/Chip/View/UIKit/ChipUIView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,10 @@ public final class ChipUIView: UIControl {
self.viewModel.isPressed = false
}
}

public func enableComponentUserInteraction(_ isEnabled: Bool) {
self.stackView.isUserInteractionEnabled = isEnabled
}
}

// MARK: - Label priorities
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,19 +75,7 @@ final class ChipComponentUIView: ComponentUIView {
}

self.viewModel.$alignment.subscribe(in: &self.cancellables) { [weak self] alignment in
guard let self = self else { return }
let iconAlignment: ChipComponentUIViewModel.IconPosition
if self.viewModel.showIcon {
switch alignment {
case .leadingIcon: iconAlignment = .leading
case .trailingIcon: iconAlignment = .trailing
@unknown default: fatalError()
}
} else {
iconAlignment = .none
}
self.viewModel.iconConfigurationItemViewModel.buttonTitle = iconAlignment.name
self.componentView.alignment = alignment
self?.componentView.alignment = alignment
}

self.viewModel.$title.subscribe(in: &self.cancellables) { [weak self] title in
Expand All @@ -96,7 +84,6 @@ final class ChipComponentUIView: ComponentUIView {
self.componentView.text = title
}


self.viewModel.$icon.subscribe(in: &self.cancellables) { [weak self] icon in
guard let self = self else { return }

Expand All @@ -106,6 +93,11 @@ final class ChipComponentUIView: ComponentUIView {
self.viewModel.$badge.subscribe(in: &self.cancellables) { [weak self] badge in
guard let self = self else { return }

if let _ = badge as? UIButton {
self.componentView.enableComponentUserInteraction(true)
} else {
self.componentView.enableComponentUserInteraction(false)
}
self.componentView.component = badge
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ final class ChipComponentViewController: UIViewController {
self.viewModel.showIconPosition.subscribe(in: &self.cancellables) { variants in
self.presentIconAlignmentActionSheet(variants)
}

self.viewModel.showExtraComponent.subscribe(in: &self.cancellables) { variants in
self.presentExtraComponentActionSheet(variants)
}
}
}

Expand Down Expand Up @@ -122,13 +126,16 @@ extension ChipComponentViewController {
let actionSheet = SparkActionSheet<ChipComponentUIViewModel.IconPosition>.init(
values: variants,
texts: variants.map{ $0.name }) { variant in
switch variant {
case .none: self.viewModel.showIcon = false
case .leading: self.viewModel.showIcon = true
self.viewModel.alignment = .leadingIcon
case .trailing: self.viewModel.showIcon = true
self.viewModel.alignment = .trailingIcon
}
self.viewModel.iconAlignmentDidUpdate(variant)
}
self.present(actionSheet, animated: true)
}

private func presentExtraComponentActionSheet(_ variants: [ChipComponentUIViewModel.ExtraComponent]) {
let actionSheet = SparkActionSheet<ChipComponentUIViewModel.ExtraComponent>.init(
values: variants,
texts: variants.map{ $0.name }) { variant in
self.viewModel.extraComponentDidUpdate(variant)
}
self.present(actionSheet, animated: true)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ final class ChipComponentUIViewModel: ComponentUIViewModel {
case none
}

enum ExtraComponent: CaseIterable {
case badge
case button
case none
}

private static let alertIcon = UIImage(imageLiteralResourceName: "alert")

private var label: String? = "Label" {
Expand Down Expand Up @@ -47,13 +53,19 @@ final class ChipComponentUIViewModel: ComponentUIViewModel {
.eraseToAnyPublisher()
}

var showExtraComponent: AnyPublisher<[ExtraComponent], Never> {
showExtraComponentSheetSubject
.eraseToAnyPublisher()
}

var themes = ThemeCellModel.themes

// MARK: - Private Properties
private var showThemeSheetSubject: PassthroughSubject<[ThemeCellModel], Never> = .init()
private var showIntentSheetSubject: PassthroughSubject<[ChipIntent], Never> = .init()
private var showVariantSheetSubject: PassthroughSubject<[ChipVariant], Never> = .init()
private var showIconPositionSheetSubject: PassthroughSubject<[IconPosition], Never> = .init()
private var showExtraComponentSheetSubject: PassthroughSubject<[ExtraComponent], Never> = .init()

// MARK: - Items Properties
lazy var themeConfigurationItemViewModel: ComponentsConfigurationItemUIViewModel = {
Expand Down Expand Up @@ -81,10 +93,21 @@ final class ChipComponentUIViewModel: ComponentUIViewModel {
}()

lazy var iconConfigurationItemViewModel: ComponentsConfigurationItemUIViewModel = {
return .init(
let viewModel = ComponentsConfigurationItemUIViewModel(
name: "Icon Alignment",
type: .button,
target: (source: self, action: #selector(self.presentIconPositonSheet)))
viewModel.buttonTitle = IconPosition.none.name
return viewModel
}()

lazy var extraComponentConfigurationItemViewModel: ComponentsConfigurationItemUIViewModel = {
let viewModel = ComponentsConfigurationItemUIViewModel(
name: "Extra Component",
type: .button,
target: (source: self, action: #selector(self.presentExtraComponentSheet)))
viewModel.buttonTitle = ExtraComponent.none.name
return viewModel
}()

lazy var labelContentConfigurationItemViewModel: ComponentsConfigurationItemUIViewModel = {
Expand All @@ -94,13 +117,6 @@ final class ChipComponentUIViewModel: ComponentUIViewModel {
target: (source: self, action: #selector(self.labelChanged(_:))))
}()

lazy var badgeConfigurationItemViewModel: ComponentsConfigurationItemUIViewModel = {
return .init(
name: "Show Badge",
type: .checkbox(title: "", isOn: self.showBadge),
target: (source: self, action: #selector(self.showBadgeChanged)))
}()

lazy var disableConfigurationItemViewModel: ComponentsConfigurationItemUIViewModel = {
return .init(
name: "Enable",
Expand Down Expand Up @@ -128,12 +144,6 @@ final class ChipComponentUIViewModel: ComponentUIViewModel {
}
}

var showBadge = false {
didSet {
self.badge = self.showBadge ? self.createBadge() : nil
}
}

// swiftlint:disable all
var hasAction: Bool {
set {
Expand All @@ -149,7 +159,7 @@ final class ChipComponentUIViewModel: ComponentUIViewModel {
@Published var intent: ChipIntent
@Published var variant: ChipVariant
@Published var alignment: ChipAlignment = .leadingIcon
@Published var badge: BadgeUIView?
@Published var badge: UIView?
@Published var isEnabled = true
@Published var isSelected = false
@Published var title: String? = "Label"
Expand All @@ -162,8 +172,8 @@ final class ChipComponentUIViewModel: ComponentUIViewModel {
self.intentConfigurationItemViewModel,
self.variantConfigurationItemViewModel,
self.iconConfigurationItemViewModel,
self.extraComponentConfigurationItemViewModel,
self.labelContentConfigurationItemViewModel,
self.badgeConfigurationItemViewModel,
self.disableConfigurationItemViewModel,
self.selectedConfigurationItemViewModel,
self.hasActionConfigurationItemViewModel
Expand Down Expand Up @@ -196,11 +206,56 @@ final class ChipComponentUIViewModel: ComponentUIViewModel {
return badge
}

private func createButton() -> UIButton {
let button = UIButton()

let image = UIImage(systemName: "xmark.circle")?
.withRenderingMode(.alwaysTemplate)

var configuration = UIButton.Configuration.bordered()
configuration.image = image
configuration.contentInsets = NSDirectionalEdgeInsets(top: 5, leading: 5, bottom: 5, trailing: 5)
configuration.baseBackgroundColor = .clear

button.configuration = configuration
button.addTarget(self, action: #selector(self.deleteItem), for: .touchUpInside)
button.translatesAutoresizingMaskIntoConstraints = false

button.tintColor = self.theme.colors.basic.basic.uiColor
return button
}

func iconAlignmentDidUpdate(_ alignment: IconPosition) {
switch alignment {
case .none: self.showIcon = false
case .leading: self.showIcon = true
self.alignment = .leadingIcon
case .trailing: self.showIcon = true
self.alignment = .trailingIcon
}

self.iconConfigurationItemViewModel.buttonTitle = alignment.name
}

func extraComponentDidUpdate(_ component: ExtraComponent) {
self.extraComponentConfigurationItemViewModel.buttonTitle = component.name

switch component {
case .none: self.badge = nil
case .button: self.badge = self.createButton()
case .badge: self.badge = self.createBadge()
}
}

}

// MARK: - Navigation
extension ChipComponentUIViewModel {

@objc func deleteItem() {

}

@objc func presentThemeSheet() {
self.showThemeSheetSubject.send(themes)
}
Expand All @@ -217,6 +272,10 @@ extension ChipComponentUIViewModel {
self.showIconPositionSheetSubject.send(IconPosition.allCases)
}

@objc func presentExtraComponentSheet() {
self.showExtraComponentSheetSubject.send(ExtraComponent.allCases)
}

@objc func labelChanged(_ textField: UITextField) {
if textField.text?.isEmpty == false {
self.label = textField.text
Expand All @@ -225,10 +284,6 @@ extension ChipComponentUIViewModel {
}
}

@objc func showBadgeChanged() {
self.showBadge.toggle()
}

@objc func showIconChanged() {
self.showIcon.toggle()
}
Expand Down

0 comments on commit 34b061e

Please sign in to comment.