SwiftLint icon indicating copy to clipboard operation
SwiftLint copied to clipboard

Add accessibility_trait_for_button rule

Open rcole34 opened this issue 2 years ago • 4 comments

Similar to the accessibility_label_for_image rule, this rule catches another common mistake developers make in SwiftUI that makes their apps less accessible.

The accessibility button and link traits are used to tell assistive technologies that an element is tappable. When an element has one of these traits, VoiceOver will automatically read "button" or "link" after the element's label to let the user know that they can activate it. When using a UIKit UIButton or SwiftUI Button or Link, the button trait is added by default, but when you manually add a tap gesture recognizer to an element, you need to explicitly add the button or link trait. In most cases the button trait should be used, but for buttons that open a URL in an external browser we use the link trait instead. This rule attempts to catch uses of the SwiftUI .onTapGesture modifier where the .isButton or .isLink trait is not explicitly applied.

Per @rwapp, Android will automatically add the button trait when a tap gesture is applied, but until iOS catches up with that I hope for this rule to help remind more people to add the proper accessibility traits!

rcole34 avatar Jun 04 '22 04:06 rcole34

@jpsim @SimplyDanny here's another proposed rule to help catch more accessibility issues in SwiftUI apps! There were some SourceKittenDictionary extensions for parsing SwiftUI modifiers that I copied over from the accessibility_label_for_image rule since I was trying to keep the extensions private, but let me know if you think it would be better to move some of these extensions to an internal extension file to centralize them. Appreciate your help reviewing this!

rcole34 avatar Jun 04 '22 05:06 rcole34

2 Warnings
:warning: Big PR
:warning: This PR introduced a violation in WordPress: /WordPress/Classes/ViewRelated/Domains/Views/DomainsDashboardView.swift:19:9: warning: Accessibility Trait for Button Violation: All views with tap gestures added should include the .isButton accessibility trait. If a tap opens an external link the .isLink trait should be used instead. (accessibility_trait_for_button)
12 Messages
:book: Linting Aerial with this PR took 1.11s vs 1.12s on main (0% faster)
:book: Linting Alamofire with this PR took 1.39s vs 1.38s on main (0% slower)
:book: Linting Firefox with this PR took 6.08s vs 6.09s on main (0% faster)
:book: Linting Kickstarter with this PR took 8.84s vs 8.8s on main (0% slower)
:book: Linting Moya with this PR took 0.65s vs 0.66s on main (1% faster)
:book: Linting Nimble with this PR took 0.61s vs 0.61s on main (0% slower)
:book: Linting Quick with this PR took 0.3s vs 0.29s on main (3% slower)
:book: Linting Realm with this PR took 10.67s vs 10.48s on main (1% slower)
:book: Linting SourceKitten with this PR took 0.5s vs 0.5s on main (0% slower)
:book: Linting Sourcery with this PR took 2.22s vs 2.21s on main (0% slower)
:book: Linting Swift with this PR took 4.1s vs 4.11s on main (0% faster)
:book: Linting WordPress with this PR took 10.26s vs 10.17s on main (0% slower)

Generated by :no_entry_sign: Danger

SwiftLintBot avatar Jun 04 '22 05:06 SwiftLintBot

Codecov Report

Merging #3989 (93495a3) into master (4382ef4) will decrease coverage by 0.02%. The diff coverage is 87.50%.

@@            Coverage Diff             @@
##           master    #3989      +/-   ##
==========================================
- Coverage   92.53%   92.50%   -0.03%     
==========================================
  Files         446      447       +1     
  Lines       22493    22613     +120     
==========================================
+ Hits        20813    20918     +105     
- Misses       1680     1695      +15     
Impacted Files Coverage Δ
...k/Rules/Lint/AccessibilityTraitForButtonRule.swift 87.28% <87.28%> (ø)
...tFrameworkTests/AutomaticRuleTests.generated.swift 100.00% <100.00%> (ø)

:mega: Codecov can now indicate which changes are the most critical in Pull Requests. Learn more

codecov-commenter avatar Jun 04 '22 05:06 codecov-commenter

@SimplyDanny I tried to make a more generic way to check for modifiers with a given name and arguments that can hopefully scale for other SwiftUI linter rules. Happy to work through some revisions of it if you see room for improvement!

rcole34 avatar Jul 20 '22 23:07 rcole34

Sorry for the late response! Could you please rebase your branch? Notice that the protocol AutomaticTestableRule has been removed. All rules are now automatically tested. The file AutomaticRuleTests.generated.swift has been renamed to GeneratedTests.swift.

SimplyDanny avatar Sep 03 '22 16:09 SimplyDanny