diff --git a/VDS.xcodeproj/project.pbxproj b/VDS.xcodeproj/project.pbxproj index 2f0fee7c..8f6878a0 100644 --- a/VDS.xcodeproj/project.pbxproj +++ b/VDS.xcodeproj/project.pbxproj @@ -102,6 +102,7 @@ EA5F86D02A1F936100BC83E4 /* TabsContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5F86CF2A1F936100BC83E4 /* TabsContainer.swift */; }; EA6642952BCEBF9500D81DC4 /* TextLinkModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA6642942BCEBF9500D81DC4 /* TextLinkModel.swift */; }; EA6F330E2B911E9000BACAB9 /* TextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA6F330D2B911E9000BACAB9 /* TextView.swift */; }; + EA78C7962C00CAC200430AD1 /* Groupable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA78C7952C00CAC200430AD1 /* Groupable.swift */; }; EA81410B2A0E8E3C004F60D2 /* ButtonIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA81410A2A0E8E3C004F60D2 /* ButtonIcon.swift */; }; EA8141102A127066004F60D2 /* UIColor+VDSColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA81410F2A127066004F60D2 /* UIColor+VDSColor.swift */; }; EA89200428AECF4B006B9984 /* UITextField+Publisher.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA89200328AECF4B006B9984 /* UITextField+Publisher.swift */; }; @@ -317,6 +318,7 @@ EA5F86CF2A1F936100BC83E4 /* TabsContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabsContainer.swift; sourceTree = ""; }; EA6642942BCEBF9500D81DC4 /* TextLinkModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextLinkModel.swift; sourceTree = ""; }; EA6F330D2B911E9000BACAB9 /* TextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextView.swift; sourceTree = ""; }; + EA78C7952C00CAC200430AD1 /* Groupable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Groupable.swift; sourceTree = ""; }; EA81410A2A0E8E3C004F60D2 /* ButtonIcon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonIcon.swift; sourceTree = ""; }; EA81410F2A127066004F60D2 /* UIColor+VDSColor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+VDSColor.swift"; sourceTree = ""; }; EA89200328AECF4B006B9984 /* UITextField+Publisher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITextField+Publisher.swift"; sourceTree = ""; }; @@ -718,6 +720,7 @@ EA5E305929510F8B0082B959 /* EnumSubset.swift */, EAF7F0A1289AFB3900B287F5 /* Errorable.swift */, EA3361AE288B26310071C351 /* FormFieldable.swift */, + EA78C7952C00CAC200430AD1 /* Groupable.swift */, EA33624628931B050071C351 /* Initable.swift */, EA471F392A95587500CE9E58 /* LayoutConstraintable.swift */, EA985C7C297DAED300F2FF2E /* Primitive.swift */, @@ -1203,6 +1206,7 @@ EA89200428AECF4B006B9984 /* UITextField+Publisher.swift in Sources */, 18A65A022B96E848006602CC /* Breadcrumbs.swift in Sources */, 1842B1E12BECE7B70021AFCA /* CalendarHeaderReusableView.swift in Sources */, + EA78C7962C00CAC200430AD1 /* Groupable.swift in Sources */, EA0D1C3F2A6AD5E200E5C127 /* Typography+ContentSizeCategory.swift in Sources */, EA5F86C82A1BD99100BC83E4 /* TabModel.swift in Sources */, EA297A5729FB0A360031ED56 /* AppleGuidelinesTouchable.swift in Sources */, diff --git a/VDS/BaseClasses/Selector/SelectorGroupBase.swift b/VDS/BaseClasses/Selector/SelectorGroupBase.swift index 1639ab86..d2632a9d 100644 --- a/VDS/BaseClasses/Selector/SelectorGroupBase.swift +++ b/VDS/BaseClasses/Selector/SelectorGroupBase.swift @@ -39,7 +39,7 @@ extension SelectorGroupSingleSelect { } /// Base Class used for any Grouped Form Control of a Selector Type. -open class SelectorGroupBase: Control, SelectorGroup, Changeable { +open class SelectorGroupBase: Control, SelectorGroup, Changeable { //-------------------------------------------------- // MARK: - Private Properties diff --git a/VDS/BaseClasses/Selector/SelectorItemBase.swift b/VDS/BaseClasses/Selector/SelectorItemBase.swift index 3dd31dda..75f832ed 100644 --- a/VDS/BaseClasses/Selector/SelectorItemBase.swift +++ b/VDS/BaseClasses/Selector/SelectorItemBase.swift @@ -11,7 +11,7 @@ import Combine import VDSTokens /// Base Class used to build out a SelectorControlable control. -open class SelectorItemBase: Control, Errorable, Changeable { +open class SelectorItemBase: Control, Errorable, Changeable, Groupable { //-------------------------------------------------- // MARK: - Initializers @@ -145,6 +145,8 @@ open class SelectorItemBase: Control, Errorable, open var hiddenValue: AnyHashable? { didSet { setNeedsUpdate() } } + open var accessibilityValueText: String? + //-------------------------------------------------- // MARK: - Overrides //-------------------------------------------------- @@ -193,6 +195,7 @@ open class SelectorItemBase: Control, Errorable, open override func updateAccessibility() { super.updateAccessibility() setAccessibilityLabel(for: [selectorView, label, childLabel, errorLabel]) + accessibilityValue = accessibilityValueText } /// Resets to default settings. diff --git a/VDS/Components/Checkbox/CheckboxGroup.swift b/VDS/Components/Checkbox/CheckboxGroup.swift index 1df8d9cd..43b8890d 100644 --- a/VDS/Components/Checkbox/CheckboxGroup.swift +++ b/VDS/Components/Checkbox/CheckboxGroup.swift @@ -48,7 +48,7 @@ open class CheckboxGroup: SelectorGroupBase, SelectorGroupMultiSel $0.inputId = model.inputId $0.hiddenValue = model.value $0.accessibilityLabel = model.accessibileText - $0.accessibilityValue = "item \(index+1) of \(selectorModels.count)" + $0.accessibilityValueText = "item \(index+1) of \(selectorModels.count)" $0.labelText = model.labelText $0.labelTextAttributes = model.labelTextAttributes $0.childText = model.childText diff --git a/VDS/Components/DatePicker/DatePicker.swift b/VDS/Components/DatePicker/DatePicker.swift index ff9fbb06..e169cccf 100644 --- a/VDS/Components/DatePicker/DatePicker.swift +++ b/VDS/Components/DatePicker/DatePicker.swift @@ -101,8 +101,10 @@ open class DatePicker: EntryFieldBase, DatePickerViewControllerDelegate, UIPopov open override func setup() { super.setup() - accessibilityLabel = "Dropdown Select" - + fieldStackView.isAccessibilityElement = true + fieldStackView.accessibilityLabel = "Date Picker" + fieldStackView.accessibilityHint = "Double Tap to open" + // setting color config selectedDateLabel.textColorConfiguration = primaryColorConfiguration.eraseToAnyColorable() @@ -142,6 +144,18 @@ open class DatePicker: EntryFieldBase, DatePickerViewControllerDelegate, UIPopov selectedDateLabel.isEnabled = isEnabled calendarIcon.color = iconColorConfiguration.getColor(self) } + + open override func updateAccessibility() { + super.updateAccessibility() + let label = "Date Picker, \(isReadOnly ? ", read only" : "")" + if let errorText, showError { + fieldStackView.accessibilityLabel = "\(label) ,error, \(errorText)" + } else { + fieldStackView.accessibilityLabel = label + } + fieldStackView.accessibilityHint = isReadOnly || !isEnabled ? "" : "Double tap to open." + fieldStackView.accessibilityValue = value + } /// Resets to default settings. open override func reset() { diff --git a/VDS/Components/DropdownSelect/DropdownSelect.swift b/VDS/Components/DropdownSelect/DropdownSelect.swift index f596f725..54007c5a 100644 --- a/VDS/Components/DropdownSelect/DropdownSelect.swift +++ b/VDS/Components/DropdownSelect/DropdownSelect.swift @@ -132,7 +132,6 @@ open class DropdownSelect: EntryFieldBase { super.setup() fieldStackView.isAccessibilityElement = true - fieldStackView.accessibilityLabel = "Dropdown Select" inlineDisplayLabel.isAccessibilityElement = true dropdownField.width(0) @@ -278,9 +277,14 @@ open class DropdownSelect: EntryFieldBase { open override func updateAccessibility() { super.updateAccessibility() - let selectedOption = selectedOptionLabel.text ?? "" - fieldStackView.accessibilityLabel = "Dropdown Select, \(selectedOption) \(isReadOnly ? ", read only" : "")" + let label = "Dropdown Select, \(isReadOnly ? ", read only" : "")" + if let errorText, showError { + fieldStackView.accessibilityLabel = "\(label) ,error, \(errorText)" + } else { + fieldStackView.accessibilityLabel = label + } fieldStackView.accessibilityHint = isReadOnly || !isEnabled ? "" : "Double tap to open." + fieldStackView.accessibilityValue = value } open override var accessibilityElements: [Any]? { diff --git a/VDS/Components/RadioBox/RadioBoxGroup.swift b/VDS/Components/RadioBox/RadioBoxGroup.swift index e284840b..296ea8ed 100644 --- a/VDS/Components/RadioBox/RadioBoxGroup.swift +++ b/VDS/Components/RadioBox/RadioBoxGroup.swift @@ -56,6 +56,7 @@ open class RadioBoxGroup: SelectorGroupBase, SelectorGroupSingleSe $0.isSelected = model.selected $0.strikethrough = model.strikethrough $0.strikethroughAccessibilityText = model.strikethroughAccessibileText + $0.accessibilityValueText = "item \(index+1) of \(selectorModels.count)" } } } diff --git a/VDS/Components/RadioBox/RadioBoxItem.swift b/VDS/Components/RadioBox/RadioBoxItem.swift index 1a9d613f..f102b7c2 100644 --- a/VDS/Components/RadioBox/RadioBoxItem.swift +++ b/VDS/Components/RadioBox/RadioBoxItem.swift @@ -13,7 +13,7 @@ import VDSTokens /// Radio boxes are single-select components through which a customer indicates a choice /// that are used within a ``RadioBoxGroup``. @objc(VDSRadioBoxItem) -open class RadioBoxItem: Control, Changeable, FormFieldable { +open class RadioBoxItem: Control, Changeable, FormFieldable, Groupable { //-------------------------------------------------- // MARK: - Initializers @@ -130,7 +130,9 @@ open class RadioBoxItem: Control, Changeable, FormFieldable { open var value: AnyHashable? { hiddenValue } open var hiddenValue: AnyHashable? { didSet { setNeedsUpdate() } } - + + open var accessibilityValueText: String? + //-------------------------------------------------- // MARK: - Configuration Properties //-------------------------------------------------- @@ -241,7 +243,15 @@ open class RadioBoxItem: Control, Changeable, FormFieldable { open override func updateAccessibility() { super.updateAccessibility() setAccessibilityLabel(for: [textLabel, subTextLabel, subTextRightLabel]) - accessibilityValue = strikethrough ? strikethroughAccessibilityText : nil + if let accessibilityValueText { + accessibilityValue = strikethrough + ? "\(strikethroughAccessibilityText), \(accessibilityValueText)" + : accessibilityValueText + } else { + accessibilityValue = strikethrough + ? "\(strikethroughAccessibilityText)" + : accessibilityValueText + } } //-------------------------------------------------- diff --git a/VDS/Components/RadioButton/RadioButtonGroup.swift b/VDS/Components/RadioButton/RadioButtonGroup.swift index aecb8034..ca91f3e5 100644 --- a/VDS/Components/RadioButton/RadioButtonGroup.swift +++ b/VDS/Components/RadioButton/RadioButtonGroup.swift @@ -47,7 +47,7 @@ open class RadioButtonGroup: SelectorGroupBase, SelectorGroupSi $0.inputId = model.inputId $0.hiddenValue = model.value $0.accessibilityLabel = model.accessibileText - $0.accessibilityValue = "item \(index+1) of \(selectorModels.count)" + $0.accessibilityValueText = "item \(index+1) of \(selectorModels.count)" $0.labelText = model.labelText $0.labelTextAttributes = model.labelTextAttributes $0.childText = model.childText diff --git a/VDS/Components/Tabs/Tab.swift b/VDS/Components/Tabs/Tab.swift index e96e20d6..2dddef93 100644 --- a/VDS/Components/Tabs/Tab.swift +++ b/VDS/Components/Tabs/Tab.swift @@ -13,7 +13,7 @@ import Combine extension Tabs { @objc(VDSTab) - open class Tab: Control { + open class Tab: Control, Groupable { //-------------------------------------------------- // MARK: - Initializers @@ -89,6 +89,8 @@ extension Tabs { open override var shouldHighlight: Bool { false } + open var accessibilityValueText: String? + //-------------------------------------------------- // MARK: - Configuration //-------------------------------------------------- @@ -178,6 +180,7 @@ extension Tabs { open override func updateAccessibility() { super.updateAccessibility() accessibilityLabel = text + accessibilityValue = accessibilityValueText } open override func layoutSubviews() { diff --git a/VDS/Components/Tabs/Tabs.swift b/VDS/Components/Tabs/Tabs.swift index 225b3f98..ddef2ad6 100644 --- a/VDS/Components/Tabs/Tabs.swift +++ b/VDS/Components/Tabs/Tabs.swift @@ -303,7 +303,7 @@ open class Tabs: View { tabItem.orientation = orientation tabItem.surface = surface tabItem.indicatorPosition = indicatorPosition - tabItem.accessibilityValue = "\(index+1) of \(tabViews.count) Tabs" + tabItem.accessibilityValueText = "\(index+1) of \(tabViews.count) Tabs" } } diff --git a/VDS/Components/TextFields/EntryFieldBase.swift b/VDS/Components/TextFields/EntryFieldBase.swift index 3f37205e..8cedb2f8 100644 --- a/VDS/Components/TextFields/EntryFieldBase.swift +++ b/VDS/Components/TextFields/EntryFieldBase.swift @@ -175,6 +175,7 @@ open class EntryFieldBase: Control, Changeable, FormFieldInternalValidatable { open var statusIcon: Icon = Icon().with { $0.size = .medium + $0.isAccessibilityElement = false } open var labelText: String? { didSet { setNeedsUpdate() } } diff --git a/VDS/Components/TextFields/InputField/InputField.swift b/VDS/Components/TextFields/InputField/InputField.swift index 70842973..70c6ecd0 100644 --- a/VDS/Components/TextFields/InputField/InputField.swift +++ b/VDS/Components/TextFields/InputField/InputField.swift @@ -210,9 +210,21 @@ open class InputField: EntryFieldBase { super.updateView() textField.isEnabled = isEnabled + textField.isUserInteractionEnabled = isEnabled && !isReadOnly textField.textColor = textFieldTextColorConfiguration.getColor(self) } + open override func updateAccessibility() { + super.updateAccessibility() + let label = "\(isReadOnly ? "read only" : "")" + if let errorText, showError { + textField.accessibilityLabel = "\(label) ,error, \(errorText)" + } else { + textField.accessibilityLabel = label + } + textField.accessibilityHint = isReadOnly || !isEnabled ? "" : "Double tap to open." + } + open override func updateErrorLabel() { super.updateErrorLabel() @@ -233,19 +245,12 @@ open class InputField: EntryFieldBase { } else { successLabel.isHidden = true } - } override func updateRules() { super.updateRules() fieldType.handler().appendRules(self) } - - /// Used to update any Accessibility properties. - open override func updateAccessibility() { - super.updateAccessibility() - textField.accessibilityLabel = showError ? "error" : nil - } open override var accessibilityElements: [Any]? { get { diff --git a/VDS/Components/TextFields/InputField/TextField.swift b/VDS/Components/TextFields/InputField/TextField.swift index 182c1660..0488f0b2 100644 --- a/VDS/Components/TextFields/InputField/TextField.swift +++ b/VDS/Components/TextFields/InputField/TextField.swift @@ -7,10 +7,11 @@ import Foundation import UIKit +import Combine @objc(VDSTextField) -open class TextField: UITextField { - +open class TextField: UITextField, ViewProtocol, Errorable { + //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- @@ -28,33 +29,46 @@ open class TextField: UITextField { super.init(coder: coder) initialSetup() } - - var horizontalPadding: CGFloat = 0 - open override func textRect(forBounds bounds: CGRect) -> CGRect { - let rect = super.textRect(forBounds: bounds) - return rect.insetBy(dx: -horizontalPadding, dy: 0) - } - - open override func editingRect(forBounds bounds: CGRect) -> CGRect { - let rect = super.editingRect(forBounds: bounds) - return rect.insetBy(dx: -horizontalPadding, dy: 0) - } - - open override func placeholderRect(forBounds bounds: CGRect) -> CGRect { - let rect = super.placeholderRect(forBounds: bounds) - return rect.insetBy(dx: -horizontalPadding, dy: 0) - } + //-------------------------------------------------- + // MARK: - Combine Properties + //-------------------------------------------------- + /// Set of Subscribers for any Publishers for this Control. + open var subscribers = Set() - open override var isSecureTextEntry: Bool { - didSet { - if isFirstResponder { - _ = becomeFirstResponder() - } + //-------------------------------------------------- + // MARK: - Private Properties + //-------------------------------------------------- + private var initialSetupPerformed = false + + private var horizontalPadding: CGFloat = 0 + + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + /// Key of whether or not updateView() is called in setNeedsUpdate() + open var shouldUpdateView: Bool = true + + open var surface: Surface = .light { didSet { setNeedsUpdate() } } + + open var showError: Bool = false { didSet { setNeedsUpdate() } } + + open var errorText: String? { didSet { setNeedsUpdate() } } + + //-------------------------------------------------- + // MARK: - Lifecycle + //-------------------------------------------------- + open func initialSetup() { + if !initialSetupPerformed { + initialSetupPerformed = true + backgroundColor = .clear + translatesAutoresizingMaskIntoConstraints = false + setup() + setNeedsUpdate() } } - open func initialSetup() { + open func setup() { let accessView = UIView(frame: .init(origin: .zero, size: .init(width: UIScreen.main.bounds.width, height: 44))) accessView.backgroundColor = .white accessView.addBorder(side: .top, width: 1, color: .lightGray) @@ -72,6 +86,50 @@ open class TextField: UITextField { // Resigns the first responder status when 'Done' is tapped resignFirstResponder() } + + open func updateView() {} + + open func updateAccessibility() { + if let errorText, showError { + accessibilityLabel = "error, \(errorText)" + } else { + accessibilityLabel = nil + } + } + + open func reset() { + shouldUpdateView = false + surface = .light + text = nil + shouldUpdateView = true + setNeedsUpdate() + } + + //-------------------------------------------------- + // MARK: - Overrides + //-------------------------------------------------- + open override func textRect(forBounds bounds: CGRect) -> CGRect { + let rect = super.textRect(forBounds: bounds) + return rect.insetBy(dx: -horizontalPadding, dy: 0) + } + + open override func editingRect(forBounds bounds: CGRect) -> CGRect { + let rect = super.editingRect(forBounds: bounds) + return rect.insetBy(dx: -horizontalPadding, dy: 0) + } + + open override func placeholderRect(forBounds bounds: CGRect) -> CGRect { + let rect = super.placeholderRect(forBounds: bounds) + return rect.insetBy(dx: -horizontalPadding, dy: 0) + } + + open override var isSecureTextEntry: Bool { + didSet { + if isFirstResponder { + _ = becomeFirstResponder() + } + } + } open override func becomeFirstResponder() -> Bool { let success = super.becomeFirstResponder() diff --git a/VDS/Components/TextFields/TextArea/TextArea.swift b/VDS/Components/TextFields/TextArea/TextArea.swift index 2333a17f..f03300d1 100644 --- a/VDS/Components/TextFields/TextArea/TextArea.swift +++ b/VDS/Components/TextFields/TextArea/TextArea.swift @@ -193,13 +193,24 @@ open class TextArea: EntryFieldBase { statusIcon.color = iconColorConfiguration.getColor(self) containerView.layer.borderColor = isReadOnly ? readOnlyBorderColorConfiguration.getColor(self).cgColor : borderColorConfiguration.getColor(self).cgColor - textView.isEditable = isReadOnly ? false : true + textView.isEditable = !isEnabled || isReadOnly ? false : true textView.backgroundColor = backgroundColorConfiguration.getColor(self) textView.tintColor = iconColorConfiguration.getColor(self) characterCounterLabel.surface = surface highlightCharacterOverflow() } + open override func updateAccessibility() { + super.updateAccessibility() + let label = "\(isReadOnly ? "read only" : "")" + if let errorText, showError { + textView.accessibilityLabel = "\(label) ,error, \(errorText)" + } else { + textView.accessibilityLabel = label + } + textView.accessibilityHint = isReadOnly || !isEnabled ? "" : "Double tap to open." + } + override func updateRules() { super.updateRules() @@ -223,13 +234,7 @@ open class TextArea: EntryFieldBase { stackView.addArrangedSubview(characterCounterLabel) return stackView } - - /// Used to update any Accessibility properties. - open override func updateAccessibility() { - super.updateAccessibility() - textView.accessibilityLabel = showError ? "error" : nil - } - + open override var accessibilityElements: [Any]? { get { var elements = [Any]() diff --git a/VDS/Components/TextFields/TextArea/TextView.swift b/VDS/Components/TextFields/TextArea/TextView.swift index b1faae53..f0b64f46 100644 --- a/VDS/Components/TextFields/TextArea/TextView.swift +++ b/VDS/Components/TextFields/TextArea/TextView.swift @@ -11,7 +11,7 @@ import Combine import VDSTokens @objc(VDSTextView) -open class TextView: UITextView, ViewProtocol { +open class TextView: UITextView, ViewProtocol, Errorable { //-------------------------------------------------- // MARK: - Initializers @@ -66,6 +66,10 @@ open class TextView: UITextView, ViewProtocol { $0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forDisabled: false) }.eraseToAnyColorable(){ didSet { setNeedsUpdate() }} + open var showError: Bool = false { didSet { setNeedsUpdate() } } + + open var errorText: String? { didSet { setNeedsUpdate() } } + open override var textColor: UIColor? { get { textColorConfiguration.getColor(self) } set { } @@ -102,7 +106,6 @@ open class TextView: UITextView, ViewProtocol { } } - open func setup() { let accessView = UIView(frame: .init(origin: .zero, size: .init(width: UIScreen.main.bounds.width, height: 44))) accessView.backgroundColor = .white @@ -126,7 +129,13 @@ open class TextView: UITextView, ViewProtocol { updateLabel() } - open func updateAccessibility() {} + open func updateAccessibility() { + if let errorText, showError { + accessibilityLabel = "error, \(errorText)" + } else { + accessibilityLabel = nil + } + } open func reset() { shouldUpdateView = false diff --git a/VDS/Components/Tilelet/Tilelet.swift b/VDS/Components/Tilelet/Tilelet.swift index 5dcd5a09..9d67a6a3 100644 --- a/VDS/Components/Tilelet/Tilelet.swift +++ b/VDS/Components/Tilelet/Tilelet.swift @@ -206,12 +206,12 @@ open class Tilelet: TileContainerBase { /// Descriptive Icon positioned in the contentView. open var descriptiveIcon = Icon().with { - $0.isAccessibilityElement = true + $0.isAccessibilityElement = false } /// Directional Icon positioned in the contentView. open var directionalIcon = Icon().with { - $0.isAccessibilityElement = true + $0.isAccessibilityElement = false $0.name = .rightArrow } diff --git a/VDS/Protocols/Groupable.swift b/VDS/Protocols/Groupable.swift new file mode 100644 index 00000000..773362b7 --- /dev/null +++ b/VDS/Protocols/Groupable.swift @@ -0,0 +1,14 @@ +// +// Groupable.swift +// VDS +// +// Created by Matt Bruce on 5/24/24. +// + +import Foundation + +public protocol Groupable: Control { + + /// Property used to add context to the Grouping of a set. + var accessibilityValueText: String? { get set } +} diff --git a/VDS/SupportingFiles/ReleaseNotes.txt b/VDS/SupportingFiles/ReleaseNotes.txt index 2a558285..ac767368 100644 --- a/VDS/SupportingFiles/ReleaseNotes.txt +++ b/VDS/SupportingFiles/ReleaseNotes.txt @@ -1,3 +1,9 @@ +1.0.65 +---------------- +- CXTDT-556996 - RadioboxGroup – Accessibility - Voice over does not render the group position +- CXTDT-560458 - Dropdown & TextArea voiceover behaviour +- CXTDT-560485 - Tilelet - Accessibility + 1.0.64 ---------------- - CXTDT-555846 - DropdownSelect - Tooltip Icon Spacing