-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1083 from adevinta/divider-demo
New component: Divider
- Loading branch information
Showing
9 changed files
with
456 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
85 changes: 85 additions & 0 deletions
85
.Demo/Classes/View/Components/Divider/SwiftUI/DividerComponentView.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
// | ||
// DividerComponentView.swift | ||
// SparkDemo | ||
// | ||
// Created by louis.borlee on 31/07/2024. | ||
// Copyright © 2024 Adevinta. All rights reserved. | ||
// | ||
|
||
import SwiftUI | ||
import SparkDivider | ||
|
||
struct DividerComponentView: View { | ||
|
||
private let theme = SparkTheme() | ||
|
||
@State private var text: String = "Text" | ||
@State private var intent: DividerIntent = .outline | ||
@State private var axis: DividerAxis = .horizontal | ||
@State private var alignment: DividerAlignment = .center | ||
|
||
@State private var withText: CheckboxSelectionState = .unselected | ||
|
||
var body: some View { | ||
Component( | ||
name: "Divider") { | ||
EnumSelector( | ||
title: "Intent", | ||
dialogTitle: "Select an intent", | ||
values: DividerIntent.allCases, | ||
value: self.$intent | ||
) | ||
EnumSelector( | ||
title: "Axis", | ||
dialogTitle: "Select an axis", | ||
values: DividerAxis.allCases, | ||
value: self.$axis | ||
) | ||
EnumSelector( | ||
title: "Alignment", | ||
dialogTitle: "Select an alignment", | ||
values: DividerAlignment.allCases, | ||
value: self.$alignment | ||
) | ||
HStack(spacing: 12) { | ||
Text("Text") | ||
TextField("Divider text", text: $text) | ||
.textFieldStyle(.roundedBorder) | ||
} | ||
} integration: { | ||
let divider = divider() | ||
if axis == .vertical { | ||
divider | ||
.frame(height: 300) | ||
} else { | ||
divider | ||
} | ||
} | ||
} | ||
|
||
@ViewBuilder | ||
private func divider() -> some View { | ||
HStack { | ||
Spacer(minLength: 0) | ||
if text.isEmpty == false { | ||
DividerView( | ||
theme: theme, | ||
intent: intent, | ||
axis: axis, | ||
alignment: alignment, | ||
text: { | ||
Text(text) | ||
} | ||
) | ||
} else { | ||
DividerView( | ||
theme: SparkTheme(), | ||
intent: intent, | ||
axis: axis, | ||
alignment: alignment | ||
) | ||
} | ||
Spacer(minLength: 0) | ||
} | ||
} | ||
} |
103 changes: 103 additions & 0 deletions
103
.Demo/Classes/View/Components/Divider/UIKit/DividerComponentUIView.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
// | ||
// DividerComponentUIView.swift | ||
// SparkDemo | ||
// | ||
// Created by louis.borlee on 31/07/2024. | ||
// Copyright © 2024 Adevinta. All rights reserved. | ||
// | ||
|
||
import Combine | ||
import UIKit | ||
@_spi(SI_SPI) import SparkCommon | ||
|
||
final class DividerComponentUIView: ComponentUIView { | ||
|
||
// MARK: - Components | ||
private let componentView: DividerUIView | ||
|
||
// MARK: - Properties | ||
|
||
private let viewModel: DividerComponentUIViewModel | ||
private var cancellables: Set<AnyCancellable> = [] | ||
|
||
private var heightConstraint = NSLayoutConstraint() | ||
|
||
// MARK: - Initializer | ||
init(viewModel: DividerComponentUIViewModel) { | ||
self.viewModel = viewModel | ||
|
||
let divider = DividerUIView( | ||
theme: self.viewModel.theme, | ||
intent: self.viewModel.intent | ||
) | ||
divider.label.text = self.viewModel.text | ||
divider.label.numberOfLines = 0 | ||
divider.axis = self.viewModel.axis | ||
divider.alignment = self.viewModel.alignment | ||
|
||
self.componentView = divider | ||
|
||
super.init( | ||
viewModel: viewModel, | ||
integrationStackViewAlignment: .fill, | ||
componentView: self.componentView | ||
) | ||
|
||
// Setup | ||
self.setupSubscriptions() | ||
} | ||
|
||
required init?(coder: NSCoder) { | ||
fatalError("init(coder:) has not been implemented") | ||
} | ||
|
||
// MARK: - Subscribe | ||
private func setupSubscriptions() { | ||
self.viewModel.$theme.subscribe(in: &self.cancellables) { [weak self] theme in | ||
guard let self = self else { return } | ||
let themes = self.viewModel.themes | ||
let themeTitle: String? = theme is SparkTheme ? themes.first?.title : themes.last?.title | ||
|
||
self.viewModel.themeConfigurationItemViewModel.buttonTitle = themeTitle | ||
self.viewModel.configurationViewModel.update(theme: theme) | ||
|
||
self.componentView.theme = theme | ||
} | ||
|
||
self.viewModel.$intent.subscribe(in: &self.cancellables) { [weak self] intent in | ||
guard let self = self else { return } | ||
self.viewModel.intentConfigurationItemViewModel.buttonTitle = intent.name | ||
self.componentView.intent = intent | ||
} | ||
|
||
self.viewModel.$axis.subscribe(in: &self.cancellables) { [weak self] axis in | ||
guard let self = self else { return } | ||
self.viewModel.axisConfigurationItemViewModel.buttonTitle = axis.name | ||
self.componentView.axis = axis | ||
if axis == .vertical { | ||
self.heightConstraint = self.componentView.heightAnchor.constraint(equalToConstant: 300) | ||
self.heightConstraint.isActive = true | ||
} else { | ||
self.heightConstraint.isActive = false | ||
self.componentView.removeConstraint(self.heightConstraint) | ||
} | ||
} | ||
|
||
self.viewModel.$alignment.subscribe(in: &self.cancellables) { [weak self] alignment in | ||
guard let self = self else { return } | ||
self.viewModel.alignmentConfigurationItemViewModel.buttonTitle = alignment.name | ||
self.componentView.alignment = alignment | ||
} | ||
|
||
self.viewModel.$text.subscribe(in: &self.cancellables) { [weak self] text in | ||
guard let self = self else { return } | ||
self.viewModel.textConfigurationItemViewModel.buttonTitle = text | ||
self.componentView.label.text = text | ||
if let text, text.isEmpty == false { | ||
self.componentView.showLabel = true | ||
} else { | ||
self.componentView.showLabel = false | ||
} | ||
} | ||
} | ||
} |
128 changes: 128 additions & 0 deletions
128
.Demo/Classes/View/Components/Divider/UIKit/DividerComponentUIViewController.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
// | ||
// DividerComponentUIViewController.swift | ||
// SparkDemo | ||
// | ||
// Created by louis.borlee on 31/07/2024. | ||
// Copyright © 2024 Adevinta. All rights reserved. | ||
// | ||
|
||
import Combine | ||
import SparkCore | ||
import SwiftUI | ||
import UIKit | ||
@_spi(SI_SPI) import SparkCommon | ||
|
||
final class DividerComponentUIViewController: UIViewController { | ||
|
||
// MARK: - Published Properties | ||
@ObservedObject private var themePublisher = SparkThemePublisher.shared | ||
|
||
// MARK: - Properties | ||
let componentView: DividerComponentUIView | ||
let viewModel: DividerComponentUIViewModel | ||
private var cancellables: Set<AnyCancellable> = [] | ||
|
||
// MARK: - Initializer | ||
init(viewModel: DividerComponentUIViewModel) { | ||
self.viewModel = viewModel | ||
self.componentView = DividerComponentUIView(viewModel: viewModel) | ||
super.init(nibName: nil, bundle: nil) | ||
|
||
self.componentView.viewController = self | ||
} | ||
|
||
required init?(coder: NSCoder) { | ||
fatalError("init(coder:) has not been implemented") | ||
} | ||
|
||
// MARK: - Lifecycle | ||
override func loadView() { | ||
super.loadView() | ||
view = componentView | ||
} | ||
|
||
// MARK: - ViewDidLoad | ||
override func viewDidLoad() { | ||
super.viewDidLoad() | ||
self.navigationItem.title = "Divider" | ||
self.addPublisher() | ||
} | ||
|
||
// MARK: - Add Publishers | ||
private func addPublisher() { | ||
|
||
self.themePublisher | ||
.$theme | ||
.sink { [weak self] theme in | ||
guard let self = self else { return } | ||
self.viewModel.theme = theme | ||
self.navigationController?.navigationBar.tintColor = theme.colors.main.main.uiColor | ||
} | ||
.store(in: &self.cancellables) | ||
|
||
self.viewModel.showThemeSheet.subscribe(in: &self.cancellables) { intents in | ||
self.presentThemeActionSheet(intents) | ||
} | ||
|
||
self.viewModel.showIntentSheet.subscribe(in: &self.cancellables) { intents in | ||
self.presentIntentActionSheet(intents) | ||
} | ||
|
||
self.viewModel.showAxisSheet.subscribe(in: &self.cancellables) { axis in | ||
self.presentAxisActionSheet(axis) | ||
} | ||
|
||
self.viewModel.showAlignmentSheet.subscribe(in: &self.cancellables) { alignments in | ||
self.presentAlignmentActionSheet(alignments) | ||
} | ||
} | ||
} | ||
|
||
// MARK: - Builder | ||
extension DividerComponentUIViewController { | ||
|
||
static func build() -> DividerComponentUIViewController { | ||
let viewModel = DividerComponentUIViewModel(theme: SparkThemePublisher.shared.theme) | ||
return DividerComponentUIViewController(viewModel: viewModel) | ||
} | ||
} | ||
|
||
// MARK: - Navigation | ||
extension DividerComponentUIViewController { | ||
|
||
private func presentThemeActionSheet(_ themes: [ThemeCellModel]) { | ||
let actionSheet = SparkActionSheet<Theme>.init( | ||
values: themes.map { $0.theme }, | ||
texts: themes.map { $0.title }) { theme in | ||
self.themePublisher.theme = theme | ||
} | ||
self.present(actionSheet, isAnimated: true) | ||
} | ||
|
||
private func presentIntentActionSheet(_ intents: [DividerIntent]) { | ||
let actionSheet = SparkActionSheet<DividerIntent>.init( | ||
values: intents, | ||
texts: intents.map { $0.name }) { intent in | ||
self.viewModel.intent = intent | ||
} | ||
self.present(actionSheet, isAnimated: true) | ||
} | ||
|
||
private func presentAxisActionSheet(_ axis: [DividerAxis]) { | ||
let actionSheet = SparkActionSheet<DividerAxis>.init( | ||
values: axis, | ||
texts: axis.map { $0.name }) { axis in | ||
self.viewModel.axis = axis | ||
} | ||
self.present(actionSheet, isAnimated: true) | ||
} | ||
|
||
private func presentAlignmentActionSheet(_ alignments: [DividerAlignment]) { | ||
let actionSheet = SparkActionSheet<DividerAlignment>.init( | ||
values: alignments, | ||
texts: alignments.map { $0.name }) { alignment in | ||
self.viewModel.alignment = alignment | ||
} | ||
self.present(actionSheet, isAnimated: true) | ||
} | ||
} |
Oops, something went wrong.