Skip to content

Commit

Permalink
refactor: change focus-ring condition (#65)
Browse files Browse the repository at this point in the history
  • Loading branch information
web-padawan authored Sep 23, 2020
1 parent b4ee15d commit fb90387
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 54 deletions.
30 changes: 8 additions & 22 deletions test/control-state.html
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@
});
});

describe('_tabPressed and focus-ring', () => {
describe('focus-ring', () => {
var focusin = () => {
focusElement.dispatchEvent(new CustomEvent('focusin', {composed: true, bubbles: true}));
};
Expand All @@ -147,20 +147,6 @@
focusElement.dispatchEvent(new CustomEvent('focusout', {composed: true, bubbles: true}));
};

it('should set and unset _tabPressed when press TAB', () => {
MockInteractions.keyDownOn(document.body, 9);
expect(customElement._tabPressed).to.be.true;
MockInteractions.keyUpOn(document.body, 9);
expect(customElement._tabPressed).to.be.false;
});

it('should set and unset _tabPressed when press SHIFT+TAB', () => {
MockInteractions.keyDownOn(document.body, 9, 'shift');
expect(customElement._tabPressed).to.be.true;
MockInteractions.keyUpOn(document.body, 9, 'shift');
expect(customElement._tabPressed).to.be.false;
});

it('should set _isShiftTabbing when pressing shift-tab', () => {
const event = MockInteractions.keyboardEventFor('keydown', 9, 'shift');
customElement.dispatchEvent(event);
Expand All @@ -179,13 +165,6 @@
expect(customElement._isShiftTabbing).not.to.be.ok;
});

it('should not change _tabPressed on any other key except TAB', () => {
MockInteractions.keyDownOn(document.body, 65);
expect(customElement._tabPressed).to.be.false;
MockInteractions.keyUpOn(document.body, 65);
expect(customElement._tabPressed).to.be.false;
});

it('should set the focus-ring attribute when TAB is pressed and focus is received', () => {
MockInteractions.keyDownOn(document.body, 9);
focusin();
Expand All @@ -202,6 +181,13 @@
expect(customElement.hasAttribute('focus-ring')).to.be.false;
});

it('should not set the focus-ring attribute when mousedown happens after keydown', () => {
MockInteractions.keyDownOn(document.body, 9);
document.body.dispatchEvent(new MouseEvent('mousedown'));
focusin();
expect(customElement.hasAttribute('focus-ring')).to.be.false;
});

it('should refocus the field', (done) => {
customElement.dispatchEvent(new CustomEvent('focusin'));
MockInteractions.keyDownOn(customElement, 9, 'shift');
Expand Down
57 changes: 25 additions & 32 deletions vaadin-control-state-mixin.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,29 @@
-->

<script>
(function() {
// We consider the keyboard to be active if the window has received a keydown
// event since the last mousedown event.
let keyboardActive = false;

// Listen for top-level keydown and mousedown events.
// Use capture phase so we detect events even if they're handled.
window.addEventListener(
'keydown',
() => {
keyboardActive = true;
},
{capture: true}
);

window.addEventListener(
'mousedown',
() => {
keyboardActive = false;
},
{capture: true}
);

/**
* @namespace Vaadin
*/
Expand Down Expand Up @@ -161,19 +184,6 @@
this.setAttribute('focus-ring', '');
});
}

this._boundKeydownListener = this._bodyKeydownListener.bind(this);
this._boundKeyupListener = this._bodyKeyupListener.bind(this);
}

/**
* @protected
*/
connectedCallback() {
super.connectedCallback();

document.body.addEventListener('keydown', this._boundKeydownListener, true);
document.body.addEventListener('keyup', this._boundKeyupListener, true);
}

/**
Expand All @@ -182,9 +192,6 @@
disconnectedCallback() {
super.disconnectedCallback();

document.body.removeEventListener('keydown', this._boundKeydownListener, true);
document.body.removeEventListener('keyup', this._boundKeyupListener, true);

// in non-Chrome browsers, blur does not fire on the element when it is disconnected.
// reproducible in `<vaadin-date-picker>` when closing on `Cancel` or `Today` click.
if (this.hasAttribute('focused')) {
Expand All @@ -205,28 +212,13 @@

// focus-ring is true when the element was focused from the keyboard.
// Focus Ring [A11ycasts]: https://youtu.be/ilj2P5-5CjI
if (focused && this._tabPressed) {
if (focused && keyboardActive) {
this.setAttribute('focus-ring', '');
} else {
this.removeAttribute('focus-ring');
}
}

/**
* @param {KeyboardEvent} e
* @private
*/
_bodyKeydownListener(e) {
this._tabPressed = e.keyCode === 9;
}

/**
* @private
*/
_bodyKeyupListener() {
this._tabPressed = false;
}

/**
* Any element extending this mixin is required to implement this getter.
* It returns the actual focusable element in the component.
Expand Down Expand Up @@ -325,4 +317,5 @@
}
}
};
})();
</script>

0 comments on commit fb90387

Please sign in to comment.