Skip to content

Commit 334c08f

Browse files
committed
fix: relax a11y-no-noninteractive-element-to-interactive-role warning
sveltejs#8167 introduced the strict version of it - until this is configurable, we should use the relaxed version instead, since many a11y docs actually advise using ul/ol etc
1 parent 0700abe commit 334c08f

File tree

2 files changed

+30
-193
lines changed
  • src/compiler/compile/nodes
  • test/validator/samples/a11y-no-noninteractive-element-to-interactive-role

2 files changed

+30
-193
lines changed

src/compiler/compile/nodes/Element.ts

+30-1
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,35 @@ const input_type_to_implicit_role = new Map([
172172
['url', 'textbox']
173173
]);
174174

175+
/**
176+
* Exceptions to the rule which follows common A11y conventions
177+
* TODO make this configurable by the user
178+
*/
179+
const a11y_non_interactive_element_to_interactive_role_exceptions = {
180+
ul: [
181+
'listbox',
182+
'menu',
183+
'menubar',
184+
'radiogroup',
185+
'tablist',
186+
'tree',
187+
'treegrid',
188+
],
189+
ol: [
190+
'listbox',
191+
'menu',
192+
'menubar',
193+
'radiogroup',
194+
'tablist',
195+
'tree',
196+
'treegrid',
197+
],
198+
li: ['menuitem', 'option', 'row', 'tab', 'treeitem'],
199+
table: ['grid'],
200+
td: ['gridcell'],
201+
fieldset: ['radiogroup', 'presentation'],
202+
};
203+
175204
const combobox_if_list = new Set(['email', 'search', 'tel', 'text', 'url']);
176205

177206
function input_implicit_role(attribute_map: Map<string, Attribute>) {
@@ -651,7 +680,7 @@ export default class Element extends Node {
651680
}
652681

653682
// no-noninteractive-element-to-interactive-role
654-
if (is_non_interactive_element(this.name, attribute_map) && is_interactive_roles(current_role)) {
683+
if (is_non_interactive_element(this.name, attribute_map) && is_interactive_roles(current_role) && !a11y_non_interactive_element_to_interactive_role_exceptions[this.name]?.includes(current_role)) {
655684
component.warn(this, compiler_warnings.a11y_no_noninteractive_element_to_interactive_role(current_role, this.name));
656685
}
657686
});

test/validator/samples/a11y-no-noninteractive-element-to-interactive-role/warnings.json

