From 7b6a62eae7dbc59f90c8b8fced87dc6d43c4c03a Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 8 Sep 2022 15:30:35 -0500 Subject: [PATCH] removed errorable from radiobox Signed-off-by: Matt Bruce --- VDS/Components/RadioBox/RadioBox.swift | 64 +------- VDS/Components/RadioBox/RadioBoxGroup.swift | 143 +++++++++++++++--- VDS/Components/RadioBox/RadioBoxModel.swift | 22 +-- .../SelectorGroupModelHandlerable.swift | 10 +- 4 files changed, 131 insertions(+), 108 deletions(-) diff --git a/VDS/Components/RadioBox/RadioBox.swift b/VDS/Components/RadioBox/RadioBox.swift index 74beb155..16074162 100644 --- a/VDS/Components/RadioBox/RadioBox.swift +++ b/VDS/Components/RadioBox/RadioBox.swift @@ -31,6 +31,7 @@ open class RadioBoxBase: Control, Changable $0.translatesAutoresizingMaskIntoConstraints = false $0.alignment = .top $0.axis = .vertical + $0.spacing = 0 } }() @@ -54,8 +55,6 @@ open class RadioBoxBase: Control, Changable private var subTextLabel = Label() private var subTextRightLabel = Label() - - private var errorLabel = Label() //-------------------------------------------------- // MARK: - Public Properties @@ -87,12 +86,6 @@ open class RadioBoxBase: Control, Changable @Proxy(\.model.subTextRight) open var subTextRight: String? - @Proxy(\.model.hasError) - open var hasError: Bool - - @Proxy(\.model.errorText) - open var errorText: String? - @Proxy(\.model.strikethrough) open var strikethrough: Bool @@ -148,9 +141,7 @@ open class RadioBoxBase: Control, Changable selectorView.addSubview(mainStackView) - //2 vertical rows mainStackView.addArrangedSubview(selectorStackView) - mainStackView.addArrangedSubview(errorLabel) selectorStackView.addArrangedSubview(selectorLeftLabelStackView) selectorStackView.addArrangedSubview(subTextRightLabel) @@ -196,17 +187,6 @@ open class RadioBoxBase: Control, Changable } else { subTextRightLabel.isHidden = true } - - //either add/remove the error from the main stack - if let errorModel = model.errorModel, model.shouldShowError { - errorLabel.set(with: errorModel) - mainStackView.spacing = 8 - errorLabel.isHidden = false - } else { - mainStackView.spacing = 0 - errorLabel.isHidden = true - } - } public override func reset() { @@ -219,9 +199,6 @@ open class RadioBoxBase: Control, Changable /// This will radioBox the state of the Selector and execute the actionBlock if provided. open func toggle() { //removed error - if hasError && isSelected == false { - hasError.toggle() - } isSelected.toggle() sendActions(for: .valueChanged) onChange?() @@ -237,7 +214,6 @@ open class RadioBoxBase: Control, Changable || viewModel.text != model.text || viewModel.subText != model.subText || viewModel.subTextRight != model.subTextRight - || viewModel.hasError != model.hasError || viewModel.surface != model.surface || viewModel.disabled != model.disabled return update @@ -264,8 +240,8 @@ open class RadioBoxBase: Control, Changable private var selectorBorderWidthSelected: CGFloat = 2.0 private var selectorBorderWidth: CGFloat = 1.0 - private var radioBoxBackgroundColorConfiguration: RadioBoxErrorColorConfiguration = { - return RadioBoxErrorColorConfiguration().with { + private var radioBoxBackgroundColorConfiguration: BinaryDisabledSurfaceColorConfiguration = { + return BinaryDisabledSurfaceColorConfiguration().with { $0.forFalse.enabled.lightColor = VDSFormControlsColor.backgroundOnlight $0.forFalse.enabled.darkColor = VDSFormControlsColor.backgroundOndark $0.forFalse.disabled.lightColor = VDSFormControlsColor.backgroundOnlight @@ -275,30 +251,20 @@ open class RadioBoxBase: Control, Changable $0.forTrue.enabled.darkColor = VDSFormControlsColor.backgroundOndark $0.forTrue.disabled.lightColor = VDSFormControlsColor.backgroundOnlight $0.forTrue.disabled.darkColor = VDSFormControlsColor.backgroundOndark - - //error doesn't care enabled/disable - $0.error.forTrue.lightColor = VDSColor.elementsPrimaryOnlight - $0.error.forTrue.darkColor = VDSColor.elementsPrimaryOndark - $0.error.forFalse.lightColor = VDSColor.feedbackErrorBackgroundOnlight - $0.error.forFalse.darkColor = VDSColor.feedbackErrorBackgroundOndark } }() - private var radioBoxBorderColorConfiguration: RadioBoxErrorColorConfiguration = { - return RadioBoxErrorColorConfiguration().with { + private var radioBoxBorderColorConfiguration: BinaryDisabledSurfaceColorConfiguration = { + return BinaryDisabledSurfaceColorConfiguration().with { $0.forTrue.enabled.lightColor = VDSColor.elementsPrimaryOnlight $0.forTrue.enabled.darkColor = VDSColor.elementsPrimaryOndark $0.forFalse.enabled.lightColor = VDSFormControlsColor.borderOnlight $0.forFalse.enabled.darkColor = VDSFormControlsColor.borderOndark + $0.forTrue.disabled.lightColor = VDSColor.interactiveDisabledOnlight $0.forTrue.disabled.darkColor = VDSColor.interactiveDisabledOndark $0.forFalse.disabled.lightColor = VDSColor.interactiveDisabledOnlight $0.forFalse.disabled.darkColor = VDSColor.interactiveDisabledOndark - //error doesn't care enabled/disable - $0.error.forTrue.lightColor = VDSColor.elementsPrimaryOnlight - $0.error.forTrue.darkColor = VDSColor.elementsPrimaryOndark - $0.error.forFalse.lightColor = VDSColor.feedbackErrorOnlight - $0.error.forFalse.darkColor = VDSColor.feedbackErrorOndark } }() @@ -358,23 +324,5 @@ open class RadioBoxBase: Control, Changable layer.addSublayer(border) } } - - //-------------------------------------------------- - // MARK: - Color Class Configurations - //-------------------------------------------------- - private class RadioBoxErrorColorConfiguration: BinaryDisabledSurfaceColorConfiguration { - public let error = BinarySurfaceColorConfiguration() - override func getColor(_ viewModel: ModelType) -> UIColor { - //only show error is enabled and showError == true - let showErrorColor = !viewModel.disabled && viewModel.hasError - - if showErrorColor { - return error.getColor(viewModel) - } else { - return super.getColor(viewModel) - } - } - } - } diff --git a/VDS/Components/RadioBox/RadioBoxGroup.swift b/VDS/Components/RadioBox/RadioBoxGroup.swift index e8dabe18..98516b02 100644 --- a/VDS/Components/RadioBox/RadioBoxGroup.swift +++ b/VDS/Components/RadioBox/RadioBoxGroup.swift @@ -30,10 +30,7 @@ public class RadioBoxGroup: Control, SelectorGroupSel } } - - if hasError { - hasError = false - } + sendActions(for: .valueChanged) } @@ -42,24 +39,7 @@ public class RadioBoxGroup: Control, SelectorGroupSel // MARK: - Public Properties //-------------------------------------------------- public var selectorViews: [ModelHandlerType] = [] - - public var hasError: Bool { - get { model.hasError } - set { - var newHasError = newValue - if selectedModel != nil, newHasError { - newHasError = false - } - let selectors = model.selectors.compactMap { existing in - return existing.copyWith { - $0.hasError = newValue - } - } - model.hasError = newValue - model.selectors = selectors - } - } - + public var onChange: Blocks.ActionBlock? //-------------------------------------------------- @@ -148,3 +128,122 @@ public class RadioBoxGroup: Control, SelectorGroupSel } } } + +public class RadioBoxGroupBase: Control, SelectorGroupSelectedModelHandlerable, Changable where GroupModelType.SelectorModelType == ModelHandlerType.ModelType { + + public func didSelect(_ selectedControl: ModelHandlerType) { + //only changes local model in control, + //this is now disconnected from the parent model + for (index, control) in selectorViews.enumerated() { + //only change the old and new + if control == selectedControl { + let updated = model.selectors[index].copyWith { + $0.selected = true + } + model.selectors[index] = updated + + } else if control.isSelected { + let updated = model.selectors[index].copyWith { + $0.selected = false + } + model.selectors[index] = updated + + } + } + + sendActions(for: .valueChanged) + + } + + //-------------------------------------------------- + // MARK: - Public Properties + //-------------------------------------------------- + public var selectorViews: [ModelHandlerType] = [] + + public var onChange: Blocks.ActionBlock? + + //-------------------------------------------------- + // MARK: - Private Properties + //-------------------------------------------------- + private var mainStackView: UIStackView = { + return UIStackView().with { + $0.translatesAutoresizingMaskIntoConstraints = false + $0.spacing = 12 + } + }() + + //-------------------------------------------------- + // MARK: - Overrides + //-------------------------------------------------- + override public var disabled: Bool { + didSet { + updateSelectors() + } + } + + override public var surface: Surface { + didSet { + updateSelectors() + } + } + + private func ensureDevice() { + if UIDevice.isIPad { + mainStackView.axis = .horizontal + mainStackView.distribution = .fillEqually + } else { + if UIDevice.current.orientation.isPortrait || UIDevice.current.orientation == .unknown { + mainStackView.axis = .vertical + mainStackView.distribution = .fillProportionally + + } else { + mainStackView.axis = .horizontal + mainStackView.distribution = .fillEqually + } + } + } + + open override func setup() { + super.setup() + isAccessibilityElement = true + accessibilityTraits = .button + addSubview(mainStackView) + ensureDevice() + mainStackView.topAnchor.constraint(equalTo: topAnchor).isActive = true + mainStackView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true + mainStackView.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true + mainStackView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true + + NotificationCenter.default + .publisher(for: UIDevice.orientationDidChangeNotification) + .sink() { [weak self] _ in + UIView.animate(withDuration: 1.0) { + self?.ensureDevice() + } + }.store(in: &subscribers) + } + + open override func shouldUpdateView(viewModel: ModelType) -> Bool { + let update = viewModel.selectedModel?.inputId != model.selectedModel?.inputId + || viewModel.selectors.count != model.selectors.count + || viewModel.surface != model.surface + || viewModel.disabled != model.disabled + return update + } + + open override func updateView(viewModel: ModelType) { + for selectorModel in viewModel.selectors { + //see if view is there for the model + if let foundSelectorView = findSelectorView(inputId: selectorModel.inputId) { + foundSelectorView.set(with: selectorModel) + } else { + + //create view + let newSelectorView = createModelHandler(selector: selectorModel) + + self.selectorViews.append(newSelectorView) + mainStackView.addArrangedSubview(newSelectorView) + } + } + } +} diff --git a/VDS/Components/RadioBox/RadioBoxModel.swift b/VDS/Components/RadioBox/RadioBoxModel.swift index d09cace9..8ec3b98e 100644 --- a/VDS/Components/RadioBox/RadioBoxModel.swift +++ b/VDS/Components/RadioBox/RadioBoxModel.swift @@ -8,7 +8,7 @@ import Foundation import UIKit -public protocol RadioBoxModel: Modelable, FormFieldable, Errorable, DataTrackable, Accessable, Selectable, BinaryColorable { +public protocol RadioBoxModel: Modelable, FormFieldable, DataTrackable, Accessable, Selectable, BinaryColorable { var text: String { get set } var textAttributes: [LabelAttributeModel]? { get set } var subText: String? { get set } @@ -20,11 +20,6 @@ public protocol RadioBoxModel: Modelable, FormFieldable, Errorable, DataTrackabl extension RadioBoxModel { - public var shouldShowError: Bool { - guard hasError && !disabled && errorText?.isEmpty == false else { return false } - return true - } - public var textModel: DefaultLabelModel { var model = DefaultLabelModel() model.textPosition = .left @@ -59,17 +54,7 @@ extension RadioBoxModel { model.attributes = subTextRightAttributes return model } - - public var errorModel: DefaultLabelModel? { - guard let errorText, hasError else { return nil } - var model = DefaultLabelModel() - model.textPosition = .left - model.typograpicalStyle = .BodyMedium - model.text = errorText - model.surface = surface - model.disabled = disabled - return model - } + } public struct DefaultRadioBoxModel: RadioBoxModel { @@ -85,9 +70,6 @@ public struct DefaultRadioBoxModel: RadioBoxModel { public var selectedAccentColor: UIColor? public var strikethrough: Bool = false - public var hasError: Bool = false - public var errorText: String? - public var inputId: String? public var value: AnyHashable? diff --git a/VDS/Protocols/SelectorGroupModelHandlerable.swift b/VDS/Protocols/SelectorGroupModelHandlerable.swift index a7f5a583..d9aa96d7 100644 --- a/VDS/Protocols/SelectorGroupModelHandlerable.swift +++ b/VDS/Protocols/SelectorGroupModelHandlerable.swift @@ -69,20 +69,14 @@ extension SelectorGroupModelHandlerable { } ///MARK: Groups that allow single selections -public protocol SelectorGroupSelectedModelHandlerable: SelectorGroupModelHandlerable { +public protocol SelectorGroupSelectedModelHandlerable: SelectorGroupModelHandlerable where ModelType: SelectorGroupSelectedModelable { func didSelect(_ selectedControl: ModelHandlerType) } extension SelectorGroupSelectedModelHandlerable { public var selectedModel: ModelHandlerType.ModelType? { - if let index = model.selectors.firstIndex(where: { element in - return element.selected == true - }) { - return model.selectors[index] - } else { - return nil - } + return model.selectedModel } public func createModelHandler(selector: ModelHandlerType.ModelType) -> ModelHandlerType {