diff --git a/src/compiler/compile/nodes/Element.ts b/src/compiler/compile/nodes/Element.ts index 7a70e603a7..b76ed875bc 100644 --- a/src/compiler/compile/nodes/Element.ts +++ b/src/compiler/compile/nodes/Element.ts @@ -61,6 +61,11 @@ const a11y_no_onchange = new Set([ 'option' ]); +const a11y_mouse_events = new Set([ + 'onMouseOver', + 'onMouseOut' +]); + const invisible_elements = new Set(['meta', 'html', 'script', 'style']); const valid_modifiers = new Set([ @@ -507,6 +512,24 @@ export default class Element extends Node { } } + if (a11y_mouse_events.has(this.name)) { + if (attribute_map.has('onMouseOver') && !attribute_map.has('onFocus')) { + component.warn(this, { + code: `a11y-mouse-events-have-key-events`, + message: `A11y: onMouseOver must be accompanied by onFocus for accessibility.` + }); + } + + if (attribute_map.has('onMouseOut') && attribute_map.has('onBlur')) { + component.warn(this, { + code: `a11y-mouse-events-have-key-events`, + message: `A11y: onMouseOut must be accompanied by onBlur for accessibility.` + }); + } + + + } + if (a11y_no_onchange.has(this.name)) { if (handlers_map.has('change') && !handlers_map.has('blur')) { component.warn(this, { diff --git a/test/validator/samples/a11y-mouse-events-have-key-events/input.svelte b/test/validator/samples/a11y-mouse-events-have-key-events/input.svelte new file mode 100644 index 0000000000..efdf95a0a1 --- /dev/null +++ b/test/validator/samples/a11y-mouse-events-have-key-events/input.svelte @@ -0,0 +1,4 @@ +
void 0 } /> +
void 0 } /> +
void 0 } onFocus={ () => void 0 } /> +
void 0 } onBlur={ () => void 0 } /> diff --git a/test/validator/samples/a11y-mouse-events-have-key-events/warnings.json b/test/validator/samples/a11y-mouse-events-have-key-events/warnings.json new file mode 100644 index 0000000000..fe51488c70 --- /dev/null +++ b/test/validator/samples/a11y-mouse-events-have-key-events/warnings.json @@ -0,0 +1 @@ +[]