Merge branch 'feature/Notification' into 'develop'
Adding Notification component See merge request BPHV_MIPS/vds_ios!53
This commit is contained in:
commit
2902a85c0c
@ -8,8 +8,6 @@
|
|||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
445BA07829C07B3D0036A7C5 /* Notification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 445BA07729C07B3D0036A7C5 /* Notification.swift */; };
|
445BA07829C07B3D0036A7C5 /* Notification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 445BA07729C07B3D0036A7C5 /* Notification.swift */; };
|
||||||
44604AD029CE17EC00E62B51 /* NotificationTitleModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44604ACF29CE17EC00E62B51 /* NotificationTitleModel.swift */; };
|
|
||||||
44604AD229CE180F00E62B51 /* NotificationSubTitleModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44604AD129CE180F00E62B51 /* NotificationSubTitleModel.swift */; };
|
|
||||||
44604AD429CE186A00E62B51 /* NotificationButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44604AD329CE186A00E62B51 /* NotificationButtonModel.swift */; };
|
44604AD429CE186A00E62B51 /* NotificationButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44604AD329CE186A00E62B51 /* NotificationButtonModel.swift */; };
|
||||||
44604AD729CE196600E62B51 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44604AD629CE196600E62B51 /* Line.swift */; };
|
44604AD729CE196600E62B51 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = 44604AD629CE196600E62B51 /* Line.swift */; };
|
||||||
5F21D7BF28DCEB3D003E7CD6 /* Useable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F21D7BE28DCEB3D003E7CD6 /* Useable.swift */; };
|
5F21D7BF28DCEB3D003E7CD6 /* Useable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5F21D7BE28DCEB3D003E7CD6 /* Useable.swift */; };
|
||||||
@ -94,6 +92,7 @@
|
|||||||
EAC9258F2911C9DE00091998 /* EntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAC9258B2911C9DE00091998 /* EntryField.swift */; };
|
EAC9258F2911C9DE00091998 /* EntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAC9258B2911C9DE00091998 /* EntryField.swift */; };
|
||||||
EAD8D2C128BFDE8B006EB6A6 /* UIGestureRecognizer+Publisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAD8D2C028BFDE8B006EB6A6 /* UIGestureRecognizer+Publisher.swift */; };
|
EAD8D2C128BFDE8B006EB6A6 /* UIGestureRecognizer+Publisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAD8D2C028BFDE8B006EB6A6 /* UIGestureRecognizer+Publisher.swift */; };
|
||||||
EAF1FE9929D4850E00101452 /* Clickable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF1FE9829D4850E00101452 /* Clickable.swift */; };
|
EAF1FE9929D4850E00101452 /* Clickable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF1FE9829D4850E00101452 /* Clickable.swift */; };
|
||||||
|
EAF1FE9B29DB1A6000101452 /* Changeable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF1FE9A29DB1A6000101452 /* Changeable.swift */; };
|
||||||
EAF7F0952899861000B287F5 /* Checkbox.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0932899861000B287F5 /* Checkbox.swift */; };
|
EAF7F0952899861000B287F5 /* Checkbox.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0932899861000B287F5 /* Checkbox.swift */; };
|
||||||
EAF7F09A2899B17200B287F5 /* CATransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0992899B17200B287F5 /* CATransaction.swift */; };
|
EAF7F09A2899B17200B287F5 /* CATransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F0992899B17200B287F5 /* CATransaction.swift */; };
|
||||||
EAF7F09E289AAEC000B287F5 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F09D289AAEC000B287F5 /* Constants.swift */; };
|
EAF7F09E289AAEC000B287F5 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAF7F09D289AAEC000B287F5 /* Constants.swift */; };
|
||||||
@ -125,8 +124,6 @@
|
|||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
445BA07729C07B3D0036A7C5 /* Notification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notification.swift; sourceTree = "<group>"; };
|
445BA07729C07B3D0036A7C5 /* Notification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notification.swift; sourceTree = "<group>"; };
|
||||||
44604ACF29CE17EC00E62B51 /* NotificationTitleModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationTitleModel.swift; sourceTree = "<group>"; };
|
|
||||||
44604AD129CE180F00E62B51 /* NotificationSubTitleModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSubTitleModel.swift; sourceTree = "<group>"; };
|
|
||||||
44604AD329CE186A00E62B51 /* NotificationButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationButtonModel.swift; sourceTree = "<group>"; };
|
44604AD329CE186A00E62B51 /* NotificationButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationButtonModel.swift; sourceTree = "<group>"; };
|
||||||
44604AD629CE196600E62B51 /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = "<group>"; };
|
44604AD629CE196600E62B51 /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = "<group>"; };
|
||||||
5F21D7BE28DCEB3D003E7CD6 /* Useable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Useable.swift; sourceTree = "<group>"; };
|
5F21D7BE28DCEB3D003E7CD6 /* Useable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Useable.swift; sourceTree = "<group>"; };
|
||||||
@ -212,6 +209,7 @@
|
|||||||
EAC9258B2911C9DE00091998 /* EntryField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EntryField.swift; sourceTree = "<group>"; };
|
EAC9258B2911C9DE00091998 /* EntryField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EntryField.swift; sourceTree = "<group>"; };
|
||||||
EAD8D2C028BFDE8B006EB6A6 /* UIGestureRecognizer+Publisher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIGestureRecognizer+Publisher.swift"; sourceTree = "<group>"; };
|
EAD8D2C028BFDE8B006EB6A6 /* UIGestureRecognizer+Publisher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIGestureRecognizer+Publisher.swift"; sourceTree = "<group>"; };
|
||||||
EAF1FE9829D4850E00101452 /* Clickable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Clickable.swift; sourceTree = "<group>"; };
|
EAF1FE9829D4850E00101452 /* Clickable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Clickable.swift; sourceTree = "<group>"; };
|
||||||
|
EAF1FE9A29DB1A6000101452 /* Changeable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Changeable.swift; sourceTree = "<group>"; };
|
||||||
EAF7F0932899861000B287F5 /* Checkbox.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Checkbox.swift; sourceTree = "<group>"; };
|
EAF7F0932899861000B287F5 /* Checkbox.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Checkbox.swift; sourceTree = "<group>"; };
|
||||||
EAF7F0992899B17200B287F5 /* CATransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CATransaction.swift; sourceTree = "<group>"; };
|
EAF7F0992899B17200B287F5 /* CATransaction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CATransaction.swift; sourceTree = "<group>"; };
|
||||||
EAF7F09D289AAEC000B287F5 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
|
EAF7F09D289AAEC000B287F5 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
|
||||||
@ -257,8 +255,6 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
445BA07729C07B3D0036A7C5 /* Notification.swift */,
|
445BA07729C07B3D0036A7C5 /* Notification.swift */,
|
||||||
44604ACF29CE17EC00E62B51 /* NotificationTitleModel.swift */,
|
|
||||||
44604AD129CE180F00E62B51 /* NotificationSubTitleModel.swift */,
|
|
||||||
44604AD329CE186A00E62B51 /* NotificationButtonModel.swift */,
|
44604AD329CE186A00E62B51 /* NotificationButtonModel.swift */,
|
||||||
);
|
);
|
||||||
path = Notification;
|
path = Notification;
|
||||||
@ -418,6 +414,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
EA4DB2FC28D3D0CA00103EE3 /* AnyEquatable.swift */,
|
EA4DB2FC28D3D0CA00103EE3 /* AnyEquatable.swift */,
|
||||||
|
EAF1FE9A29DB1A6000101452 /* Changeable.swift */,
|
||||||
EAF1FE9829D4850E00101452 /* Clickable.swift */,
|
EAF1FE9829D4850E00101452 /* Clickable.swift */,
|
||||||
EAA5EEDF28F49DB3003B3210 /* Colorable.swift */,
|
EAA5EEDF28F49DB3003B3210 /* Colorable.swift */,
|
||||||
EA3361A9288B25E40071C351 /* Disabling.swift */,
|
EA3361A9288B25E40071C351 /* Disabling.swift */,
|
||||||
@ -792,7 +789,6 @@
|
|||||||
EA33622E2891EA3C0071C351 /* DispatchQueue+Once.swift in Sources */,
|
EA33622E2891EA3C0071C351 /* DispatchQueue+Once.swift in Sources */,
|
||||||
EA4DB2FD28D3D0CA00103EE3 /* AnyEquatable.swift in Sources */,
|
EA4DB2FD28D3D0CA00103EE3 /* AnyEquatable.swift in Sources */,
|
||||||
EAA5EEB728ECC03A003B3210 /* ToolTipLabelAttribute.swift in Sources */,
|
EAA5EEB728ECC03A003B3210 /* ToolTipLabelAttribute.swift in Sources */,
|
||||||
44604AD029CE17EC00E62B51 /* NotificationTitleModel.swift in Sources */,
|
|
||||||
EA5E305A29510F8B0082B959 /* EnumSubset.swift in Sources */,
|
EA5E305A29510F8B0082B959 /* EnumSubset.swift in Sources */,
|
||||||
EA985BF7296C665E00F2FF2E /* IconName.swift in Sources */,
|
EA985BF7296C665E00F2FF2E /* IconName.swift in Sources */,
|
||||||
EAF7F0AF289B144C00B287F5 /* UnderlineLabelAttribute.swift in Sources */,
|
EAF7F0AF289B144C00B287F5 /* UnderlineLabelAttribute.swift in Sources */,
|
||||||
@ -825,10 +821,10 @@
|
|||||||
EA3361BD288B2C760071C351 /* TypeAlias.swift in Sources */,
|
EA3361BD288B2C760071C351 /* TypeAlias.swift in Sources */,
|
||||||
EAB1D2CF28ABEF2B00DAE764 /* Typography.swift in Sources */,
|
EAB1D2CF28ABEF2B00DAE764 /* Typography.swift in Sources */,
|
||||||
EAF7F09A2899B17200B287F5 /* CATransaction.swift in Sources */,
|
EAF7F09A2899B17200B287F5 /* CATransaction.swift in Sources */,
|
||||||
|
EAF1FE9B29DB1A6000101452 /* Changeable.swift in Sources */,
|
||||||
EAF7F0A2289AFB3900B287F5 /* Errorable.swift in Sources */,
|
EAF7F0A2289AFB3900B287F5 /* Errorable.swift in Sources */,
|
||||||
EA985C7D297DAED300F2FF2E /* Primitive.swift in Sources */,
|
EA985C7D297DAED300F2FF2E /* Primitive.swift in Sources */,
|
||||||
EAF1FE9929D4850E00101452 /* Clickable.swift in Sources */,
|
EAF1FE9929D4850E00101452 /* Clickable.swift in Sources */,
|
||||||
44604AD229CE180F00E62B51 /* NotificationSubTitleModel.swift in Sources */,
|
|
||||||
EAB5FEF829393A7200998C17 /* ButtonGroupConstants.swift in Sources */,
|
EAB5FEF829393A7200998C17 /* ButtonGroupConstants.swift in Sources */,
|
||||||
EA3361AF288B26310071C351 /* FormFieldable.swift in Sources */,
|
EA3361AF288B26310071C351 /* FormFieldable.swift in Sources */,
|
||||||
44604AD729CE196600E62B51 /* Line.swift in Sources */,
|
44604AD729CE196600E62B51 /* Line.swift in Sources */,
|
||||||
|
|||||||
@ -7,14 +7,23 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import UIKit
|
import UIKit
|
||||||
|
import Combine
|
||||||
|
|
||||||
public class SelectorGroupHandlerBase<HandlerType: Control>: Control {
|
public class SelectorGroupHandlerBase<HandlerType: Control>: Control, Changeable {
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Public Properties
|
// MARK: - Public Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
public var selectorViews: [HandlerType] = []
|
public var selectorViews: [HandlerType] = []
|
||||||
|
|
||||||
|
public var onChangeSubscriber: AnyCancellable? {
|
||||||
|
willSet {
|
||||||
|
if let onChangeSubscriber {
|
||||||
|
onChangeSubscriber.cancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Overrides
|
// MARK: - Overrides
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|||||||
@ -121,7 +121,7 @@ open class ButtonBase: UIButton, Buttonable, Handlerable, ViewProtocol, Resettab
|
|||||||
translatesAutoresizingMaskIntoConstraints = false
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
accessibilityCustomActions = []
|
accessibilityCustomActions = []
|
||||||
setup()
|
setup()
|
||||||
setupDidChangeEvent()
|
setupDidChangeEvent(true)
|
||||||
updateView()
|
updateView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,13 +7,13 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import UIKit
|
import UIKit
|
||||||
|
import Combine
|
||||||
import VDSColorTokens
|
import VDSColorTokens
|
||||||
import VDSFormControlsTokens
|
import VDSFormControlsTokens
|
||||||
import Combine
|
|
||||||
|
|
||||||
/// Checkboxes are a multi-select component through which a customer indicates a choice. If a binary choice, the component is a checkbox. If the choice has multiple options, the component is a ``CheckboxGroup``.
|
/// Checkboxes are a multi-select component through which a customer indicates a choice. If a binary choice, the component is a checkbox. If the choice has multiple options, the component is a ``CheckboxGroup``.
|
||||||
@objc(VDSCheckboxBase)
|
@objc(VDSCheckboxBase)
|
||||||
open class Checkbox: Control, Errorable {
|
open class Checkbox: Control, Errorable, Changeable {
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializers
|
// MARK: - Initializers
|
||||||
@ -63,6 +63,14 @@ open class Checkbox: Control, Errorable {
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Public Properties
|
// MARK: - Public Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
public var onChangeSubscriber: AnyCancellable? {
|
||||||
|
willSet {
|
||||||
|
if let onChangeSubscriber {
|
||||||
|
onChangeSubscriber.cancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
open var label = Label().with {
|
open var label = Label().with {
|
||||||
$0.setContentCompressionResistancePriority(.required, for: .vertical)
|
$0.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||||
$0.textPosition = .left
|
$0.textPosition = .left
|
||||||
|
|||||||
@ -94,7 +94,7 @@ public class Label: UILabel, Handlerable, ViewProtocol, Resettable, UserInfoable
|
|||||||
accessibilityCustomActions = []
|
accessibilityCustomActions = []
|
||||||
accessibilityTraits = .staticText
|
accessibilityTraits = .staticText
|
||||||
setup()
|
setup()
|
||||||
setupDidChangeEvent()
|
setupDidChangeEvent(true)
|
||||||
updateView()
|
updateView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,7 +18,7 @@ public class Notification: View {
|
|||||||
// MARK: - Enums
|
// MARK: - Enums
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
public enum NotificationStyle: String, CaseIterable {
|
public enum Style: String, CaseIterable {
|
||||||
case info, success, warning, error
|
case info, success, warning, error
|
||||||
|
|
||||||
func styleIconName() -> Icon.Name {
|
func styleIconName() -> Icon.Name {
|
||||||
@ -35,6 +35,10 @@ public class Notification: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum Layout: String, CaseIterable {
|
||||||
|
case vertical, horizontal
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Private Properties
|
// MARK: - Private Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -52,6 +56,14 @@ public class Notification: View {
|
|||||||
$0.axis = .vertical
|
$0.axis = .vertical
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var labelButtonView = UIStackView().with {
|
||||||
|
$0.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
$0.alignment = .top
|
||||||
|
$0.distribution = .fillEqually
|
||||||
|
$0.axis = .vertical
|
||||||
|
$0.spacing = VDSLayout.Spacing.space2X.value
|
||||||
|
}
|
||||||
|
|
||||||
private var edgeSpacing: CGFloat {
|
private var edgeSpacing: CGFloat {
|
||||||
return UIDevice.isIPad ? VDSLayout.Spacing.space5X.value : VDSLayout.Spacing.space4X.value
|
return UIDevice.isIPad ? VDSLayout.Spacing.space5X.value : VDSLayout.Spacing.space4X.value
|
||||||
}
|
}
|
||||||
@ -64,24 +76,40 @@ public class Notification: View {
|
|||||||
return UIDevice.isIPad ? VDSLayout.Spacing.space5X.value : VDSLayout.Spacing.space4X.value
|
return UIDevice.isIPad ? VDSLayout.Spacing.space5X.value : VDSLayout.Spacing.space4X.value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var minViewWidth: CGFloat {
|
||||||
|
return fullBleed ? 320 : 288
|
||||||
|
}
|
||||||
|
|
||||||
|
///Max view width is for Tablet
|
||||||
|
private var maxViewWidth: CGFloat {
|
||||||
|
return fullBleed ? 1272 : 1232
|
||||||
|
}
|
||||||
|
|
||||||
|
private var maxWidthConstraint: NSLayoutConstraint?
|
||||||
|
|
||||||
|
open var leadingConstraint: NSLayoutConstraint?
|
||||||
|
|
||||||
|
open var trailingConstraint: NSLayoutConstraint?
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - View Properties
|
// MARK: - View Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
open var typeIcon = Icon().with {
|
open var typeIcon = Icon().with {
|
||||||
$0.name = .infoBold
|
$0.name = .infoBold
|
||||||
|
$0.size = UIDevice.isIPad ? .medium : .small
|
||||||
}
|
}
|
||||||
|
|
||||||
open var closeButton = Icon().with {
|
open var closeButton = Icon().with {
|
||||||
$0.name = .close
|
$0.name = .close
|
||||||
|
$0.size = UIDevice.isIPad ? .medium : .small
|
||||||
}
|
}
|
||||||
|
|
||||||
open var titleLabel = Label().with {
|
open var titleLabel = Label().with {
|
||||||
$0.textStyle = .boldBodyLarge
|
$0.textStyle = UIDevice.isIPad ? .boldBodyLarge : .boldBodySmall
|
||||||
}
|
}
|
||||||
|
|
||||||
open var subTitleLabel = Label().with {
|
open var subTitleLabel = Label().with {
|
||||||
$0.textStyle = .bodyLarge
|
$0.textStyle = UIDevice.isIPad ? .bodyLarge : .bodySmall
|
||||||
}
|
}
|
||||||
|
|
||||||
open var buttonsView = ButtonGroup().with {
|
open var buttonsView = ButtonGroup().with {
|
||||||
@ -89,11 +117,10 @@ public class Notification: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Text
|
//Text
|
||||||
open var titleText: String = "" { didSet{didChange()}}
|
open var title: String = "" { didSet{didChange()}}
|
||||||
|
|
||||||
open var subTitleText: String? { didSet{didChange()}}
|
open var subTitle: String? { didSet{didChange()}}
|
||||||
|
|
||||||
#warning("will need to think about this one, probably create a model that has 2 props - text, onClick = (Button) -> () so we are not accessing the button directly. The only reason why I leave it open is for things like accessibility, but not for setting properties outside of this class. More or less follow how Tilelet is working, look at that, below is a temp fix until we can discuss with the guys")
|
|
||||||
//Buttons
|
//Buttons
|
||||||
open var primaryButtonModel: ButtonModel? { didSet{didChange()}}
|
open var primaryButtonModel: ButtonModel? { didSet{didChange()}}
|
||||||
open var primaryButton = Button().with {
|
open var primaryButton = Button().with {
|
||||||
@ -122,16 +149,31 @@ public class Notification: View {
|
|||||||
}
|
}
|
||||||
internal var onCloseSubscriber: AnyCancellable?
|
internal var onCloseSubscriber: AnyCancellable?
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Modal Properties
|
// MARK: - Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
|
||||||
open var type: NotificationStyle = .info { didSet{didChange()}}
|
open var hideCloseButton: Bool = false { didSet{didChange()}}
|
||||||
|
|
||||||
|
open var type: Style = .info { didSet{didChange()}}
|
||||||
|
|
||||||
|
open var fullBleed: Bool = false { didSet {didChange()}}
|
||||||
|
|
||||||
|
var _layout: Layout = .vertical
|
||||||
|
open var layout: Layout {
|
||||||
|
set {
|
||||||
|
if !UIDevice.isIPad, newValue == .horizontal { return }
|
||||||
|
_layout = newValue
|
||||||
|
buttonsView.buttonPosition = _layout == .horizontal ? .center : .left
|
||||||
|
didChange()
|
||||||
|
}
|
||||||
|
get { _layout }
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Configuration
|
// MARK: - Configuration
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
private var backgroundColorConfiguration: AnyColorable = {
|
private var backgroundColorConfiguration: AnyColorable = {
|
||||||
let config = KeyedColorConfiguration<Notification, NotificationStyle>(keyPath: \.type)
|
let config = KeyedColorConfiguration<Notification, Style>(keyPath: \.type)
|
||||||
config.setSurfaceColors(VDSColor.feedbackInformationBackgroundOnlight, VDSColor.feedbackInformationBackgroundOndark, forKey: .info)
|
config.setSurfaceColors(VDSColor.feedbackInformationBackgroundOnlight, VDSColor.feedbackInformationBackgroundOndark, forKey: .info)
|
||||||
config.setSurfaceColors(VDSColor.feedbackWarningBackgroundOnlight, VDSColor.feedbackWarningBackgroundOndark, forKey: .warning)
|
config.setSurfaceColors(VDSColor.feedbackWarningBackgroundOnlight, VDSColor.feedbackWarningBackgroundOndark, forKey: .warning)
|
||||||
config.setSurfaceColors(VDSColor.feedbackSuccessBackgroundOnlight, VDSColor.feedbackSuccessBackgroundOndark, forKey: .success)
|
config.setSurfaceColors(VDSColor.feedbackSuccessBackgroundOnlight, VDSColor.feedbackSuccessBackgroundOndark, forKey: .success)
|
||||||
@ -170,11 +212,15 @@ public class Notification: View {
|
|||||||
|
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
heightAnchor.constraint(greaterThanOrEqualToConstant: minViewHeight),
|
heightAnchor.constraint(greaterThanOrEqualToConstant: minViewHeight),
|
||||||
mainStackView.heightAnchor.constraint(greaterThanOrEqualToConstant: minContentHeight)
|
mainStackView.heightAnchor.constraint(greaterThanOrEqualToConstant: minContentHeight),
|
||||||
|
widthAnchor.constraint(greaterThanOrEqualToConstant: minViewWidth)
|
||||||
])
|
])
|
||||||
|
maxWidthConstraint = widthAnchor.constraint(lessThanOrEqualToConstant: maxViewWidth)
|
||||||
|
|
||||||
|
labelButtonView.addArrangedSubview(labelsView)
|
||||||
|
|
||||||
mainStackView.addArrangedSubview(typeIcon)
|
mainStackView.addArrangedSubview(typeIcon)
|
||||||
mainStackView.addArrangedSubview(labelsView)
|
mainStackView.addArrangedSubview(labelButtonView)
|
||||||
mainStackView.addArrangedSubview(closeButton)
|
mainStackView.addArrangedSubview(closeButton)
|
||||||
|
|
||||||
//labels
|
//labels
|
||||||
@ -186,14 +232,29 @@ public class Notification: View {
|
|||||||
super.reset()
|
super.reset()
|
||||||
|
|
||||||
titleLabel.reset()
|
titleLabel.reset()
|
||||||
|
titleLabel.text = ""
|
||||||
|
titleLabel.textStyle = UIDevice.isIPad ? .boldBodyLarge : .boldBodySmall
|
||||||
|
|
||||||
subTitleLabel.reset()
|
subTitleLabel.reset()
|
||||||
|
subTitleLabel.textStyle = UIDevice.isIPad ? .bodyLarge : .bodySmall
|
||||||
|
|
||||||
buttonsView.reset()
|
buttonsView.reset()
|
||||||
primaryButton.reset()
|
buttonsView.buttonPosition = .left
|
||||||
secondaryButton.reset()
|
|
||||||
|
primaryButtonModel = nil
|
||||||
|
secondaryButtonModel = nil
|
||||||
|
|
||||||
type = .info
|
type = .info
|
||||||
|
typeIcon.size = UIDevice.isIPad ? .medium : .small
|
||||||
typeIcon.name = .infoBold
|
typeIcon.name = .infoBold
|
||||||
|
|
||||||
|
onCloseClick = nil
|
||||||
|
closeButton.size = UIDevice.isIPad ? .medium : .small
|
||||||
closeButton.name = .close
|
closeButton.name = .close
|
||||||
|
|
||||||
|
layout = .vertical
|
||||||
|
hideCloseButton = false
|
||||||
|
fullBleed = false
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -204,6 +265,7 @@ public class Notification: View {
|
|||||||
updateIcons()
|
updateIcons()
|
||||||
updateLabels()
|
updateLabels()
|
||||||
updateButtons()
|
updateButtons()
|
||||||
|
setConstraints()
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateIcons() {
|
private func updateIcons() {
|
||||||
@ -211,21 +273,22 @@ public class Notification: View {
|
|||||||
typeIcon.name = type.styleIconName()
|
typeIcon.name = type.styleIconName()
|
||||||
typeIcon.color = iconColor
|
typeIcon.color = iconColor
|
||||||
closeButton.color = iconColor
|
closeButton.color = iconColor
|
||||||
|
closeButton.isHidden = hideCloseButton
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateLabels() {
|
private func updateLabels() {
|
||||||
titleLabel.surface = surface
|
titleLabel.surface = surface
|
||||||
subTitleLabel.surface = surface
|
subTitleLabel.surface = surface
|
||||||
|
|
||||||
if !titleText.isEmpty {
|
if !title.isEmpty {
|
||||||
titleLabel.text = titleText
|
titleLabel.text = title
|
||||||
labelsView.addArrangedSubview(titleLabel)
|
labelsView.addArrangedSubview(titleLabel)
|
||||||
} else {
|
} else {
|
||||||
titleLabel.removeFromSuperview()
|
titleLabel.removeFromSuperview()
|
||||||
}
|
}
|
||||||
|
|
||||||
if let subTitleText {
|
if let subTitle {
|
||||||
subTitleLabel.text = subTitleText
|
subTitleLabel.text = subTitle
|
||||||
labelsView.addArrangedSubview(subTitleLabel)
|
labelsView.addArrangedSubview(subTitleLabel)
|
||||||
} else {
|
} else {
|
||||||
subTitleLabel.removeFromSuperview()
|
subTitleLabel.removeFromSuperview()
|
||||||
@ -254,14 +317,32 @@ public class Notification: View {
|
|||||||
buttonsView.removeFromSuperview()
|
buttonsView.removeFromSuperview()
|
||||||
} else {
|
} else {
|
||||||
labelsView.setCustomSpacing(VDSLayout.Spacing.space3X.value, after: subTitleLabel)
|
labelsView.setCustomSpacing(VDSLayout.Spacing.space3X.value, after: subTitleLabel)
|
||||||
///This below doesn't work
|
|
||||||
buttonsView.buttons = buttons
|
buttonsView.buttons = buttons
|
||||||
labelsView.addArrangedSubview(buttonsView)
|
labelButtonView.axis = layout == .vertical ? .vertical : .horizontal
|
||||||
|
labelButtonView.addArrangedSubview(buttonsView)
|
||||||
|
|
||||||
buttonsView
|
buttonsView
|
||||||
.pinLeading()
|
.pinLeading()
|
||||||
.pinTrailing()
|
.pinTrailing()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func setConstraints() {
|
||||||
|
|
||||||
|
maxWidthConstraint?.constant = maxViewWidth
|
||||||
|
maxWidthConstraint?.isActive = UIDevice.isIPad
|
||||||
|
|
||||||
|
if leadingConstraint == nil, let superview {
|
||||||
|
leadingConstraint = NSLayoutConstraint(item: self, attribute: .leading, relatedBy: .equal, toItem: superview, attribute: .leading, multiplier: 1, constant: 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
if trailingConstraint == nil, let superview {
|
||||||
|
trailingConstraint = NSLayoutConstraint(item: superview, attribute: .trailing, relatedBy: .equal, toItem: self, attribute: .trailing, multiplier: 1, constant: 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
leadingConstraint?.isActive = fullBleed
|
||||||
|
trailingConstraint?.isActive = fullBleed
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,26 +0,0 @@
|
|||||||
//
|
|
||||||
// NotificationSubTitleModel.swift
|
|
||||||
// VDS
|
|
||||||
//
|
|
||||||
// Created by Nadigadda, Sumanth on 24/03/23.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
extension Notification {
|
|
||||||
public struct SubTitleModel {
|
|
||||||
public var text: String
|
|
||||||
public var textAttributes: [any LabelAttributeModel]?
|
|
||||||
public var textStyle: TextStyle = .bodySmall
|
|
||||||
public var numberOfLines: Int
|
|
||||||
|
|
||||||
public init(text: String,
|
|
||||||
textColor: Use = .primary,
|
|
||||||
textAttributes: [any LabelAttributeModel]? = nil,
|
|
||||||
numberOfLines: Int = 0) {
|
|
||||||
self.text = text
|
|
||||||
self.textAttributes = textAttributes
|
|
||||||
self.numberOfLines = numberOfLines
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
//
|
|
||||||
// NotificationTitleModel.swift
|
|
||||||
// VDS
|
|
||||||
//
|
|
||||||
// Created by Nadigadda, Sumanth on 24/03/23.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
extension Notification {
|
|
||||||
public struct TitleModel {
|
|
||||||
public var text: String
|
|
||||||
public var textAttributes: [any LabelAttributeModel]?
|
|
||||||
public var textStyle: TextStyle = .boldBodySmall
|
|
||||||
public var numberOfLines: Int
|
|
||||||
|
|
||||||
public init(text: String,
|
|
||||||
textAttributes: [any LabelAttributeModel]? = nil,
|
|
||||||
numberOfLines: Int = 0) {
|
|
||||||
self.text = text
|
|
||||||
self.textAttributes = textAttributes
|
|
||||||
self.numberOfLines = numberOfLines
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -7,12 +7,12 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import UIKit
|
import UIKit
|
||||||
|
import Combine
|
||||||
import VDSColorTokens
|
import VDSColorTokens
|
||||||
import VDSFormControlsTokens
|
import VDSFormControlsTokens
|
||||||
import Combine
|
|
||||||
|
|
||||||
@objc(VDSRadioBox)
|
@objc(VDSRadioBox)
|
||||||
open class RadioBox: Control {
|
open class RadioBox: Control, Changeable {
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializers
|
// MARK: - Initializers
|
||||||
@ -56,6 +56,14 @@ open class RadioBox: Control {
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Public Properties
|
// MARK: - Public Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
public var onChangeSubscriber: AnyCancellable? {
|
||||||
|
willSet {
|
||||||
|
if let onChangeSubscriber {
|
||||||
|
onChangeSubscriber.cancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
open var textLabel = Label().with {
|
open var textLabel = Label().with {
|
||||||
$0.setContentCompressionResistancePriority(.required, for: .vertical)
|
$0.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||||
$0.textPosition = .left
|
$0.textPosition = .left
|
||||||
|
|||||||
@ -7,11 +7,12 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import UIKit
|
import UIKit
|
||||||
|
import Combine
|
||||||
import VDSColorTokens
|
import VDSColorTokens
|
||||||
import VDSFormControlsTokens
|
import VDSFormControlsTokens
|
||||||
|
|
||||||
@objc(VDSRadioButton)
|
@objc(VDSRadioButton)
|
||||||
open class RadioButton: Control, Errorable {
|
open class RadioButton: Control, Errorable, Changeable {
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Initializers
|
// MARK: - Initializers
|
||||||
@ -61,6 +62,14 @@ open class RadioButton: Control, Errorable {
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Public Properties
|
// MARK: - Public Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
public var onChangeSubscriber: AnyCancellable? {
|
||||||
|
willSet {
|
||||||
|
if let onChangeSubscriber {
|
||||||
|
onChangeSubscriber.cancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
open var label = Label().with {
|
open var label = Label().with {
|
||||||
$0.setContentCompressionResistancePriority(.required, for: .vertical)
|
$0.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||||
$0.textPosition = .left
|
$0.textPosition = .left
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import VDSFormControlsTokens
|
|||||||
import Combine
|
import Combine
|
||||||
|
|
||||||
@objc(VDSEntryField)
|
@objc(VDSEntryField)
|
||||||
open class EntryField: Control {
|
open class EntryField: Control, Changeable {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Enums
|
// MARK: - Enums
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -98,6 +98,14 @@ open class EntryField: Control {
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Public Properties
|
// MARK: - Public Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
public var onChangeSubscriber: AnyCancellable? {
|
||||||
|
willSet {
|
||||||
|
if let onChangeSubscriber {
|
||||||
|
onChangeSubscriber.cancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
open var titleLabel = Label().with {
|
open var titleLabel = Label().with {
|
||||||
$0.setContentCompressionResistancePriority(.required, for: .vertical)
|
$0.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||||
$0.attributes = []
|
$0.attributes = []
|
||||||
|
|||||||
@ -18,7 +18,7 @@ import Combine
|
|||||||
Knob: The circular indicator that slides on the container.
|
Knob: The circular indicator that slides on the container.
|
||||||
*/
|
*/
|
||||||
@objc(VDSToggle)
|
@objc(VDSToggle)
|
||||||
open class Toggle: Control {
|
open class Toggle: Control, Changeable {
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Enums
|
// MARK: - Enums
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
@ -107,6 +107,14 @@ open class Toggle: Control {
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// MARK: - Public Properties
|
// MARK: - Public Properties
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
|
public var onChangeSubscriber: AnyCancellable? {
|
||||||
|
willSet {
|
||||||
|
if let onChangeSubscriber {
|
||||||
|
onChangeSubscriber.cancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
open var label = Label().with {
|
open var label = Label().with {
|
||||||
$0.setContentCompressionResistancePriority(.required, for: .vertical)
|
$0.setContentCompressionResistancePriority(.required, for: .vertical)
|
||||||
}
|
}
|
||||||
|
|||||||
31
VDS/Protocols/Changeable.swift
Normal file
31
VDS/Protocols/Changeable.swift
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
//
|
||||||
|
// Changeable.swift
|
||||||
|
// VDS
|
||||||
|
//
|
||||||
|
// Created by Matt Bruce on 4/3/23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
import Combine
|
||||||
|
|
||||||
|
public protocol Changeable: Handlerable where Self: UIControl {
|
||||||
|
var onChangeSubscriber: AnyCancellable? { get set }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Changeable {
|
||||||
|
public var onChange: ((Self) -> ())? {
|
||||||
|
get { return nil }
|
||||||
|
set {
|
||||||
|
if let newValue {
|
||||||
|
onChangeSubscriber = publisher(for: .valueChanged)
|
||||||
|
.sink { c in
|
||||||
|
newValue(c)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
onChangeSubscriber?.cancel()
|
||||||
|
onChangeSubscriber = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -15,13 +15,6 @@ public protocol Clickable: Handlerable where Self: UIControl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension Clickable {
|
extension Clickable {
|
||||||
public func addEvent(event: UIControl.Event, block: @escaping (Self)->()) {
|
|
||||||
publisher(for: event)
|
|
||||||
.sink(receiveValue: { c in
|
|
||||||
block(c)
|
|
||||||
}).store(in: &subscribers)
|
|
||||||
}
|
|
||||||
|
|
||||||
public var onClick: ((Self) -> ())? {
|
public var onClick: ((Self) -> ())? {
|
||||||
get { return nil }
|
get { return nil }
|
||||||
set {
|
set {
|
||||||
|
|||||||
@ -17,15 +17,22 @@ public protocol Handlerable: AnyObject, Initable, Disabling, Surfaceable {
|
|||||||
|
|
||||||
extension Handlerable {
|
extension Handlerable {
|
||||||
|
|
||||||
public func setupDidChangeEvent() {
|
public func setupDidChangeEvent(_ debounce: Bool = false) {
|
||||||
handlerPublisher().sink { [weak self] _ in
|
handlerPublisher(debounce)
|
||||||
self?.updateView()
|
.sink { [weak self] _ in
|
||||||
|
self?.updateView()
|
||||||
}.store(in: &subscribers)
|
}.store(in: &subscribers)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func handlerPublisher() -> AnyPublisher<Void, Never> {
|
public func handlerPublisher(_ debounce: Bool = false) -> AnyPublisher<Void, Never> {
|
||||||
subject
|
if debounce {
|
||||||
.eraseToAnyPublisher()
|
return subject
|
||||||
|
.debounce(for: .seconds(Constants.StateDebounce), scheduler: RunLoop.main)
|
||||||
|
.eraseToAnyPublisher()
|
||||||
|
} else {
|
||||||
|
return subject
|
||||||
|
.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,3 +41,12 @@ extension Handlerable where Self: UIView {
|
|||||||
subject.send()
|
subject.send()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension Handlerable where Self: UIControl {
|
||||||
|
public func addEvent(event: UIControl.Event, block: @escaping (Self)->()) {
|
||||||
|
publisher(for: event)
|
||||||
|
.sink(receiveValue: { c in
|
||||||
|
block(c)
|
||||||
|
}).store(in: &subscribers)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user