moved underneath tabs class
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
parent
38aff5a637
commit
1205fc7fad
@ -9,132 +9,164 @@ import Foundation
|
||||
import VDSColorTokens
|
||||
import Combine
|
||||
|
||||
public class TabItem: View {
|
||||
extension Tabs {
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Public Properties
|
||||
//--------------------------------------------------
|
||||
public var label: Label = Label()
|
||||
public var orientation: Tabs.Orientation = .horizontal { didSet { setNeedsUpdate() } }
|
||||
public var size: Tabs.Size = .medium { didSet { setNeedsUpdate() } }
|
||||
public var indicatorPosition: Tabs.IndicatorPosition = .bottom { didSet { setNeedsUpdate() } }
|
||||
public var onClick: (() -> Void)? { didSet { setNeedsUpdate() } }
|
||||
public var width: CGFloat? { didSet { setNeedsUpdate() } }
|
||||
public var selected: Bool = false { didSet { setNeedsUpdate() } }
|
||||
public var text: String? { didSet { setNeedsUpdate() } }
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Private Properties
|
||||
//--------------------------------------------------
|
||||
private var labelWidthConstraint: NSLayoutConstraint?
|
||||
private var labelLeadingConstraint: NSLayoutConstraint?
|
||||
private var labelTopConstraint: NSLayoutConstraint?
|
||||
private var labelBottomConstraint: NSLayoutConstraint?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Configuration
|
||||
//--------------------------------------------------
|
||||
private var textColorConfiguration: SurfaceColorConfiguration { selected ? textColorSelectedConfiguration : textColorNonSelectedConfiguration }
|
||||
private var textColorNonSelectedConfiguration = SurfaceColorConfiguration(VDSColor.elementsSecondaryOnlight , VDSColor.elementsSecondaryOnlight)
|
||||
private var textColorSelectedConfiguration = SurfaceColorConfiguration(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark)
|
||||
private var indicatorColorConfiguration = SurfaceColorConfiguration(VDSColor.paletteRed, VDSColor.elementsPrimaryOndark)
|
||||
private var indicatorWidth: CGFloat = 4.0
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
||||
public required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
required public convenience init() {
|
||||
self.init(frame: .zero)
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Overrides
|
||||
//--------------------------------------------------
|
||||
override public func setup() {
|
||||
super.setup()
|
||||
addSubview(label)
|
||||
backgroundColor = .clear
|
||||
label.backgroundColor = .clear
|
||||
open class TabItem: View {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Public Properties
|
||||
//--------------------------------------------------
|
||||
///position of the tab
|
||||
open var index: Int = 0
|
||||
|
||||
label.translatesAutoresizingMaskIntoConstraints = false
|
||||
label.pinTrailing()
|
||||
///label to write out the text
|
||||
open var label: Label = Label()
|
||||
|
||||
labelTopConstraint = label.topAnchor.constraint(equalTo: topAnchor, constant: 0)
|
||||
labelTopConstraint?.isActive = true
|
||||
///orientation of the tabs
|
||||
open var orientation: Tabs.Orientation = .horizontal { didSet { setNeedsUpdate() } }
|
||||
|
||||
labelBottomConstraint = label.bottomAnchor.constraint(equalTo: bottomAnchor, constant: 0)
|
||||
labelBottomConstraint?.isActive = true
|
||||
///Size for tab
|
||||
open var size: Tabs.Size = .medium { didSet { setNeedsUpdate() } }
|
||||
|
||||
labelLeadingConstraint = label.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 0)
|
||||
labelLeadingConstraint?.isActive = true
|
||||
///Text position left or center
|
||||
open var textPosition: TextPosition = .left { didSet { setNeedsUpdate() } }
|
||||
|
||||
labelWidthConstraint = label.widthAnchor.constraint(greaterThanOrEqualToConstant: 44.0)
|
||||
labelWidthConstraint?.isActive = true
|
||||
///Sets the Position of the Selected/Hover Border Accent for All Tabs.
|
||||
open var indicatorPosition: Tabs.IndicatorPosition = .bottom { didSet { setNeedsUpdate() } }
|
||||
|
||||
publisher(for: UITapGestureRecognizer())
|
||||
.sink { [weak self] _ in
|
||||
self?.onClick?()
|
||||
}.store(in: &subscribers)
|
||||
///An optional callback that is called when this Tab is clicked. Passes parameters (tabIndex).
|
||||
open var onClick: ((Int) -> Void)? { didSet { setNeedsUpdate() } }
|
||||
|
||||
}
|
||||
|
||||
public override func updateView() {
|
||||
if orientation == .horizontal {
|
||||
label.textPosition = .center
|
||||
} else {
|
||||
label.textPosition = .left
|
||||
///If provided, it will set fixed width for this Tab.
|
||||
open var width: CGFloat? { didSet { setNeedsUpdate() } }
|
||||
|
||||
///If provided, it will set this Tab to the Active Tab on render.
|
||||
open var selected: Bool = false { didSet { setNeedsUpdate() } }
|
||||
|
||||
///The text label of the tab.
|
||||
open var text: String? { didSet { setNeedsUpdate() } }
|
||||
|
||||
///Minimum width for the tab
|
||||
open var minWidth: CGFloat = 44.0 { didSet { setNeedsUpdate() } }
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Private Properties
|
||||
//--------------------------------------------------
|
||||
private var labelWidthConstraint: NSLayoutConstraint?
|
||||
private var labelLeadingConstraint: NSLayoutConstraint?
|
||||
private var labelTopConstraint: NSLayoutConstraint?
|
||||
private var labelBottomConstraint: NSLayoutConstraint?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Configuration
|
||||
//--------------------------------------------------
|
||||
private var textColorConfiguration: SurfaceColorConfiguration { selected ? textColorSelectedConfiguration : textColorNonSelectedConfiguration }
|
||||
private var textColorNonSelectedConfiguration = SurfaceColorConfiguration(VDSColor.elementsSecondaryOnlight , VDSColor.elementsSecondaryOnlight)
|
||||
private var textColorSelectedConfiguration = SurfaceColorConfiguration(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark)
|
||||
private var indicatorColorConfiguration = SurfaceColorConfiguration(VDSColor.paletteRed, VDSColor.elementsPrimaryOndark)
|
||||
private var indicatorWidth: CGFloat = 4.0
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
}
|
||||
label.text = text
|
||||
label.textStyle = size.textStyle
|
||||
label.textColor = textColorConfiguration.getColor(self)
|
||||
|
||||
labelWidthConstraint?.isActive = false
|
||||
if let width {
|
||||
labelWidthConstraint = label.widthAnchor.constraint(equalToConstant: width)
|
||||
} else {
|
||||
labelWidthConstraint = label.widthAnchor.constraint(greaterThanOrEqualToConstant: 44.0)
|
||||
public required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
labelWidthConstraint?.isActive = true
|
||||
|
||||
var leadingSpace: CGFloat
|
||||
if orientation == .horizontal {
|
||||
leadingSpace = 0
|
||||
} else {
|
||||
leadingSpace = size == .medium ? VDSLayout.Spacing.space4X.value : VDSLayout.Spacing.space6X.value
|
||||
}
|
||||
labelLeadingConstraint?.constant = leadingSpace
|
||||
|
||||
var otherSpace: CGFloat
|
||||
if orientation == .horizontal {
|
||||
otherSpace = size == .medium ? VDSLayout.Spacing.space3X.value : VDSLayout.Spacing.space4X.value
|
||||
} else {
|
||||
otherSpace = VDSLayout.Spacing.space2X.value
|
||||
}
|
||||
labelTopConstraint?.constant = otherSpace
|
||||
labelBottomConstraint?.constant = -otherSpace
|
||||
|
||||
setNeedsLayout()
|
||||
}
|
||||
|
||||
public override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
removeBorders()
|
||||
|
||||
if selected {
|
||||
var indicator: UIRectEdge = .left
|
||||
if orientation == .horizontal {
|
||||
indicator = indicatorPosition.value
|
||||
required public convenience init() {
|
||||
self.init(frame: .zero)
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Overrides
|
||||
//--------------------------------------------------
|
||||
open override func setup() {
|
||||
super.setup()
|
||||
addSubview(label)
|
||||
backgroundColor = .clear
|
||||
label.backgroundColor = .clear
|
||||
|
||||
label.translatesAutoresizingMaskIntoConstraints = false
|
||||
label.pinTrailing()
|
||||
|
||||
labelTopConstraint = label.topAnchor.constraint(equalTo: topAnchor)
|
||||
labelTopConstraint?.isActive = true
|
||||
|
||||
labelBottomConstraint = label.bottomAnchor.constraint(equalTo: bottomAnchor)
|
||||
labelBottomConstraint?.isActive = true
|
||||
|
||||
labelLeadingConstraint = label.leadingAnchor.constraint(equalTo: leadingAnchor)
|
||||
labelLeadingConstraint?.isActive = true
|
||||
|
||||
let layoutGuide = UILayoutGuide()
|
||||
addLayoutGuide(layoutGuide)
|
||||
|
||||
|
||||
labelWidthConstraint = layoutGuide.widthAnchor.constraint(greaterThanOrEqualToConstant: 44.0)
|
||||
labelWidthConstraint?.isActive = true
|
||||
|
||||
//activate the constraints
|
||||
NSLayoutConstraint.activate([layoutGuide.topAnchor.constraint(equalTo: topAnchor),
|
||||
layoutGuide.bottomAnchor.constraint(equalTo: bottomAnchor),
|
||||
layoutGuide.leadingAnchor.constraint(equalTo: leadingAnchor),
|
||||
layoutGuide.trailingAnchor.constraint(equalTo: trailingAnchor)])
|
||||
|
||||
publisher(for: UITapGestureRecognizer())
|
||||
.sink { [weak self] _ in
|
||||
guard let self else { return }
|
||||
self.onClick?(self.index)
|
||||
}.store(in: &subscribers)
|
||||
|
||||
}
|
||||
|
||||
open override func updateView() {
|
||||
label.text = text
|
||||
label.textPosition = textPosition
|
||||
label.textStyle = size.textStyle
|
||||
label.textColor = textColorConfiguration.getColor(self)
|
||||
labelWidthConstraint?.isActive = false
|
||||
if let width {
|
||||
labelWidthConstraint = label.widthAnchor.constraint(equalToConstant: width)
|
||||
} else {
|
||||
labelWidthConstraint = label.widthAnchor.constraint(greaterThanOrEqualToConstant: 44.0)
|
||||
}
|
||||
labelWidthConstraint?.isActive = true
|
||||
|
||||
var leadingSpace: CGFloat
|
||||
if orientation == .horizontal {
|
||||
leadingSpace = 0
|
||||
} else {
|
||||
leadingSpace = size == .medium ? VDSLayout.Spacing.space4X.value : VDSLayout.Spacing.space6X.value
|
||||
}
|
||||
labelLeadingConstraint?.constant = leadingSpace
|
||||
|
||||
var otherSpace: CGFloat
|
||||
if orientation == .horizontal {
|
||||
otherSpace = size == .medium ? VDSLayout.Spacing.space3X.value : VDSLayout.Spacing.space4X.value
|
||||
} else {
|
||||
otherSpace = VDSLayout.Spacing.space2X.value
|
||||
}
|
||||
labelTopConstraint?.constant = otherSpace
|
||||
labelBottomConstraint?.constant = -otherSpace
|
||||
|
||||
setNeedsLayout()
|
||||
}
|
||||
|
||||
open override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
removeBorders()
|
||||
|
||||
if selected {
|
||||
var indicator: UIRectEdge = .left
|
||||
if orientation == .horizontal {
|
||||
indicator = indicatorPosition.value
|
||||
}
|
||||
addBorder(side: indicator, width: indicatorWidth, color: indicatorColorConfiguration.getColor(self), offset: 1)
|
||||
}
|
||||
addBorder(side: indicator, width: indicatorWidth, color: indicatorColorConfiguration.getColor(self))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,14 +7,22 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
public struct TabModel {
|
||||
public var text: String
|
||||
public var onClick: (() -> Void)?
|
||||
public var width: CGFloat?
|
||||
|
||||
public init(text: String, onClick: (() -> Void)? = nil, width: CGFloat? = nil) {
|
||||
self.text = text
|
||||
self.onClick = onClick
|
||||
self.width = width
|
||||
extension Tabs {
|
||||
public struct TabModel {
|
||||
|
||||
///Text that goes in the Tab
|
||||
public var text: String
|
||||
|
||||
///Click event when you click on a tab
|
||||
public var onClick: ((Int) -> Void)?
|
||||
|
||||
///Width of the tab
|
||||
public var width: CGFloat?
|
||||
|
||||
public init(text: String, onClick: ((Int) -> Void)? = nil, width: CGFloat? = nil) {
|
||||
self.text = text
|
||||
self.onClick = onClick
|
||||
self.width = width
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user