From 33163a61834263a807372a19be6a859326fca69d Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 27 Jul 2023 15:32:14 -0500 Subject: [PATCH 01/20] fixed bug for trailing tooltip Signed-off-by: Matt Bruce --- VDS/Components/Label/Label.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/VDS/Components/Label/Label.swift b/VDS/Components/Label/Label.swift index f2f83116..0e78d762 100644 --- a/VDS/Components/Label/Label.swift +++ b/VDS/Components/Label/Label.swift @@ -97,7 +97,7 @@ open class Label: UILabel, Handlerable, ViewProtocol, Resettable, UserInfoable { .sink { [weak self] notification in self?.setNeedsUpdate() }.store(in: &subscribers) - + isUserInteractionEnabled = true backgroundColor = .clear numberOfLines = 0 lineBreakMode = .byWordWrapping @@ -120,6 +120,7 @@ open class Label: UILabel, Handlerable, ViewProtocol, Resettable, UserInfoable { textStyle = .defaultStyle textPosition = .left text = nil + isUserInteractionEnabled = true attributedText = nil numberOfLines = 0 backgroundColor = .clear From 29e4fcb165d7a616664f6bac2511a935e3ccb7d7 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Thu, 27 Jul 2023 15:34:46 -0500 Subject: [PATCH 02/20] made real update and not a forced one Signed-off-by: Matt Bruce --- VDS/Components/Label/Label.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/VDS/Components/Label/Label.swift b/VDS/Components/Label/Label.swift index 0e78d762..59358125 100644 --- a/VDS/Components/Label/Label.swift +++ b/VDS/Components/Label/Label.swift @@ -97,7 +97,7 @@ open class Label: UILabel, Handlerable, ViewProtocol, Resettable, UserInfoable { .sink { [weak self] notification in self?.setNeedsUpdate() }.store(in: &subscribers) - isUserInteractionEnabled = true + backgroundColor = .clear numberOfLines = 0 lineBreakMode = .byWordWrapping @@ -120,7 +120,6 @@ open class Label: UILabel, Handlerable, ViewProtocol, Resettable, UserInfoable { textStyle = .defaultStyle textPosition = .left text = nil - isUserInteractionEnabled = true attributedText = nil numberOfLines = 0 backgroundColor = .clear @@ -223,6 +222,7 @@ open class Label: UILabel, Handlerable, ViewProtocol, Resettable, UserInfoable { private var actions: [LabelAction] = [] { didSet { + isUserInteractionEnabled = !actions.isEmpty if actions.isEmpty { tapGesture = nil } else { From 16d37e1c45aefc75cfecb797128efab2cee1a5f6 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Fri, 28 Jul 2023 14:29:43 -0500 Subject: [PATCH 03/20] ONEAPP-5104 - Button Disabled Accessibility iOS Signed-off-by: Matt Bruce --- VDS/Classes/SelectorBase.swift | 11 ++++++----- VDS/Classes/SelectorGroupHandlerBase.swift | 14 +++++++------- VDS/Classes/SelectorItemBase.swift | 12 +++++++----- VDS/Components/Buttons/Button/ButtonBase.swift | 6 +++--- VDS/Components/RadioBox/RadioBoxItem.swift | 10 +++++----- VDS/Components/Toggle/Toggle.swift | 10 +++++----- VDS/Components/Toggle/ToggleView.swift | 10 +++++----- VDS/Components/Tooltip/Tooltip.swift | 6 +++--- 8 files changed, 41 insertions(+), 38 deletions(-) diff --git a/VDS/Classes/SelectorBase.swift b/VDS/Classes/SelectorBase.swift index a6d6a7f5..ffd94ccd 100644 --- a/VDS/Classes/SelectorBase.swift +++ b/VDS/Classes/SelectorBase.swift @@ -90,16 +90,17 @@ open class SelectorBase: Control, SelectorControlable { open override func updateAccessibilityLabel() { accessibilityValue = isSelected ? "1" : "0" - if !accessibilityTraits.contains(.selected) && isSelected { + if isSelected { accessibilityTraits.insert(.selected) - } else if accessibilityTraits.contains(.selected) && !isSelected{ + } else { accessibilityTraits.remove(.selected) } - if !accessibilityTraits.contains(.notEnabled) && !isEnabled { - accessibilityTraits.insert(.notEnabled) - } else if accessibilityTraits.contains(.notEnabled) && !isEnabled { + if isEnabled { accessibilityTraits.remove(.notEnabled) + } else { + accessibilityTraits.insert(.notEnabled) } + accessibilityLabel = isSelected ? "Selected" : "Not Selected" } } diff --git a/VDS/Classes/SelectorGroupHandlerBase.swift b/VDS/Classes/SelectorGroupHandlerBase.swift index 76a6fc74..d5669538 100644 --- a/VDS/Classes/SelectorGroupHandlerBase.swift +++ b/VDS/Classes/SelectorGroupHandlerBase.swift @@ -69,18 +69,18 @@ open class SelectorGroupHandlerBase: Control, Changeable { selectorViews.forEach{ $0.reset() } } - open override func updateAccessibilityLabel() { - if !accessibilityTraits.contains(.selected) && isSelected { + open override func updateAccessibilityLabel() { + if isSelected { accessibilityTraits.insert(.selected) - } else if accessibilityTraits.contains(.selected) && !isSelected{ + } else { accessibilityTraits.remove(.selected) } - if !accessibilityTraits.contains(.notEnabled) && !isEnabled { - accessibilityTraits.insert(.notEnabled) - } else if accessibilityTraits.contains(.notEnabled) && !isEnabled { + if isEnabled { accessibilityTraits.remove(.notEnabled) - } + } else { + accessibilityTraits.insert(.notEnabled) + } setAccessibilityLabel(for: selectorViews) } } diff --git a/VDS/Classes/SelectorItemBase.swift b/VDS/Classes/SelectorItemBase.swift index b9f659bd..c98102fd 100644 --- a/VDS/Classes/SelectorItemBase.swift +++ b/VDS/Classes/SelectorItemBase.swift @@ -272,17 +272,19 @@ open class SelectorItemBase: Control, Errorable, open override func updateAccessibilityLabel() { accessibilityValue = isSelected ? "1" : "0" - if !accessibilityTraits.contains(.selected) && isSelected { + if isSelected { accessibilityTraits.insert(.selected) - } else if accessibilityTraits.contains(.selected) && !isSelected{ + } else { accessibilityTraits.remove(.selected) } - if !accessibilityTraits.contains(.notEnabled) && !isEnabled { - accessibilityTraits.insert(.notEnabled) - } else if accessibilityTraits.contains(.notEnabled) && !isEnabled { + if isEnabled { accessibilityTraits.remove(.notEnabled) + } else { + accessibilityTraits.insert(.notEnabled) } setAccessibilityLabel(for: [label, childLabel, errorLabel]) + + accessibilityLabel = "\(isSelected ? "Selected" : "Not Selected"), \(accessibilityLabel ?? "")" } } diff --git a/VDS/Components/Buttons/Button/ButtonBase.swift b/VDS/Components/Buttons/Button/ButtonBase.swift index 054c10b3..ea01479d 100644 --- a/VDS/Components/Buttons/Button/ButtonBase.swift +++ b/VDS/Components/Buttons/Button/ButtonBase.swift @@ -162,10 +162,10 @@ open class ButtonBase: UIButton, Buttonable, Handlerable, ViewProtocol, Resettab } open func updateAccessibilityLabel() { - if !accessibilityTraits.contains(.notEnabled) && !isEnabled { - accessibilityTraits.insert(.notEnabled) - } else if accessibilityTraits.contains(.notEnabled) && !isEnabled { + if isEnabled { accessibilityTraits.remove(.notEnabled) + } else { + accessibilityTraits.insert(.notEnabled) } } diff --git a/VDS/Components/RadioBox/RadioBoxItem.swift b/VDS/Components/RadioBox/RadioBoxItem.swift index 74e2f574..9f674099 100644 --- a/VDS/Components/RadioBox/RadioBoxItem.swift +++ b/VDS/Components/RadioBox/RadioBoxItem.swift @@ -250,16 +250,16 @@ open class RadioBoxItem: Control, Changeable { open override func updateAccessibilityLabel() { accessibilityValue = isSelected ? "1" : "0" - if !accessibilityTraits.contains(.selected) && isSelected { + if isSelected { accessibilityTraits.insert(.selected) - } else if accessibilityTraits.contains(.selected) && !isSelected{ + } else { accessibilityTraits.remove(.selected) } - if !accessibilityTraits.contains(.notEnabled) && !isEnabled { - accessibilityTraits.insert(.notEnabled) - } else if accessibilityTraits.contains(.notEnabled) && !isEnabled { + if isEnabled { accessibilityTraits.remove(.notEnabled) + } else { + accessibilityTraits.insert(.notEnabled) } if accessibilityLabel == nil { setAccessibilityLabel(for: [textLabel, subTextLabel, subTextRightLabel]) diff --git a/VDS/Components/Toggle/Toggle.swift b/VDS/Components/Toggle/Toggle.swift index 1d9b77b0..30459205 100644 --- a/VDS/Components/Toggle/Toggle.swift +++ b/VDS/Components/Toggle/Toggle.swift @@ -242,16 +242,16 @@ open class Toggle: Control, Changeable { open override func updateAccessibilityLabel() { accessibilityValue = isSelected ? "1" : "0" - if !accessibilityTraits.contains(.selected) && isSelected { + if isSelected { accessibilityTraits.insert(.selected) - } else if accessibilityTraits.contains(.selected) && !isSelected{ + } else { accessibilityTraits.remove(.selected) } - if !accessibilityTraits.contains(.notEnabled) && !isEnabled { - accessibilityTraits.insert(.notEnabled) - } else if accessibilityTraits.contains(.notEnabled) && !isEnabled{ + if isEnabled { accessibilityTraits.remove(.notEnabled) + } else { + accessibilityTraits.insert(.notEnabled) } setAccessibilityLabel(for: [label]) } diff --git a/VDS/Components/Toggle/ToggleView.swift b/VDS/Components/Toggle/ToggleView.swift index db07e66d..1608bb6c 100644 --- a/VDS/Components/Toggle/ToggleView.swift +++ b/VDS/Components/Toggle/ToggleView.swift @@ -205,16 +205,16 @@ open class ToggleView: Control, Changeable { open override func updateAccessibilityLabel() { accessibilityLabel = "Toggle" accessibilityValue = isSelected ? "1" : "0" - if !accessibilityTraits.contains(.selected) && isSelected { + if isSelected { accessibilityTraits.insert(.selected) - } else if accessibilityTraits.contains(.selected) && !isSelected{ + } else { accessibilityTraits.remove(.selected) } - if !accessibilityTraits.contains(.notEnabled) && !isEnabled { - accessibilityTraits.insert(.notEnabled) - } else if accessibilityTraits.contains(.notEnabled) && !isEnabled{ + if isEnabled { accessibilityTraits.remove(.notEnabled) + } else { + accessibilityTraits.insert(.notEnabled) } } } diff --git a/VDS/Components/Tooltip/Tooltip.swift b/VDS/Components/Tooltip/Tooltip.swift index 585ab355..9c55747f 100644 --- a/VDS/Components/Tooltip/Tooltip.swift +++ b/VDS/Components/Tooltip/Tooltip.swift @@ -167,10 +167,10 @@ open class Tooltip: Control, TooltipLaunchable { } open override func updateAccessibilityLabel() { - if !accessibilityTraits.contains(.notEnabled) && !isEnabled { - accessibilityTraits.insert(.notEnabled) - } else if accessibilityTraits.contains(.notEnabled) && !isEnabled { + if isEnabled { accessibilityTraits.remove(.notEnabled) + } else { + accessibilityTraits.insert(.notEnabled) } var label = title if label == nil { From 1bed04dae0435f95dfd6de119eb2660a798825d5 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 31 Jul 2023 10:13:37 -0500 Subject: [PATCH 04/20] added presenter Signed-off-by: Matt Bruce --- .../Label/Attributes/TooltipLabelAttribute.swift | 8 ++++++-- VDS/Components/TextFields/EntryField/EntryField.swift | 2 +- VDS/Components/Tooltip/Tooltip.swift | 7 +++++-- VDS/Components/Tooltip/TooltipLaunchable.swift | 5 +++-- VDS/Components/Tooltip/TrailingTooltipLabel.swift | 6 ++++-- 5 files changed, 19 insertions(+), 9 deletions(-) diff --git a/VDS/Components/Label/Attributes/TooltipLabelAttribute.swift b/VDS/Components/Label/Attributes/TooltipLabelAttribute.swift index 067d70ed..2ea9f227 100644 --- a/VDS/Components/Label/Attributes/TooltipLabelAttribute.swift +++ b/VDS/Components/Label/Attributes/TooltipLabelAttribute.swift @@ -23,6 +23,7 @@ public class TooltipLabelAttribute: ActionLabelAttributeModel, TooltipLaunchable public var title: String? public var content: String? public var contentView: UIView? + public var presenter: UIView? public func setAttribute(on attributedString: NSMutableAttributedString) { //update the location @@ -66,7 +67,7 @@ public class TooltipLabelAttribute: ActionLabelAttributeModel, TooltipLaunchable addHandler(on: attributedString) } - public init(id: UUID = UUID(), action: PassthroughSubject = PassthroughSubject(), subscriber: AnyCancellable? = nil, surface: Surface, accessibleText: String? = nil, closeButtonText: String = "Close", title: String? = nil, content: String? = nil, contentView: UIView? = nil) { + public init(id: UUID = UUID(), action: PassthroughSubject = PassthroughSubject(), subscriber: AnyCancellable? = nil, surface: Surface, accessibleText: String? = nil, closeButtonText: String = "Close", title: String? = nil, content: String? = nil, contentView: UIView? = nil, presenter: UIView? = nil) { self.id = id self.action = action self.subscriber = subscriber @@ -76,6 +77,8 @@ public class TooltipLabelAttribute: ActionLabelAttributeModel, TooltipLaunchable self.title = title self.content = content self.contentView = contentView + self.presenter = presenter + //create the tooltip click event self.subscriber = action.sink { [weak self] in guard let self else { return } @@ -83,7 +86,8 @@ public class TooltipLabelAttribute: ActionLabelAttributeModel, TooltipLaunchable title: self.title, content: self.content, contentView: contentView, - closeButtonText: self.closeButtonText) + closeButtonText: self.closeButtonText, + presenter: self.presenter) } } diff --git a/VDS/Components/TextFields/EntryField/EntryField.swift b/VDS/Components/TextFields/EntryField/EntryField.swift index eb43ba49..d485c007 100644 --- a/VDS/Components/TextFields/EntryField/EntryField.swift +++ b/VDS/Components/TextFields/EntryField/EntryField.swift @@ -295,7 +295,7 @@ open class EntryField: Control, Changeable { } if let tooltipTitle, let tooltipContent { - attributes.append(TooltipLabelAttribute(surface: surface, title: tooltipTitle, content: tooltipContent, contentView: tooltipContentView)) + attributes.append(TooltipLabelAttribute(surface: surface, title: tooltipTitle, content: tooltipContent, contentView: tooltipContentView, presenter: self)) } //set the titleLabel diff --git a/VDS/Components/Tooltip/Tooltip.swift b/VDS/Components/Tooltip/Tooltip.swift index 9c55747f..8010a81f 100644 --- a/VDS/Components/Tooltip/Tooltip.swift +++ b/VDS/Components/Tooltip/Tooltip.swift @@ -135,7 +135,8 @@ open class Tooltip: Control, TooltipLaunchable { title: tooltip.title, content: tooltip.content, contentView: tooltip.contentView, - closeButtonText: tooltip.closeButtonText) + closeButtonText: tooltip.closeButtonText, + presenter: self) }) } @@ -176,8 +177,10 @@ open class Tooltip: Control, TooltipLaunchable { if label == nil { label = content } + accessibilityHint = "Tooltip" + accessibilityValue = "collapsed" if let label { - accessibilityLabel = "Tooltip: \(label)" + accessibilityLabel = label } } } diff --git a/VDS/Components/Tooltip/TooltipLaunchable.swift b/VDS/Components/Tooltip/TooltipLaunchable.swift index 17c3f680..33d09b16 100644 --- a/VDS/Components/Tooltip/TooltipLaunchable.swift +++ b/VDS/Components/Tooltip/TooltipLaunchable.swift @@ -9,11 +9,11 @@ import Foundation import UIKit public protocol TooltipLaunchable { - func presentTooltip(surface: Surface, title: String?, content: String?, contentView: UIView?, closeButtonText: String) + func presentTooltip(surface: Surface, title: String?, content: String?, contentView: UIView?, closeButtonText: String, presenter: UIView?) } extension TooltipLaunchable { - public func presentTooltip(surface: Surface, title: String?, content: String?, contentView: UIView? = nil, closeButtonText: String = "Close") { + public func presentTooltip(surface: Surface, title: String?, content: String?, contentView: UIView? = nil, closeButtonText: String = "Close", presenter: UIView? = nil) { if let presenting = UIApplication.topViewController() { let tooltipViewController = TooltipAlertViewController(nibName: nil, bundle: nil).with { $0.surface = surface @@ -21,6 +21,7 @@ extension TooltipLaunchable { $0.contentText = content $0.contentView = contentView $0.closeButtonText = closeButtonText + $0.presenter = presenter $0.modalPresentationStyle = .overCurrentContext $0.modalTransitionStyle = .crossDissolve } diff --git a/VDS/Components/Tooltip/TrailingTooltipLabel.swift b/VDS/Components/Tooltip/TrailingTooltipLabel.swift index 00cbc8f3..6986dd3a 100644 --- a/VDS/Components/Tooltip/TrailingTooltipLabel.swift +++ b/VDS/Components/Tooltip/TrailingTooltipLabel.swift @@ -57,7 +57,8 @@ open class TrailingTooltipLabel: View, TooltipLaunchable { self.presentTooltip(surface: self.surface, title: self.tooltipTitle, content: self.tooltipContent, - closeButtonText: self.tooltipCloseButtonText) + closeButtonText: self.tooltipCloseButtonText, + presenter: self) }.store(in: &subscribers) } @@ -126,7 +127,8 @@ extension Label { closeButtonText: model.closeButtonText, title: model.title, content: model.content, - contentView: model.contentView) + contentView: model.contentView, + presenter: self) newAttributes.append(tooltip) } From 2c7666c2141f11e3f26a271f22acd0be29c535fc Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 31 Jul 2023 13:42:37 -0500 Subject: [PATCH 05/20] helper for text Signed-off-by: Matt Bruce --- VDS/Components/Tooltip/Tooltip.swift | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/VDS/Components/Tooltip/Tooltip.swift b/VDS/Components/Tooltip/Tooltip.swift index 8010a81f..6d88fca2 100644 --- a/VDS/Components/Tooltip/Tooltip.swift +++ b/VDS/Components/Tooltip/Tooltip.swift @@ -183,6 +183,20 @@ open class Tooltip: Control, TooltipLaunchable { accessibilityLabel = label } } + + public static func accessibleText(for title: String?, content: String?, closeButtonText: String) -> String { + var label = "" + if let title { + label = title + } + if let content { + if !label.isEmpty { + label += "," + } + label += content + } + return label + } } From d275c476b330a121165d02d7095f6c734b01976a Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Mon, 31 Jul 2023 13:42:48 -0500 Subject: [PATCH 06/20] update for bug Signed-off-by: Matt Bruce --- .../Tooltip/TooltipAlertViewController.swift | 57 +++++++++++++------ 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/VDS/Components/Tooltip/TooltipAlertViewController.swift b/VDS/Components/Tooltip/TooltipAlertViewController.swift index 23d84c48..da461287 100644 --- a/VDS/Components/Tooltip/TooltipAlertViewController.swift +++ b/VDS/Components/Tooltip/TooltipAlertViewController.swift @@ -36,7 +36,7 @@ open class TooltipAlertViewController: UIViewController, Surfaceable { open var contentText: String? { didSet { updateView() }} open var contentView: UIView? { didSet { updateView() }} open var closeButtonText: String = "Close" { didSet { updateView() }} - + open var presenter: UIView? { didSet { updateView() }} //-------------------------------------------------- // MARK: - Configuration //-------------------------------------------------- @@ -50,28 +50,41 @@ open class TooltipAlertViewController: UIViewController, Surfaceable { isModalInPresentation = true setup() } + open override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + UIAccessibility.post(notification: .screenChanged, argument: tooltipDialog) + } + + private func dismiss() { + dismiss(animated: true) { [weak self] in + guard let self, let presenter else { return } + UIAccessibility.post(notification: .layoutChanged, argument: presenter) + } + } open func setup() { + view.accessibilityElements = [tooltipDialog] + //left-right swipe view.publisher(for: UISwipeGestureRecognizer().with{ $0.direction = .right }) .sink { [weak self] swipe in - guard let self else { return } - self.dismiss(animated: true, completion: nil) - }.store(in: &subscribers) - + guard let self else { return } + self.dismiss() + }.store(in: &subscribers) + //tapping in background view.publisher(for: UITapGestureRecognizer().with{ $0.numberOfTapsRequired = 1 }) .sink { [weak self] swipe in - guard let self else { return } - self.dismiss(animated: true, completion: nil) - }.store(in: &subscribers) - + guard let self else { return } + self.dismiss() + }.store(in: &subscribers) + //clicking button onClickSubscriber = tooltipDialog.closeButton.publisher(for: .touchUpInside) .sink {[weak self] button in - guard let self else { return } - self.dismiss(animated: true, completion: nil) - } + guard let self else { return } + self.dismiss() + } view.addSubview(tooltipDialog) @@ -160,9 +173,8 @@ open class TooltipDialog: View, UIScrollViewDelegate { //-------------------------------------------------- open override func setup() { super.setup() - layer.cornerRadius = 8 - + contentStackView.isAccessibilityElement = true contentStackView.addArrangedSubview(titleLabel) contentStackView.addArrangedSubview(contentLabel) scrollView.addSubview(contentStackView) @@ -204,7 +216,7 @@ open class TooltipDialog: View, UIScrollViewDelegate { open override func updateView() { super.updateView() - + backgroundColor = backgroundColorConfiguration.getColor(self) scrollView.indicatorStyle = surface == .light ? .black : .white @@ -257,6 +269,7 @@ open class TooltipDialog: View, UIScrollViewDelegate { closeButton.setTitleColor(closeButtonTextColor, for: .normal) closeButton.setTitleColor(closeButtonTextColor, for: .highlighted) closeButton.setTitle(closeButtonText, for: .normal) + closeButton.accessibilityLabel = closeButtonText contentStackView.setNeedsLayout() contentStackView.layoutIfNeeded() @@ -282,7 +295,19 @@ open class TooltipDialog: View, UIScrollViewDelegate { //stackView between the bottom of the scrollView contentStackViewBottomConstraint?.constant = -containerViewInset } - + heightConstraint?.constant = contentHeight } + + open override func updateAccessibilityLabel() { + var label = Tooltip.accessibleText(for: titleText, content: contentText, closeButtonText: closeButtonText) + if !label.isEmpty { + label += "," + } + + contentStackView.accessibilityLabel = "\(label) Click on the \(closeButtonText) button to close." + contentStackView.accessibilityHint = "Tooltip" + contentStackView.accessibilityValue = "expanded" + accessibilityElements = [contentStackView, closeButton] + } } From 05543e7c897e2cf040a71e22f9c30a93569c48fb Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 1 Aug 2023 09:21:16 -0500 Subject: [PATCH 07/20] updated trait from text to link when there is a action Signed-off-by: Matt Bruce --- VDS/Components/Label/Label.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/VDS/Components/Label/Label.swift b/VDS/Components/Label/Label.swift index 59358125..733d858b 100644 --- a/VDS/Components/Label/Label.swift +++ b/VDS/Components/Label/Label.swift @@ -223,6 +223,7 @@ open class Label: UILabel, Handlerable, ViewProtocol, Resettable, UserInfoable { private var actions: [LabelAction] = [] { didSet { isUserInteractionEnabled = !actions.isEmpty + accessibilityTraits = !actions.isEmpty ? .link : .staticText if actions.isEmpty { tapGesture = nil } else { @@ -265,7 +266,6 @@ open class Label: UILabel, Handlerable, ViewProtocol, Resettable, UserInfoable { let actionText = accessibleText ?? NSString(string:text).substring(with: range) let accessibleAction = UIAccessibilityCustomAction(name: actionText, target: self, selector: #selector(accessibilityCustomAction(_:))) accessibilityCustomActions?.append(accessibleAction) - return accessibleAction } @@ -295,4 +295,3 @@ open class Label: UILabel, Handlerable, ViewProtocol, Resettable, UserInfoable { return false } } - From ecff7b968636da1f999e32ef6e1ebc1d8df8665c Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 1 Aug 2023 10:23:24 -0500 Subject: [PATCH 08/20] refactored updateAccessibiltyLabel to updateAccessibility moved down common isEnabled/isSelected down to base classes Signed-off-by: Matt Bruce --- VDS/Classes/Control.swift | 15 +++++++++++++-- VDS/Classes/SelectorBase.swift | 15 ++------------- VDS/Classes/SelectorGroupHandlerBase.swift | 18 ++++-------------- VDS/Classes/SelectorItemBase.swift | 18 +++--------------- VDS/Classes/View.swift | 10 +++++++--- .../Buttons/Button/ButtonBase.swift | 4 ++-- VDS/Components/Icon/Icon.swift | 4 ---- VDS/Components/Label/Label.swift | 4 ++-- VDS/Components/RadioBox/RadioBoxItem.swift | 16 +++------------- VDS/Components/RadioSwatch/RadioSwatch.swift | 2 +- VDS/Components/Tabs/Tabs.swift | 6 +++++- .../TextFields/InputField/InputField.swift | 4 ---- VDS/Components/Tilelet/Tilelet.swift | 4 ++-- VDS/Components/Toggle/Toggle.swift | 19 ++++++------------- VDS/Components/Toggle/ToggleView.swift | 16 +++------------- VDS/Components/Tooltip/Tooltip.swift | 9 +++------ .../Tooltip/TooltipAlertViewController.swift | 2 +- VDS/Protocols/ViewProtocol.swift | 2 +- 18 files changed, 58 insertions(+), 110 deletions(-) diff --git a/VDS/Classes/Control.swift b/VDS/Classes/Control.swift index cf1a9100..6920ac48 100644 --- a/VDS/Classes/Control.swift +++ b/VDS/Classes/Control.swift @@ -128,12 +128,23 @@ open class Control: UIControl, Handlerable, ViewProtocol, Resettable, UserInfoab /// Update this view based off of property changes open func updateView() { - updateAccessibilityLabel() + updateAccessibility() } /// Used to update any Accessibility properties - open func updateAccessibilityLabel() { + open func updateAccessibility() { + if isSelected { + accessibilityTraits.insert(.selected) + } else { + accessibilityTraits.remove(.selected) + } + if isEnabled { + accessibilityTraits.remove(.notEnabled) + } else { + accessibilityTraits.insert(.notEnabled) + } + } /// Resets to the Controls default values diff --git a/VDS/Classes/SelectorBase.swift b/VDS/Classes/SelectorBase.swift index ffd94ccd..bf66a5c3 100644 --- a/VDS/Classes/SelectorBase.swift +++ b/VDS/Classes/SelectorBase.swift @@ -88,19 +88,8 @@ open class SelectorBase: Control, SelectorControlable { layoutIfNeeded() } - open override func updateAccessibilityLabel() { + open override func updateAccessibility() { + super.updateAccessibility() accessibilityValue = isSelected ? "1" : "0" - if isSelected { - accessibilityTraits.insert(.selected) - } else { - accessibilityTraits.remove(.selected) - } - - if isEnabled { - accessibilityTraits.remove(.notEnabled) - } else { - accessibilityTraits.insert(.notEnabled) - } - accessibilityLabel = isSelected ? "Selected" : "Not Selected" } } diff --git a/VDS/Classes/SelectorGroupHandlerBase.swift b/VDS/Classes/SelectorGroupHandlerBase.swift index d5669538..2575ca2e 100644 --- a/VDS/Classes/SelectorGroupHandlerBase.swift +++ b/VDS/Classes/SelectorGroupHandlerBase.swift @@ -69,18 +69,8 @@ open class SelectorGroupHandlerBase: Control, Changeable { selectorViews.forEach{ $0.reset() } } - open override func updateAccessibilityLabel() { - if isSelected { - accessibilityTraits.insert(.selected) - } else { - accessibilityTraits.remove(.selected) - } - - if isEnabled { - accessibilityTraits.remove(.notEnabled) - } else { - accessibilityTraits.insert(.notEnabled) - } + open override func updateAccessibility() { + super.updateAccessibility() setAccessibilityLabel(for: selectorViews) } } @@ -92,8 +82,8 @@ open class SelectorGroupSelectedHandlerBase: SelectorGroup return selectorViews.filter { $0.isSelected == true }.first } - open override func updateAccessibilityLabel() { - super.updateAccessibilityLabel() + open override func updateAccessibility() { + super.updateAccessibility() if let selectedHandler, let value = selectedHandler.accessibilityValue, let label = selectedHandler.accessibilityLabel { accessibilityValue = "\(label) \(value)" } else { diff --git a/VDS/Classes/SelectorItemBase.swift b/VDS/Classes/SelectorItemBase.swift index c98102fd..fec3eacd 100644 --- a/VDS/Classes/SelectorItemBase.swift +++ b/VDS/Classes/SelectorItemBase.swift @@ -267,24 +267,12 @@ open class SelectorItemBase: Control, Errorable, selectorView.isHighlighted = isHighlighted selectorView.disabled = disabled selectorView.surface = surface - updateAccessibilityLabel() + updateAccessibility() } - open override func updateAccessibilityLabel() { + open override func updateAccessibility() { + super.updateAccessibility() accessibilityValue = isSelected ? "1" : "0" - if isSelected { - accessibilityTraits.insert(.selected) - } else { - accessibilityTraits.remove(.selected) - } - - if isEnabled { - accessibilityTraits.remove(.notEnabled) - } else { - accessibilityTraits.insert(.notEnabled) - } setAccessibilityLabel(for: [label, childLabel, errorLabel]) - - accessibilityLabel = "\(isSelected ? "Selected" : "Not Selected"), \(accessibilityLabel ?? "")" } } diff --git a/VDS/Classes/View.swift b/VDS/Classes/View.swift index b130b56a..199fadcb 100644 --- a/VDS/Classes/View.swift +++ b/VDS/Classes/View.swift @@ -82,12 +82,16 @@ open class View: UIView, Handlerable, ViewProtocol, Resettable, UserInfoable { /// Update this view based off of property changes open func updateView() { - updateAccessibilityLabel() + updateAccessibility() } /// Used to update any Accessibility properties - open func updateAccessibilityLabel() { - + open func updateAccessibility() { + if isEnabled { + accessibilityTraits.remove(.notEnabled) + } else { + accessibilityTraits.insert(.notEnabled) + } } /// Resets to the Views default values diff --git a/VDS/Components/Buttons/Button/ButtonBase.swift b/VDS/Components/Buttons/Button/ButtonBase.swift index ea01479d..637fceb3 100644 --- a/VDS/Components/Buttons/Button/ButtonBase.swift +++ b/VDS/Components/Buttons/Button/ButtonBase.swift @@ -158,10 +158,10 @@ open class ButtonBase: UIButton, Buttonable, Handlerable, ViewProtocol, Resettab open func updateView() { updateLabel() - updateAccessibilityLabel() + updateAccessibility() } - open func updateAccessibilityLabel() { + open func updateAccessibility() { if isEnabled { accessibilityTraits.remove(.notEnabled) } else { diff --git a/VDS/Components/Icon/Icon.swift b/VDS/Components/Icon/Icon.swift index b1cb3c0b..58a712fb 100644 --- a/VDS/Components/Icon/Icon.swift +++ b/VDS/Components/Icon/Icon.swift @@ -102,11 +102,7 @@ open class Icon: View { imageView.image = nil } } - - public override func updateAccessibilityLabel() { - } - private func getImage(for imageName: String) -> UIImage? { return BundleManager.shared.image(for: imageName) diff --git a/VDS/Components/Label/Label.swift b/VDS/Components/Label/Label.swift index 733d858b..b4e77888 100644 --- a/VDS/Components/Label/Label.swift +++ b/VDS/Components/Label/Label.swift @@ -156,7 +156,7 @@ open class Label: UILabel, Handlerable, ViewProtocol, Resettable, UserInfoable { attributedText = mutableText //get accessibility - updateAccessibilityLabel() + updateAccessibility() //force a drawText setNeedsDisplay() @@ -164,7 +164,7 @@ open class Label: UILabel, Handlerable, ViewProtocol, Resettable, UserInfoable { } } - open func updateAccessibilityLabel() { + open func updateAccessibility() { accessibilityLabel = text } diff --git a/VDS/Components/RadioBox/RadioBoxItem.swift b/VDS/Components/RadioBox/RadioBoxItem.swift index 9f674099..db3e03e8 100644 --- a/VDS/Components/RadioBox/RadioBoxItem.swift +++ b/VDS/Components/RadioBox/RadioBoxItem.swift @@ -243,24 +243,14 @@ open class RadioBoxItem: Control, Changeable { //-------------------------------------------------- open override func updateView() { updateLabels() - updateAccessibilityLabel() + updateAccessibility() setNeedsLayout() layoutIfNeeded() } - open override func updateAccessibilityLabel() { + open override func updateAccessibility() { + super.updateAccessibility() accessibilityValue = isSelected ? "1" : "0" - if isSelected { - accessibilityTraits.insert(.selected) - } else { - accessibilityTraits.remove(.selected) - } - - if isEnabled { - accessibilityTraits.remove(.notEnabled) - } else { - accessibilityTraits.insert(.notEnabled) - } if accessibilityLabel == nil { setAccessibilityLabel(for: [textLabel, subTextLabel, subTextRightLabel]) } diff --git a/VDS/Components/RadioSwatch/RadioSwatch.swift b/VDS/Components/RadioSwatch/RadioSwatch.swift index 465aef71..f6651bdd 100644 --- a/VDS/Components/RadioSwatch/RadioSwatch.swift +++ b/VDS/Components/RadioSwatch/RadioSwatch.swift @@ -117,7 +117,7 @@ open class RadioSwatch: Control { layer.setNeedsDisplay() } - public override func updateAccessibilityLabel() { + public override func updateAccessibility() { accessibilityLabel = text } diff --git a/VDS/Components/Tabs/Tabs.swift b/VDS/Components/Tabs/Tabs.swift index 6728700b..5c7cda8c 100644 --- a/VDS/Components/Tabs/Tabs.swift +++ b/VDS/Components/Tabs/Tabs.swift @@ -256,7 +256,11 @@ open class Tabs: View { tabItem.orientation = orientation tabItem.surface = surface tabItem.indicatorPosition = indicatorPosition - tabItem.accessibilityLabel = "\(tabItem.text) \(tabItem.selected ? "selected" : "unselected") \(index+1) of \(tabViews.count)" + 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" } //update the width based on rules diff --git a/VDS/Components/TextFields/InputField/InputField.swift b/VDS/Components/TextFields/InputField/InputField.swift index 6b25c7e1..8ee35f0e 100644 --- a/VDS/Components/TextFields/InputField/InputField.swift +++ b/VDS/Components/TextFields/InputField/InputField.swift @@ -198,10 +198,6 @@ open class InputField: EntryField, UITextFieldDelegate { } } - public override func updateAccessibilityLabel() { - - } - open override func updateHelperLabel(){ //remove first helperLabel.removeFromSuperview() diff --git a/VDS/Components/Tilelet/Tilelet.swift b/VDS/Components/Tilelet/Tilelet.swift index 9cc2e938..80c66ea0 100644 --- a/VDS/Components/Tilelet/Tilelet.swift +++ b/VDS/Components/Tilelet/Tilelet.swift @@ -376,10 +376,10 @@ open class Tilelet: TileContainer { updateIcons() layoutIfNeeded() - updateAccessibilityLabel() + updateAccessibility() } - open override func updateAccessibilityLabel() { + open override func updateAccessibility() { setAccessibilityLabel(for: [badge.label, titleLockup.eyebrowLabel, titleLockup.titleLabel, titleLockup.subTitleLabel]) } } diff --git a/VDS/Components/Toggle/Toggle.swift b/VDS/Components/Toggle/Toggle.swift index 30459205..e7b50206 100644 --- a/VDS/Components/Toggle/Toggle.swift +++ b/VDS/Components/Toggle/Toggle.swift @@ -237,23 +237,16 @@ open class Toggle: Control, Changeable { toggleView.surface = surface toggleView.disabled = disabled toggleView.isOn = isOn - updateAccessibilityLabel() + updateAccessibility() } - open override func updateAccessibilityLabel() { - accessibilityValue = isSelected ? "1" : "0" - if isSelected { - accessibilityTraits.insert(.selected) + open override func updateAccessibility() { + super.updateAccessibility() + if showText { + setAccessibilityLabel(for: [label]) } else { - accessibilityTraits.remove(.selected) + accessibilityLabel = "Toggle" } - - if isEnabled { - accessibilityTraits.remove(.notEnabled) - } else { - accessibilityTraits.insert(.notEnabled) - } - setAccessibilityLabel(for: [label]) } open override var intrinsicContentSize: CGSize { diff --git a/VDS/Components/Toggle/ToggleView.swift b/VDS/Components/Toggle/ToggleView.swift index 1608bb6c..8bc5e03f 100644 --- a/VDS/Components/Toggle/ToggleView.swift +++ b/VDS/Components/Toggle/ToggleView.swift @@ -199,23 +199,13 @@ open class ToggleView: Control, Changeable { //-------------------------------------------------- open override func updateView() { updateToggle() - updateAccessibilityLabel() + updateAccessibility() } - open override func updateAccessibilityLabel() { + open override func updateAccessibility() { + super.updateAccessibility() accessibilityLabel = "Toggle" accessibilityValue = isSelected ? "1" : "0" - if isSelected { - accessibilityTraits.insert(.selected) - } else { - accessibilityTraits.remove(.selected) - } - - if isEnabled { - accessibilityTraits.remove(.notEnabled) - } else { - accessibilityTraits.insert(.notEnabled) - } } } diff --git a/VDS/Components/Tooltip/Tooltip.swift b/VDS/Components/Tooltip/Tooltip.swift index 6d88fca2..c777ee02 100644 --- a/VDS/Components/Tooltip/Tooltip.swift +++ b/VDS/Components/Tooltip/Tooltip.swift @@ -167,12 +167,9 @@ open class Tooltip: Control, TooltipLaunchable { imageView.image = infoImage.withTintColor(imageColor) } - open override func updateAccessibilityLabel() { - if isEnabled { - accessibilityTraits.remove(.notEnabled) - } else { - accessibilityTraits.insert(.notEnabled) - } + open override func updateAccessibility() { + super.updateAccessibility() + var label = title if label == nil { label = content diff --git a/VDS/Components/Tooltip/TooltipAlertViewController.swift b/VDS/Components/Tooltip/TooltipAlertViewController.swift index da461287..cff2bdc2 100644 --- a/VDS/Components/Tooltip/TooltipAlertViewController.swift +++ b/VDS/Components/Tooltip/TooltipAlertViewController.swift @@ -299,7 +299,7 @@ open class TooltipDialog: View, UIScrollViewDelegate { heightConstraint?.constant = contentHeight } - open override func updateAccessibilityLabel() { + open override func updateAccessibility() { var label = Tooltip.accessibleText(for: titleText, content: contentText, closeButtonText: closeButtonText) if !label.isEmpty { label += "," diff --git a/VDS/Protocols/ViewProtocol.swift b/VDS/Protocols/ViewProtocol.swift index a73b83c5..63517b35 100644 --- a/VDS/Protocols/ViewProtocol.swift +++ b/VDS/Protocols/ViewProtocol.swift @@ -12,7 +12,7 @@ public protocol ViewProtocol { // Can setup ui here. Should be called in the initialization functions. func setup() - func updateAccessibilityLabel() + func updateAccessibility() } extension ViewProtocol where Self: UIView { From 090068031e8185d536d34a25005dd3ca88f74a25 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 1 Aug 2023 10:45:40 -0500 Subject: [PATCH 09/20] convert tab to control Signed-off-by: Matt Bruce --- VDS/Components/Tabs/Tab.swift | 40 +++++++++++++++++----------------- VDS/Components/Tabs/Tabs.swift | 23 ++++++------------- 2 files changed, 27 insertions(+), 36 deletions(-) diff --git a/VDS/Components/Tabs/Tab.swift b/VDS/Components/Tabs/Tab.swift index 1b7cda8d..753b9a8d 100644 --- a/VDS/Components/Tabs/Tab.swift +++ b/VDS/Components/Tabs/Tab.swift @@ -12,7 +12,7 @@ import Combine extension Tabs { @objc(VDSTab) - open class Tab: View { + open class Tab: Control { //-------------------------------------------------- // MARK: - Public Properties //-------------------------------------------------- @@ -20,7 +20,7 @@ extension Tabs { open var index: Int = 0 ///label to write out the text - open var label: Label = Label() + open var label: Label = Label().with { $0.isUserInteractionEnabled = false } ///orientation of the tabs 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. 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. 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() } } @@ -71,7 +65,7 @@ extension Tabs { //-------------------------------------------------- // 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 textColorSelectedConfiguration = SurfaceColorConfiguration(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark) private var indicatorColorConfiguration = SurfaceColorConfiguration(VDSColor.paletteRed, VDSColor.elementsPrimaryOndark) @@ -125,7 +119,8 @@ extension Tabs { super.setup() addSubview(label) accessibilityTraits = .button - + isAccessibilityElement = true + label.translatesAutoresizingMaskIntoConstraints = false label.pinTrailing() @@ -149,16 +144,11 @@ extension Tabs { 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() { + super.updateView() + guard !text.isEmpty else { return } //label properties @@ -178,15 +168,25 @@ extension Tabs { setNeedsLayout() } + open override func updateAccessibility() { + super.updateAccessibility() + accessibilityLabel = text + } + open override func layoutSubviews() { super.layoutSubviews() removeBorders() - if selected { + if isSelected { addBorder(side: indicatorSide, width: indicatorWidth, color: indicatorColorConfiguration.getColor(self)) } } + + open override func accessibilityActivate() -> Bool { + sendActions(for: .touchUpInside) + return true + } } } diff --git a/VDS/Components/Tabs/Tabs.swift b/VDS/Components/Tabs/Tabs.swift index 5c7cda8c..59cfda95 100644 --- a/VDS/Components/Tabs/Tabs.swift +++ b/VDS/Components/Tabs/Tabs.swift @@ -211,20 +211,15 @@ open class Tabs: View { let tabItem = Tab() tabItem.size = size tabItem.text = model.text - tabItem.onClick = model.onClick tabItem.width = model.width tabViews.append(tabItem) tabStackView.addArrangedSubview(tabItem) - - tabItem - .publisher(for: UITapGestureRecognizer()) - .sink { [weak self] gesture in - guard let self, let tabItem = gesture.view as? Tab else { return } - if let selectedIndex = self.tabViews.firstIndex(of: tabItem) { - self.selectedIndex = selectedIndex - self.onTabChange?(selectedIndex) - } - }.store(in: &tabItem.subscribers) + tabItem.onClick = { [weak self] tab in + guard let self else { return } + model.onClick?(tab.index) + self.selectedIndex = tab.index + self.onTabChange?(tab.index) + } } setNeedsUpdate() scrollToSelectedIndex(animated: false) @@ -249,17 +244,13 @@ open class Tabs: View { // Update tab appearance based on properties for (index, tabItem) in tabViews.enumerated() { tabItem.size = size - tabItem.selected = selectedIndex == index + tabItem.isSelected = selectedIndex == index tabItem.index = index tabItem.minWidth = minWidth tabItem.textPosition = textPosition tabItem.orientation = orientation tabItem.surface = surface 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" } From 4561050dca1b5614b4bf3b3e24d47a4874133cd8 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 1 Aug 2023 10:45:58 -0500 Subject: [PATCH 10/20] added accessibilityActivate() Signed-off-by: Matt Bruce --- VDS/Components/Toggle/Toggle.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/VDS/Components/Toggle/Toggle.swift b/VDS/Components/Toggle/Toggle.swift index e7b50206..5a93feb1 100644 --- a/VDS/Components/Toggle/Toggle.swift +++ b/VDS/Components/Toggle/Toggle.swift @@ -249,6 +249,11 @@ open class Toggle: Control, Changeable { } } + open override func accessibilityActivate() -> Bool { + sendActions(for: .touchUpInside) + return true + } + open override var intrinsicContentSize: CGSize { if showLabel { label.sizeToFit() From 59f6ed0e7abeba05d2043744cca51f75e840f12c Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 1 Aug 2023 11:14:33 -0500 Subject: [PATCH 11/20] removed code that was in base Signed-off-by: Matt Bruce --- VDS/Components/Tabs/Tab.swift | 5 ----- VDS/Components/Toggle/Toggle.swift | 5 ----- 2 files changed, 10 deletions(-) diff --git a/VDS/Components/Tabs/Tab.swift b/VDS/Components/Tabs/Tab.swift index 753b9a8d..4ec39b4e 100644 --- a/VDS/Components/Tabs/Tab.swift +++ b/VDS/Components/Tabs/Tab.swift @@ -182,11 +182,6 @@ extension Tabs { addBorder(side: indicatorSide, width: indicatorWidth, color: indicatorColorConfiguration.getColor(self)) } } - - open override func accessibilityActivate() -> Bool { - sendActions(for: .touchUpInside) - return true - } } } diff --git a/VDS/Components/Toggle/Toggle.swift b/VDS/Components/Toggle/Toggle.swift index 5a93feb1..e7b50206 100644 --- a/VDS/Components/Toggle/Toggle.swift +++ b/VDS/Components/Toggle/Toggle.swift @@ -249,11 +249,6 @@ open class Toggle: Control, Changeable { } } - open override func accessibilityActivate() -> Bool { - sendActions(for: .touchUpInside) - return true - } - open override var intrinsicContentSize: CGSize { if showLabel { label.sizeToFit() From 8ffbe7f86453ef9b5c2a2fb0a723cc9f0be72119 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 1 Aug 2023 12:59:42 -0500 Subject: [PATCH 12/20] ONEAPP-4684 - (Acessibility) VDS Brand 3.0 Tooltip Signed-off-by: Matt Bruce --- VDS/Components/Tooltip/Tooltip.swift | 2 +- VDS/Components/Tooltip/TooltipAlertViewController.swift | 4 ++-- VDS/SupportingFiles/ReleaseNotes.txt | 4 ++++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/VDS/Components/Tooltip/Tooltip.swift b/VDS/Components/Tooltip/Tooltip.swift index c777ee02..5df97beb 100644 --- a/VDS/Components/Tooltip/Tooltip.swift +++ b/VDS/Components/Tooltip/Tooltip.swift @@ -174,7 +174,7 @@ open class Tooltip: Control, TooltipLaunchable { if label == nil { label = content } - accessibilityHint = "Tooltip" + accessibilityHint = isEnabled ? "Click to open Tooltip." : "" accessibilityValue = "collapsed" if let label { accessibilityLabel = label diff --git a/VDS/Components/Tooltip/TooltipAlertViewController.swift b/VDS/Components/Tooltip/TooltipAlertViewController.swift index cff2bdc2..01aa8f09 100644 --- a/VDS/Components/Tooltip/TooltipAlertViewController.swift +++ b/VDS/Components/Tooltip/TooltipAlertViewController.swift @@ -305,8 +305,8 @@ open class TooltipDialog: View, UIScrollViewDelegate { label += "," } - contentStackView.accessibilityLabel = "\(label) Click on the \(closeButtonText) button to close." - contentStackView.accessibilityHint = "Tooltip" + contentStackView.accessibilityLabel = label + contentStackView.accessibilityHint = "Click on the \(closeButtonText) button to close." contentStackView.accessibilityValue = "expanded" accessibilityElements = [contentStackView, closeButton] } diff --git a/VDS/SupportingFiles/ReleaseNotes.txt b/VDS/SupportingFiles/ReleaseNotes.txt index 418fbd1e..176b0ee4 100644 --- a/VDS/SupportingFiles/ReleaseNotes.txt +++ b/VDS/SupportingFiles/ReleaseNotes.txt @@ -1,3 +1,7 @@ +1.0.35 +======= +- ONEAPP-4684 - (Acessibility) Tooltip + 1.0.34 ======= - Added new spec for Bottom Inset for TextStyle From d0459cfb7dbd6f0026368068e3c36c9e95116d10 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 1 Aug 2023 13:42:04 -0500 Subject: [PATCH 13/20] removed the accessibilityValue for selected 1 : 0 Signed-off-by: Matt Bruce --- VDS/Classes/SelectorBase.swift | 1 - VDS/Classes/SelectorItemBase.swift | 1 - VDS/Components/RadioBox/RadioBoxItem.swift | 1 - VDS/Components/Toggle/ToggleView.swift | 1 - 4 files changed, 4 deletions(-) diff --git a/VDS/Classes/SelectorBase.swift b/VDS/Classes/SelectorBase.swift index bf66a5c3..91935143 100644 --- a/VDS/Classes/SelectorBase.swift +++ b/VDS/Classes/SelectorBase.swift @@ -90,6 +90,5 @@ open class SelectorBase: Control, SelectorControlable { open override func updateAccessibility() { super.updateAccessibility() - accessibilityValue = isSelected ? "1" : "0" } } diff --git a/VDS/Classes/SelectorItemBase.swift b/VDS/Classes/SelectorItemBase.swift index fec3eacd..de49b09a 100644 --- a/VDS/Classes/SelectorItemBase.swift +++ b/VDS/Classes/SelectorItemBase.swift @@ -272,7 +272,6 @@ open class SelectorItemBase: Control, Errorable, open override func updateAccessibility() { super.updateAccessibility() - accessibilityValue = isSelected ? "1" : "0" setAccessibilityLabel(for: [label, childLabel, errorLabel]) } } diff --git a/VDS/Components/RadioBox/RadioBoxItem.swift b/VDS/Components/RadioBox/RadioBoxItem.swift index db3e03e8..9da920ef 100644 --- a/VDS/Components/RadioBox/RadioBoxItem.swift +++ b/VDS/Components/RadioBox/RadioBoxItem.swift @@ -250,7 +250,6 @@ open class RadioBoxItem: Control, Changeable { open override func updateAccessibility() { super.updateAccessibility() - accessibilityValue = isSelected ? "1" : "0" if accessibilityLabel == nil { setAccessibilityLabel(for: [textLabel, subTextLabel, subTextRightLabel]) } diff --git a/VDS/Components/Toggle/ToggleView.swift b/VDS/Components/Toggle/ToggleView.swift index 8bc5e03f..b19afeed 100644 --- a/VDS/Components/Toggle/ToggleView.swift +++ b/VDS/Components/Toggle/ToggleView.swift @@ -205,7 +205,6 @@ open class ToggleView: Control, Changeable { open override func updateAccessibility() { super.updateAccessibility() accessibilityLabel = "Toggle" - accessibilityValue = isSelected ? "1" : "0" } } From a3dfa2efeda9f63927aa4185ce7c11284db88379 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 1 Aug 2023 13:57:59 -0500 Subject: [PATCH 14/20] updated for item count in groups Signed-off-by: Matt Bruce --- VDS/Components/Checkbox/CheckboxGroup.swift | 3 ++- VDS/Components/RadioButton/RadioButtonGroup.swift | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/VDS/Components/Checkbox/CheckboxGroup.swift b/VDS/Components/Checkbox/CheckboxGroup.swift index 0c499e42..03635d4d 100644 --- a/VDS/Components/Checkbox/CheckboxGroup.swift +++ b/VDS/Components/Checkbox/CheckboxGroup.swift @@ -38,13 +38,14 @@ open class CheckboxGroup: SelectorGroupHandlerBase { public var selectorModels: [CheckboxModel]? { didSet { if let selectorModels { - selectorViews = selectorModels.map { model in + selectorViews = selectorModels.enumerated().map { index, model in return CheckboxItem().with { $0.disabled = model.disabled $0.surface = model.surface $0.inputId = model.inputId $0.value = model.value $0.accessibilityLabel = model.accessibileText + $0.accessibilityValue = "item \(index+1) of \(selectorModels.count)" $0.labelText = model.labelText $0.labelTextAttributes = model.labelTextAttributes $0.childText = model.childText diff --git a/VDS/Components/RadioButton/RadioButtonGroup.swift b/VDS/Components/RadioButton/RadioButtonGroup.swift index 9d8f67eb..1ffa55bb 100644 --- a/VDS/Components/RadioButton/RadioButtonGroup.swift +++ b/VDS/Components/RadioButton/RadioButtonGroup.swift @@ -33,13 +33,14 @@ open class RadioButtonGroup: SelectorGroupSelectedHandlerBase { public var selectorModels: [RadioButtonModel]? { didSet { if let selectorModels { - selectorViews = selectorModels.map { model in + selectorViews = selectorModels.enumerated().map { index, model in return RadioButtonItem().with { $0.disabled = model.disabled $0.surface = model.surface $0.inputId = model.inputId $0.value = model.value $0.accessibilityLabel = model.accessibileText + $0.accessibilityValue = "item \(index+1) of \(selectorModels.count)" $0.labelText = model.labelText $0.labelTextAttributes = model.labelTextAttributes $0.childText = model.childText From e6615f9003b1fca668f51b12e31cf8e338fac249 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 1 Aug 2023 14:01:41 -0500 Subject: [PATCH 15/20] updated notes Signed-off-by: Matt Bruce --- VDS/SupportingFiles/ReleaseNotes.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/VDS/SupportingFiles/ReleaseNotes.txt b/VDS/SupportingFiles/ReleaseNotes.txt index 176b0ee4..b80931ed 100644 --- a/VDS/SupportingFiles/ReleaseNotes.txt +++ b/VDS/SupportingFiles/ReleaseNotes.txt @@ -1,6 +1,11 @@ 1.0.35 ======= - ONEAPP-4684 - (Acessibility) Tooltip +- ONEAPP-4681 - (Acessibility) Checkbox +- ONEAPP-4825 - (Acessibility) Radiobutton +- ONEAPP-5104 - (Acessibility) Button +- ONEAPP-4115 - (Acessibility) Tabs + 1.0.34 ======= From e3e5ed68fb2b2e88456a99e818c7522ad2cc173d Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Tue, 1 Aug 2023 14:05:42 -0500 Subject: [PATCH 16/20] updated radiobutton group to deal with the item count label Signed-off-by: Matt Bruce --- VDS/Components/RadioBox/RadioBoxGroup.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/VDS/Components/RadioBox/RadioBoxGroup.swift b/VDS/Components/RadioBox/RadioBoxGroup.swift index d0f8bef2..0742459f 100644 --- a/VDS/Components/RadioBox/RadioBoxGroup.swift +++ b/VDS/Components/RadioBox/RadioBoxGroup.swift @@ -33,9 +33,10 @@ open class RadioBoxGroup: SelectorGroupSelectedHandlerBase { public var selectorModels: [RadioBoxModel]? { didSet { if let selectorModels { - selectorViews = selectorModels.map { model in + selectorViews = selectorModels.enumerated().map { index, model in return RadioBoxItem().with { $0.accessibilityLabel = model.accessibileText + $0.accessibilityValue = "item \(index+1) of \(selectorModels.count)" $0.text = model.text $0.textAttributes = model.textAttributes $0.subText = model.subText From 19f0744cc172494171942164fd56752ff77dddf8 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 2 Aug 2023 09:27:16 -0500 Subject: [PATCH 17/20] titleLockup update for Janet release Signed-off-by: Matt Bruce --- VDS/Components/TitleLockup/TitleLockup.swift | 90 +++++++++++++++++-- .../TitleLockup/TitleLockupTextStyle.swift | 4 + 2 files changed, 85 insertions(+), 9 deletions(-) diff --git a/VDS/Components/TitleLockup/TitleLockup.swift b/VDS/Components/TitleLockup/TitleLockup.swift index 9fd0f6b6..1c197470 100644 --- a/VDS/Components/TitleLockup/TitleLockup.swift +++ b/VDS/Components/TitleLockup/TitleLockup.swift @@ -46,20 +46,57 @@ open class TitleLockup: View { $0.distribution = .fill } + ///This logic applies when the type style and size used for the title and subtitle/eyebrow is exactly the same (not including the type weight). This should be automatically detected. + private var isUniformSize: Bool { + otherStandardStyle.value == titleModel?.standardStyle.value + } + //-------------------------------------------------- // MARK: - Configuration Properties //-------------------------------------------------- // Sizes are from InVision design specs. open var standardStyleConfiguration: StandardStyleConfigurationProvider = StandardStyleConfigurationProvider(styleConfigurations: [ - .init(deviceType: .iPad, - titleStandardStyles: [.titleSmall, .titleMedium], + .init(deviceType: .iPad, + titleStandardStyles: [.bodySmall], spacingConfigurations: [ - .init(otherStandardStyles: [.bodySmall, .bodyMedium, .bodyLarge], - topSpacing: VDSLayout.Spacing.space2X.value, - bottomSpacing: VDSLayout.Spacing.space2X.value) + .init(otherStandardStyles: [.bodySmall], + topSpacing: VDSLayout.Spacing.space1X.value, + bottomSpacing: VDSLayout.Spacing.space1X.value) ]), + .init(deviceType: .iPad, + titleStandardStyles: [.bodyMedium], + spacingConfigurations: [ + .init(otherStandardStyles: [.bodyMedium], + topSpacing: VDSLayout.Spacing.space1X.value, + bottomSpacing: VDSLayout.Spacing.space1X.value) + ]), + + .init(deviceType: .iPad, + titleStandardStyles: [.bodyLarge], + spacingConfigurations: [ + .init(otherStandardStyles: [.bodyLarge], + topSpacing: VDSLayout.Spacing.space1X.value, + bottomSpacing: VDSLayout.Spacing.space1X.value) + ]), + + .init(deviceType: .iPad, + titleStandardStyles: [.titleSmall], + spacingConfigurations: [ + .init(otherStandardStyles: [.bodySmall, .bodyMedium, .bodyLarge, .titleSmall], + topSpacing: VDSLayout.Spacing.space2X.value, + bottomSpacing: VDSLayout.Spacing.space2X.value) + ]), + + .init(deviceType: .iPad, + titleStandardStyles: [.titleMedium], + spacingConfigurations: [ + .init(otherStandardStyles: [.bodySmall, .bodyMedium, .bodyLarge], + topSpacing: VDSLayout.Spacing.space2X.value, + bottomSpacing: VDSLayout.Spacing.space2X.value) + ]), + .init(deviceType: .iPad, titleStandardStyles: [.titleLarge], spacingConfigurations: [ @@ -100,6 +137,30 @@ open class TitleLockup: View { bottomSpacing: VDSLayout.Spacing.space6X.value), ]), + .init(deviceType: .iPhone, + titleStandardStyles: [.bodySmall], + spacingConfigurations: [ + .init(otherStandardStyles: [.bodySmall], + topSpacing: VDSLayout.Spacing.space1X.value, + bottomSpacing: VDSLayout.Spacing.space1X.value) + ]), + + .init(deviceType: .iPhone, + titleStandardStyles: [.bodyMedium], + spacingConfigurations: [ + .init(otherStandardStyles: [.bodyMedium], + topSpacing: VDSLayout.Spacing.space1X.value, + bottomSpacing: VDSLayout.Spacing.space1X.value) + ]), + + .init(deviceType: .iPhone, + titleStandardStyles: [.bodyLarge], + spacingConfigurations: [ + .init(otherStandardStyles: [.bodyLarge], + topSpacing: VDSLayout.Spacing.space1X.value, + bottomSpacing: VDSLayout.Spacing.space1X.value) + ]), + .init(deviceType: .iPhone, titleStandardStyles: [.titleSmall], spacingConfigurations: [ @@ -152,6 +213,10 @@ open class TitleLockup: View { bottomSpacing: VDSLayout.Spacing.space6X.value) ]), ]) + + private var textColorSecondaryConfiguration = SurfaceColorConfiguration(VDSColor.elementsSecondaryOnlight , VDSColor.elementsSecondaryOnlight).eraseToAnyColorable() + + private var textColorPrimaryConfiguration = SurfaceColorConfiguration(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark).eraseToAnyColorable() //-------------------------------------------------- // MARK: - Public Properties @@ -182,6 +247,8 @@ open class TitleLockup: View { open override func setup() { super.setup() + titleLabel.textColorConfiguration = textColorPrimaryConfiguration + accessibilityElements = [eyebrowLabel, titleLabel, subTitleLabel] addSubview(stackView) @@ -223,7 +290,7 @@ open class TitleLockup: View { //-------------------------------------------------- open override func updateView() { super.updateView() - + let allLabelsTextPosition = textPosition.value var eyebrowTextIsEmpty = true var titleTextIsEmpty = true @@ -231,7 +298,7 @@ open class TitleLockup: View { var topSpacing: CGFloat = 0.0 var bottomSpacing: CGFloat = 0.0 - + //get the spacing based on the title style and other style used for eyebrow and subtitle if let titleModel, let config = standardStyleConfiguration.spacing(for: titleModel.standardStyle, otherStandardStyle: otherStandardStyle) { @@ -247,10 +314,15 @@ open class TitleLockup: View { eyebrowLabel.attributes = eyebrowModel.textAttributes eyebrowLabel.numberOfLines = eyebrowModel.numberOfLines eyebrowLabel.surface = surface + if let titleModel, isUniformSize && titleModel.isBold { + eyebrowLabel.textColorConfiguration = textColorSecondaryConfiguration + } else { + eyebrowLabel.textColorConfiguration = textColorPrimaryConfiguration + } } else { eyebrowLabel.reset() } - + if let titleModel, !titleModel.text.isEmpty { titleTextIsEmpty = false titleLabel.textPosition = allLabelsTextPosition @@ -267,11 +339,11 @@ open class TitleLockup: View { subTitleTextIsEmpty = false subTitleLabel.textPosition = allLabelsTextPosition subTitleLabel.textStyle = otherStandardStyle.value.regular + subTitleLabel.textColorConfiguration = subTitleModel.textColor == .secondary ? textColorSecondaryConfiguration : textColorPrimaryConfiguration subTitleLabel.text = subTitleModel.text subTitleLabel.attributes = subTitleModel.textAttributes subTitleLabel.numberOfLines = subTitleModel.numberOfLines subTitleLabel.surface = surface - subTitleLabel.disabled = subTitleModel.textColor == .secondary } else { subTitleLabel.reset() } diff --git a/VDS/Components/TitleLockup/TitleLockupTextStyle.swift b/VDS/Components/TitleLockup/TitleLockupTextStyle.swift index fa2aefba..0b5c7875 100644 --- a/VDS/Components/TitleLockup/TitleLockupTextStyle.swift +++ b/VDS/Components/TitleLockup/TitleLockupTextStyle.swift @@ -23,6 +23,10 @@ extension TitleLockup { case titleMedium case titleSmall + case bodyLarge + case bodyMedium + case bodySmall + public var defaultValue: TextStyle.StandardStyle {.featureXSmall } public var value: TextStyle.StandardStyle { From dba0b2dc4fa4cf000549a7b1ae2bac436df07573 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 2 Aug 2023 10:51:03 -0500 Subject: [PATCH 18/20] updated release Signed-off-by: Matt Bruce --- VDS/SupportingFiles/ReleaseNotes.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VDS/SupportingFiles/ReleaseNotes.txt b/VDS/SupportingFiles/ReleaseNotes.txt index b80931ed..b135fbc6 100644 --- a/VDS/SupportingFiles/ReleaseNotes.txt +++ b/VDS/SupportingFiles/ReleaseNotes.txt @@ -5,7 +5,7 @@ - ONEAPP-4825 - (Acessibility) Radiobutton - ONEAPP-5104 - (Acessibility) Button - ONEAPP-4115 - (Acessibility) Tabs - +- TitleLockup update for Janet release 1.0.34 ======= From f10ea3d5d6b9a1c53217d7602ffab84b38af033b Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 2 Aug 2023 10:54:44 -0500 Subject: [PATCH 19/20] added setNeedsUpdate to textColorConfiguration Signed-off-by: Matt Bruce --- VDS/Components/Label/Label.swift | 2 +- VDS/Components/Tabs/Tab.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/VDS/Components/Label/Label.swift b/VDS/Components/Label/Label.swift index b4e77888..092b48a2 100644 --- a/VDS/Components/Label/Label.swift +++ b/VDS/Components/Label/Label.swift @@ -66,7 +66,7 @@ open class Label: UILabel, Handlerable, ViewProtocol, Resettable, UserInfoable { public var textColorConfiguration: AnyColorable = ViewColorConfiguration().with { $0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forDisabled: true) $0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forDisabled: false) - }.eraseToAnyColorable() + }.eraseToAnyColorable(){ didSet { setNeedsUpdate() }} //-------------------------------------------------- // MARK: - Initializers diff --git a/VDS/Components/Tabs/Tab.swift b/VDS/Components/Tabs/Tab.swift index 4ec39b4e..4720fabe 100644 --- a/VDS/Components/Tabs/Tab.swift +++ b/VDS/Components/Tabs/Tab.swift @@ -155,7 +155,7 @@ extension Tabs { label.text = text label.textStyle = textStyle label.textPosition = textPosition - label.textColor = textColorConfiguration.getColor(self) + label.textColorConfiguration = textColorConfiguration.eraseToAnyColorable() //constaints labelWidthConstraint?.isActive = false From 635d5abe9ffec24fc4c0c58a9657937ae41d0c21 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Wed, 2 Aug 2023 11:05:21 -0500 Subject: [PATCH 20/20] updated titleLockup logic for janet Signed-off-by: Matt Bruce --- VDS/Components/TitleLockup/TitleLockup.swift | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/VDS/Components/TitleLockup/TitleLockup.swift b/VDS/Components/TitleLockup/TitleLockup.swift index 1c197470..ab745a33 100644 --- a/VDS/Components/TitleLockup/TitleLockup.swift +++ b/VDS/Components/TitleLockup/TitleLockup.swift @@ -309,15 +309,27 @@ open class TitleLockup: View { if let eyebrowModel, !eyebrowModel.text.isEmpty { eyebrowTextIsEmpty = false eyebrowLabel.textPosition = allLabelsTextPosition - eyebrowLabel.textStyle = eyebrowModel.isBold ? otherStandardStyle.value.bold : otherStandardStyle.value.regular eyebrowLabel.text = eyebrowModel.text eyebrowLabel.attributes = eyebrowModel.textAttributes eyebrowLabel.numberOfLines = eyebrowModel.numberOfLines eyebrowLabel.surface = surface - if let titleModel, isUniformSize && titleModel.isBold { - eyebrowLabel.textColorConfiguration = textColorSecondaryConfiguration + + //When uniform size is true + if let titleModel, isUniformSize { + if titleModel.isBold { + //When uniform size is true and the title is bold, + //the eyebrow is always regular weight and the secondary color. + eyebrowLabel.textStyle = otherStandardStyle.value.regular + eyebrowLabel.textColorConfiguration = textColorSecondaryConfiguration + } else { + //When uniform size is true and the title is regular weight + //the eyebrow is always bold and uses the primary color. + eyebrowLabel.textStyle = otherStandardStyle.value.bold + eyebrowLabel.textColorConfiguration = textColorPrimaryConfiguration + } } else { eyebrowLabel.textColorConfiguration = textColorPrimaryConfiguration + eyebrowLabel.textStyle = eyebrowModel.isBold ? otherStandardStyle.value.bold : otherStandardStyle.value.regular } } else { eyebrowLabel.reset()