a11y-lint 0.13.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0c17375bf978e252c281fec08a28a33d0fc22642e49d8aeb5af721454dc967f1
4
- data.tar.gz: 9c89ac25d4163cb4807b31c396114bac42a153ecd7309effb4c77fd19c292c91
3
+ metadata.gz: c80dbcc5dec24d2850b42b84b2bbf512dc792f9c77e41ba4fd778d792c0d750a
4
+ data.tar.gz: aff2c4e3002a785f2f8fbfc5cfe9b115466cc3850299114b8724a82b5c71e52a
5
5
  SHA512:
6
- metadata.gz: 637000bab2f93eacb3a7a799a22e8844c450f7a0da6226cada99866c57accc4bb60a4dfc36bbf7355fa35aaaf155a88bf593caef26c159d8451b0053b83f5105
7
- data.tar.gz: ae04ef4e64f360df93fae63aaa502f08462958f29c3fa5e1f9afe89b263dd0d1a8ec2f0212e35507bb30ddfab7804ae50f88e9278b3e565ca591c889beb739dd
6
+ metadata.gz: c6431784a0c4704f7040953c2ef881678b13e61fee513f639c1ff4de019a4bb1599633638902764dc0cf9f9b25fe553349262639e0f30029033e5498f252f23a
7
+ data.tar.gz: 5b140955d0e2eadc1fefe2314bf85a16f0129d0c2cf569deb507c829ca0cf1aeb633ed601d670e4eef814d1b825a0576a5ad5d41e733bf4c8fceae7b6040f4fe
data/CHANGELOG.md CHANGED
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.14.0] - 2026-04-28
11
+
12
+ ### Changed
13
+
14
+ - **Breaking:** `SimpleFormSelectMissingAccessibleName` is now `SimpleFormInputMissingAccessibleName` and flags any Simple Form `form.input` with `label: false`/`label: ""` that has no `aria-label` or `aria-labelledby` in `input_html`, regardless of input type (WCAG 4.1.2). `as: :hidden` is skipped. Projects that pinned the rule by name in `.a11y-lint.yml` need to update the key
15
+
10
16
  ## [0.13.0] - 2026-04-28
11
17
 
12
18
  ### Added
@@ -29,15 +29,19 @@ In Simple Form, both go inside `input_html`:
29
29
 
30
30
  A placeholder is **not** a label. It disappears as soon as the user types, browsers don't reliably expose it as the accessible name, and it fails users who rely on the prompt staying visible while they fill the field.
31
31
 
