convert tab to control

Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
Matt Bruce 2023-08-01 10:45:40 -05:00
parent ecff7b9686
commit 090068031e
2 changed files with 27 additions and 36 deletions

View File

@ -12,7 +12,7 @@ import Combine
extension Tabs { extension Tabs {
@objc(VDSTab) @objc(VDSTab)
open class Tab: View { open class Tab: Control {
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Public Properties // MARK: - Public Properties
//-------------------------------------------------- //--------------------------------------------------
@ -20,7 +20,7 @@ extension Tabs {
open var index: Int = 0 open var index: Int = 0
///label to write out the text ///label to write out the text
open var label: Label = Label() open var label: Label = Label().with { $0.isUserInteractionEnabled = false }
///orientation of the tabs ///orientation of the tabs
open var orientation: Tabs.Orientation = .horizontal { didSet { setNeedsUpdate() } } open var orientation: Tabs.Orientation = .horizontal { didSet { setNeedsUpdate() } }
@ -33,16 +33,10 @@ extension Tabs {
///Sets the Position of the Selected/Hover Border Accent for All Tabs. ///Sets the Position of the Selected/Hover Border Accent for All Tabs.
open var indicatorPosition: Tabs.IndicatorPosition = .bottom { didSet { setNeedsUpdate() } } open var indicatorPosition: Tabs.IndicatorPosition = .bottom { didSet { setNeedsUpdate() } }
///An optional callback that is called when this Tab is clicked. Passes parameters (tabIndex).
open var onClick: ((Int) -> Void)? { didSet { setNeedsUpdate() } }
///If provided, it will set fixed width for this Tab. ///If provided, it will set fixed width for this Tab.
open var width: CGFloat? { didSet { setNeedsUpdate() } } 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. ///The text label of the tab.
open var text: String = "" { didSet { setNeedsUpdate() } } open var text: String = "" { didSet { setNeedsUpdate() } }
@ -71,7 +65,7 @@ extension Tabs {
//-------------------------------------------------- //--------------------------------------------------
// MARK: - Configuration // MARK: - Configuration
//-------------------------------------------------- //--------------------------------------------------
private var textColorConfiguration: SurfaceColorConfiguration { selected ? textColorSelectedConfiguration : textColorNonSelectedConfiguration } private var textColorConfiguration: SurfaceColorConfiguration { isSelected ? textColorSelectedConfiguration : textColorNonSelectedConfiguration }
private var textColorNonSelectedConfiguration = SurfaceColorConfiguration(VDSColor.elementsSecondaryOnlight , VDSColor.elementsSecondaryOnlight) private var textColorNonSelectedConfiguration = SurfaceColorConfiguration(VDSColor.elementsSecondaryOnlight , VDSColor.elementsSecondaryOnlight)
private var textColorSelectedConfiguration = SurfaceColorConfiguration(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark) private var textColorSelectedConfiguration = SurfaceColorConfiguration(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark)
private var indicatorColorConfiguration = SurfaceColorConfiguration(VDSColor.paletteRed, VDSColor.elementsPrimaryOndark) private var indicatorColorConfiguration = SurfaceColorConfiguration(VDSColor.paletteRed, VDSColor.elementsPrimaryOndark)
@ -125,7 +119,8 @@ extension Tabs {
super.setup() super.setup()
addSubview(label) addSubview(label)
accessibilityTraits = .button accessibilityTraits = .button
isAccessibilityElement = true
label.translatesAutoresizingMaskIntoConstraints = false label.translatesAutoresizingMaskIntoConstraints = false
label.pinTrailing() label.pinTrailing()
@ -149,16 +144,11 @@ extension Tabs {
layoutGuide.bottomAnchor.constraint(equalTo: bottomAnchor), layoutGuide.bottomAnchor.constraint(equalTo: bottomAnchor),
layoutGuide.leadingAnchor.constraint(equalTo: leadingAnchor), layoutGuide.leadingAnchor.constraint(equalTo: leadingAnchor),
layoutGuide.trailingAnchor.constraint(equalTo: trailingAnchor)]) 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() { open override func updateView() {
super.updateView()
guard !text.isEmpty else { return } guard !text.isEmpty else { return }
//label properties //label properties
@ -178,15 +168,25 @@ extension Tabs {
setNeedsLayout() setNeedsLayout()
} }
open override func updateAccessibility() {
super.updateAccessibility()
accessibilityLabel = text
}
open override func layoutSubviews() { open override func layoutSubviews() {
super.layoutSubviews() super.layoutSubviews()
removeBorders() removeBorders()
if selected { if isSelected {
addBorder(side: indicatorSide, width: indicatorWidth, color: indicatorColorConfiguration.getColor(self)) addBorder(side: indicatorSide, width: indicatorWidth, color: indicatorColorConfiguration.getColor(self))
} }
} }
open override func accessibilityActivate() -> Bool {
sendActions(for: .touchUpInside)
return true
}
} }
} }

View File

@ -211,20 +211,15 @@ open class Tabs: View {
let tabItem = Tab() let tabItem = Tab()
tabItem.size = size tabItem.size = size
tabItem.text = model.text tabItem.text = model.text
tabItem.onClick = model.onClick
tabItem.width = model.width tabItem.width = model.width
tabViews.append(tabItem) tabViews.append(tabItem)
tabStackView.addArrangedSubview(tabItem) tabStackView.addArrangedSubview(tabItem)
tabItem.onClick = { [weak self] tab in
tabItem guard let self else { return }
.publisher(for: UITapGestureRecognizer()) model.onClick?(tab.index)
.sink { [weak self] gesture in self.selectedIndex = tab.index
guard let self, let tabItem = gesture.view as? Tab else { return } self.onTabChange?(tab.index)
if let selectedIndex = self.tabViews.firstIndex(of: tabItem) { }
self.selectedIndex = selectedIndex
self.onTabChange?(selectedIndex)
}
}.store(in: &tabItem.subscribers)
} }
setNeedsUpdate() setNeedsUpdate()
scrollToSelectedIndex(animated: false) scrollToSelectedIndex(animated: false)
@ -249,17 +244,13 @@ open class Tabs: View {
// Update tab appearance based on properties // Update tab appearance based on properties
for (index, tabItem) in tabViews.enumerated() { for (index, tabItem) in tabViews.enumerated() {
tabItem.size = size tabItem.size = size
tabItem.selected = selectedIndex == index tabItem.isSelected = selectedIndex == index
tabItem.index = index tabItem.index = index
tabItem.minWidth = minWidth tabItem.minWidth = minWidth
tabItem.textPosition = textPosition tabItem.textPosition = textPosition
tabItem.orientation = orientation tabItem.orientation = orientation
tabItem.surface = surface tabItem.surface = surface
tabItem.indicatorPosition = indicatorPosition tabItem.indicatorPosition = indicatorPosition
tabItem.isAccessibilityElement = true
tabItem.accessibilityLabel = tabItem.text
tabItem.accessibilityHint = "Tab Item"
tabItem.accessibilityTraits = tabItem.selected ? [.button, .selected] : .button
tabItem.accessibilityValue = "\(index+1) of \(tabViews.count) Tabs" tabItem.accessibilityValue = "\(index+1) of \(tabViews.count) Tabs"
} }