Skip to content

Commit

Permalink
refactor: use FocusMixin instead of custom logic (#2966)
Browse files Browse the repository at this point in the history
  • Loading branch information
web-padawan committed Nov 2, 2021
1 parent 6f9cc93 commit c2d88fd
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 53 deletions.
16 changes: 15 additions & 1 deletion packages/avatar-group/test/avatar-group.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -404,11 +404,25 @@ describe('avatar-group', () => {
overflow.click();
});

it('should not restore focus-ring attribute on close if not set', (done) => {
it('should restore focus-ring attribute on close if closed with keyboard', (done) => {
overlay.addEventListener('vaadin-overlay-open', () => {
const list = overlay.content.querySelector('vaadin-avatar-group-list-box');
escKeyDown(list);

afterNextRender(overlay, () => {
expect(overflow.hasAttribute('focus-ring')).to.be.true;
done();
});
});

overflow.click();
});

it('should not restore focus-ring attribute on close if not set', (done) => {
overlay.addEventListener('vaadin-overlay-open', () => {
const items = overlay.content.querySelectorAll('[theme="avatar-group-item"]');
items[0].click();

afterNextRender(overlay, () => {
expect(overflow.hasAttribute('focus-ring')).to.be.false;
done();
Expand Down
11 changes: 7 additions & 4 deletions packages/avatar/src/vaadin-avatar.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
*/
import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
import { FocusMixin } from '@vaadin/component-base/src/focus-mixin.js';
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';

export interface AvatarI18n {
Expand All @@ -26,15 +27,17 @@ export interface AvatarI18n {
* `abbr` | The abbreviation element
* `icon` | The icon element
*
* The following attributes are exposed for styling:
* The following state attributes are available for styling:
*
* Attribute | Description
* --------- | -----------
* Attribute | Description
* ------------------|-------------
* `focus-ring` | Set when the avatar is focused using the keyboard.
* `focused` | Set when the avatar is focused.
* `has-color-index` | Set when the avatar has `colorIndex` and the corresponding custom CSS property exists.
*
* See [Styling Components](https://vaadin.com/docs/latest/ds/customization/styling-components) documentation.
*/
declare class Avatar extends ElementMixin(ThemableMixin(HTMLElement)) {
declare class Avatar extends FocusMixin(ElementMixin(ThemableMixin(HTMLElement))) {
/**
* The path to the image
*/
Expand Down
56 changes: 8 additions & 48 deletions packages/avatar/src/vaadin-avatar.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,10 @@
*/
import { PolymerElement, html } from '@polymer/polymer/polymer-element.js';
import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
import { FocusMixin } from '@vaadin/component-base/src/focus-mixin.js';
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
import './vaadin-avatar-icons.js';

// 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 Tab keydown and mousedown events.
// Use capture phase so we detect events even if they're handled.
window.addEventListener(
'keydown',
(e) => {
keyboardActive = e.keyCode === 9;
},
true
);

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

/**
* `<vaadin-avatar>` is a Web Component providing avatar displaying functionality.
*
Expand All @@ -46,19 +25,22 @@ window.addEventListener(
* `abbr` | The abbreviation element
* `icon` | The icon element
*
* The following attributes are exposed for styling:
* The following state attributes are available for styling:
*
* Attribute | Description
* --------- | -----------
* Attribute | Description
* ------------------|-------------
* `focus-ring` | Set when the avatar is focused using the keyboard.
* `focused` | Set when the avatar is focused.
* `has-color-index` | Set when the avatar has `colorIndex` and the corresponding custom CSS property exists.
*
* See [Styling Components](https://vaadin.com/docs/latest/ds/customization/styling-components) documentation.
*
* @extends HTMLElement
* @mixes FocusMixin
* @mixes ElementMixin
* @mixes ThemableMixin
*/
class Avatar extends ElementMixin(ThemableMixin(PolymerElement)) {
class Avatar extends FocusMixin(ElementMixin(ThemableMixin(PolymerElement))) {
static get template() {
return html`
<style>
Expand Down Expand Up @@ -236,28 +218,6 @@ class Avatar extends ElementMixin(ThemableMixin(PolymerElement)) {
if (!this.hasAttribute('tabindex')) {
this.setAttribute('tabindex', '0');
}

this.addEventListener('focusin', () => {
this.__setFocused(true);
});

this.addEventListener('focusout', () => {
this.__setFocused(false);
});
}

/** @private */
__setFocused(focused) {
if (focused) {
this.setAttribute('focused', '');

if (keyboardActive) {
this.setAttribute('focus-ring', '');
}
} else {
this.removeAttribute('focused');
this.removeAttribute('focus-ring');
}
}

/** @private */
Expand Down

0 comments on commit c2d88fd

Please sign in to comment.