32
- ## SimpleFormSelectMissingAccessibleName
33
- {:#simple-form-select-missing-accessible-name}
32
+ ## SimpleFormInputMissingAccessibleName
33
+ {:#simple-form-input-missing-accessible-name}
34
34
 
35
- Applies to: Simple Form `form.input` calls that render a `<select>`either `collection:` is passed, or `as: :select` is set when `label: false` or `label: ""` hides the visible label.
35
+ Applies to: Simple Form `form.input` calls with `label: false` or `label: ""` regardless of input type. `as: :hidden` is skipped, since hidden inputs don't render a visible control.
36
36
 
37
37
  The rule passes when `input_html` provides `aria-label` or `aria-labelledby`. Both hash and string keys are accepted (`aria: { label: "..." }` and `"aria-label" => "..."`).
38
38
 
39
39
  ### Bad
40
40
 
41
+ ```erb
42
+ <%%= form.input :name, label: false %>
43
+ ```
44
+
41
45
  ```erb
42
46
  <%%= form.input :sort_by, collection: opts, label: false %>
43
47
  ```
@@ -48,17 +52,18 @@ The rule passes when `input_html` provides `aria-label` or `aria-labelledby`. Bo
48
52
 
49
53
  ### Good
50
54
 
51
- Render a visible label by removing `label: false`:
55
+ Render a visible label by removing `label: false` and letting Simple Form generate one from the attribute name, or by passing an explicit string:
52
56
 
53
57
  ```erb
58
+ <%%= form.input :name %>
54
59
  <%%= form.input :sort_by, collection: opts, label: "Sort by" %>
55
60
  ```
56
61
 
57
62
  Or, when there's no visible label, supply `aria-label`:
58
63
 
59
64
  ```erb
60
- <%%= form.input :sort_by, collection: opts, label: false,
61
- input_html: { aria: { label: "Sort by" } } %>
65
+ <%%= form.input :name, label: false,
66
+ input_html: { aria: { label: "Name" } } %>
62
67
  ```
63
68
 
64
69
  Or `aria-labelledby` pointing to existing visible text:
@@ -69,19 +74,25 @@ Or `aria-labelledby` pointing to existing visible text:
69
74
  input_html: { aria: { labelledby: "sort-label" } } %>
70
75
  ```
71
76
 
77
+ `as: :hidden` doesn't render a visible control, so it's exempt:
78
+
79
+ ```erb
80
+ <%%= form.input :secret, as: :hidden, label: false %>
81
+ ```
82
+
72
83
  ### Slim equivalent
73
84
 
74
85
  ```slim
75
- = form.input :sort_by, collection: opts, label: false, input_html: { aria: { label: "Sort by" } }
86
+ = form.input :name, label: false, input_html: { aria: { label: "Name" } }
76
87
  ```
77
88
 
78
89
  ## What this rule doesn't catch
79
90
 
80
91
  This rule has a deliberately narrow scope. Things it doesn't flag:
81
92
 
82
- - **Plain `<select>` elements.** The rule targets Simple Form's `form.input` helper. A bare `<select>` with no associated `<label>` is not reported.
93
+ - **Plain HTML form controls.** The rule targets Simple Form's `form.input` helper. A bare `<input>`, `<select>`, or `<textarea>` with no associated `<label>` is not reported.
83
94
  - **Other Simple Form helpers.** `form.select`, `form.association`, and similar helpers aren't checked — only `form.input`.
84
- - **Other input types.** `form.input` rendering as text, email, checkbox, radio, etc. is not checked. Selects are flagged because the `label: false` + missing aria pattern is unusually common for sort and filter dropdowns.
95
+ - **Inputs without `label: false`.** Simple Form auto-generates a label from the attribute name, so `form.input :name` is treated as having a visible label. The rule only kicks in once the label is explicitly suppressed.
85
96
  - **Phlex views.** The rule is a no-op in Phlex by design. The Phlex pipeline only walks receiverless calls, so `form.input(...)` isn't surfaced as a candidate node. Simple Form code embedded inside a Phlex component won't be checked.
86
97
  - **Bad accessible name content.** `aria: { label: "" }` will pass the rule check above (an empty aria-label is its own problem, but not this rule's). `aria: { label: "select" }` will pass. The linter checks that an aria attribute is present, not that the value is useful.
87
98
  - **Dynamic accessible names.** `aria: { label: variable }` satisfies the rule even if `variable` is `nil` at runtime.
@@ -3,11 +3,11 @@
3
3
  module A11y
4
4
  module Lint
5
5
  module Rules
6
- # Checks that Simple Form `form.input` calls rendering a select
7
- # (via `collection:` or `as: :select`) with `label: false` /
6
+ # Checks that Simple Form `form.input` calls with `label: false` /
8
7
  # `label: ""` provide an accessible name through `input_html:`
9
- # `aria-label` or `aria-labelledby` (WCAG 4.1.2).
10
- class SimpleFormSelectMissingAccessibleName < NodeRule
8
+ # `aria-label` or `aria-labelledby` (WCAG 4.1.2). Skips
9
+ # `as: :hidden`, which doesn't render a visible control.
10
+ class SimpleFormInputMissingAccessibleName < NodeRule
11
11
  def check
12
12
  return if no_offense?
13
13
 
@@ -18,14 +18,13 @@ module A11y
18
18
 
19
19
  def no_offense?
20
20
  !helper_call ||
21
- !select_like? ||
22
21
  !helper_call.label_hidden? ||
22
+ hidden_input? ||
23
23
  aria_label_in_input_html?
24
24
  end
25
25
 
26
- def select_like?
27
- helper_call.keyword?(:collection) ||
28
- helper_call.keyword_symbol?(:as, :select)
26
+ def hidden_input?
27
+ helper_call.keyword_symbol?(:as, :hidden)
29
28
  end
30
29
 
31
30
  def aria_label_in_input_html?
@@ -53,7 +52,7 @@ module A11y
53
52
 
54
53
  def offense_message
55
54
  <<~MSG.strip
56
- form.input select missing an accessible name \
55
+ form.input missing an accessible name \
57
56
  requires aria-label or aria-labelledby in input_html (WCAG 4.1.2)
58
57
  MSG
59
58
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module A11y
4
4
  module Lint
5
- VERSION = "0.13.0"
5
+ VERSION = "0.14.0"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: a11y-lint
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.0
4
+ version: 0.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Abdullah Hashim
@@ -124,7 +124,7 @@ files:
124
124
  - lib/a11y/lint/rules/robust/button_missing_accessible_name.rb
125
125
  - lib/a11y/lint/rules/robust/button_tag_missing_accessible_name.rb
126
126
  - lib/a11y/lint/rules/robust/link_to_missing_accessible_name.rb
127
- - lib/a11y/lint/rules/robust/simple_form_select_missing_accessible_name.rb
127
+ - lib/a11y/lint/rules/robust/simple_form_input_missing_accessible_name.rb
128
128
  - lib/a11y/lint/slim_node.rb
129
129
  - lib/a11y/lint/slim_runner.rb
130
130
  - lib/a11y/lint/version.rb