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

[Chip#577] Give user possibility to enable action on extra component. #578

Merged
merged 1 commit into from
Oct 26, 2023
Merged
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
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
Loading