-192
Original file line numberDiff line numberDiff line change
@@ -622,197 +622,5 @@
622622
"column": 0,
623623
"line": 53
624624
}
625-
},
626-
{
627-
"code": "a11y-no-noninteractive-element-to-interactive-role",
628-
"end": {
629-
"column": 18,
630-
"line": 57
631-
},
632-
"message": "A11y: Non-interactive element <ul> cannot have interactive role 'menu'",
633-
"start": {
634-
"column": 0,
635-
"line": 57
636-
}
637-
},
638-
{
639-
"code": "a11y-no-noninteractive-element-to-interactive-role",
640-
"end": {
641-
"column": 21,
642-
"line": 58
643-
},
644-
"message": "A11y: Non-interactive element <ul> cannot have interactive role 'menubar'",
645-
"start": {
646-
"column": 0,
647-
"line": 58
648-
}
649-
},
650-
{
651-
"code": "a11y-no-noninteractive-element-to-interactive-role",
652-
"end": {
653-
"column": 24,
654-
"line": 59
655-
},
656-
"message": "A11y: Non-interactive element <ul> cannot have interactive role 'radiogroup'",
657-
"start": {
658-
"column": 0,
659-
"line": 59
660-
}
661-
},
662-
{
663-
"code": "a11y-no-noninteractive-element-to-interactive-role",
664-
"end": {
665-
"column": 21,
666-
"line": 60
667-
},
668-
"message": "A11y: Non-interactive element <ul> cannot have interactive role 'tablist'",
669-
"start": {
670-
"column": 0,
671-
"line": 60
672-
}
673-
},
674-
{
675-
"code": "a11y-no-noninteractive-element-to-interactive-role",
676-
"end": {
677-
"column": 18,
678-
"line": 61
679-
},
680-
"message": "A11y: Non-interactive element <ul> cannot have interactive role 'tree'",
681-
"start": {
682-
"column": 0,
683-
"line": 61
684-
}
685-
},
686-
{
687-
"code": "a11y-no-noninteractive-element-to-interactive-role",
688-
"end": {
689-
"column": 22,
690-
"line": 62
691-
},
692-
"message": "A11y: Non-interactive element <ul> cannot have interactive role 'treegrid'",
693-
"start": {
694-
"column": 0,
695-
"line": 62
696-
}
697-
},
698-
{
699-
"code": "a11y-no-noninteractive-element-to-interactive-role",
700-
"end": {
701-
"column": 18,
702-
"line": 64
703-
},
704-
"message": "A11y: Non-interactive element <ol> cannot have interactive role 'menu'",
705-
"start": {
706-
"column": 0,
707-
"line": 64
708-
}
709-
},
710-
{
711-
"code": "a11y-no-noninteractive-element-to-interactive-role",
712-
"end": {
713-
"column": 21,
714-
"line": 65
715-
},
716-
"message": "A11y: Non-interactive element <ol> cannot have interactive role 'menubar'",
717-
"start": {
718-
"column": 0,
719-
"line": 65
720-
}
721-
},
722-
{
723-
"code": "a11y-no-noninteractive-element-to-interactive-role",
724-
"end": {
725-
"column": 24,
726-
"line": 66
727-
},
728-
"message": "A11y: Non-interactive element <ol> cannot have interactive role 'radiogroup'",
729-
"start": {
730-
"column": 0,
731-
"line": 66
732-
}
733-
},
734-
{
735-
"code": "a11y-no-noninteractive-element-to-interactive-role",
736-
"end": {
737-
"column": 21,
738-
"line": 67
739-
},
740-
"message": "A11y: Non-interactive element <ol> cannot have interactive role 'tablist'",
741-
"start": {
742-
"column": 0,
743-
"line": 67
744-
}
745-
},
746-
{
747-
"code": "a11y-no-noninteractive-element-to-interactive-role",
748-
"end": {
749-
"column": 18,
750-
"line": 68
751-
},
752-
"message": "A11y: Non-interactive element <ol> cannot have interactive role 'tree'",
753-
"start": {
754-
"column": 0,
755-
"line": 68
756-
}
757-
},
758-
{
759-
"code": "a11y-no-noninteractive-element-to-interactive-role",
760-
"end": {
761-
"column": 22,
762-
"line": 69
763-
},
764-
"message": "A11y: Non-interactive element <ol> cannot have interactive role 'treegrid'",
765-
"start": {
766-
"column": 0,
767-
"line": 69
768-
}
769-
},
770-
{
771-
"code": "a11y-no-noninteractive-element-to-interactive-role",
772-
"end": {
773-
"column": 17,
774-
"line": 71
775-
},
776-
"message": "A11y: Non-interactive element <li> cannot have interactive role 'tab'",
777-
"start": {
778-
"column": 0,
779-
"line": 71
780-
}
781-
},
782-
{
783-
"code": "a11y-no-noninteractive-element-to-interactive-role",
784-
"end": {
785-
"column": 22,
786-
"line": 72
787-
},
788-
"message": "A11y: Non-interactive element <li> cannot have interactive role 'menuitem'",
789-
"start": {
790-
"column": 0,
791-
"line": 72
792-
}
793-
},
794-
{
795-
"code": "a11y-no-noninteractive-element-to-interactive-role",
796-
"end": {
797-
"column": 17,
798-
"line": 73
799-
},
800-
"message": "A11y: Non-interactive element <li> cannot have interactive role 'row'",
801-
"start": {
802-
"column": 0,
803-
"line": 73
804-
}
805-
},
806-
{
807-
"code": "a11y-no-noninteractive-element-to-interactive-role",
808-
"end": {
809-
"column": 44,
810-
"line": 74
811-
},
812-
"message": "A11y: Non-interactive element <li> cannot have interactive role 'treeitem'",
813-
"start": {
814-
"column": 0,
815-
"line": 74
816-
}
817625
}
818626
]

0 commit comments

Comments
 (0)