Skip to content

Commit

Permalink
refactor: remove iron-resizable-behavior from avatar-group (#3150)
Browse files Browse the repository at this point in the history
  • Loading branch information
tomivirkki authored Dec 3, 2021
1 parent ee17de4 commit 191badc
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 47 deletions.
1 change: 0 additions & 1 deletion packages/avatar-group/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
],
"dependencies": {
"@polymer/iron-a11y-announcer": "^3.0.0",
"@polymer/iron-resizable-behavior": "^3.0.0",
"@polymer/polymer": "^3.0.0",
"@vaadin/avatar": "23.0.0-alpha1",
"@vaadin/component-base": "23.0.0-alpha1",
Expand Down
17 changes: 13 additions & 4 deletions packages/avatar-group/src/vaadin-avatar-group.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ import '@vaadin/item/src/vaadin-item.js';
import './vaadin-avatar-group-list-box.js';
import './vaadin-avatar-group-overlay.js';
import { IronA11yAnnouncer } from '@polymer/iron-a11y-announcer/iron-a11y-announcer.js';
import { IronResizableBehavior } from '@polymer/iron-resizable-behavior/iron-resizable-behavior.js';
import { mixinBehaviors } from '@polymer/polymer/lib/legacy/class.js';
import { calculateSplices } from '@polymer/polymer/lib/utils/array-splice.js';
import { afterNextRender } from '@polymer/polymer/lib/utils/render-status.js';
import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
Expand Down Expand Up @@ -61,7 +59,7 @@ const MINIMUM_DISPLAYED_AVATARS = 2;
* @mixes ElementMixin
* @mixes ThemableMixin
*/
class AvatarGroup extends ElementMixin(ThemableMixin(mixinBehaviors([IronResizableBehavior], PolymerElement))) {
class AvatarGroup extends ElementMixin(ThemableMixin(PolymerElement)) {
static get template() {
return html`
<style>
Expand Down Expand Up @@ -284,7 +282,8 @@ class AvatarGroup extends ElementMixin(ThemableMixin(mixinBehaviors([IronResizab

this.__boundSetPosition = this.__setPosition.bind(this);

this.addEventListener('iron-resize', this._onResize.bind(this));
this.__resizeObserver = new ResizeObserver(() => this._onResize());
this.__resizeObserver.observe(this);

this._overlayElement = this.shadowRoot.querySelector('vaadin-avatar-group-overlay');

Expand Down Expand Up @@ -594,6 +593,16 @@ class AvatarGroup extends ElementMixin(ThemableMixin(mixinBehaviors([IronResizab
this._overlayElement.style.top = btnRect.bottom + 'px';
}
}

/**
* @deprecated Since Vaadin 23, `notifyResize()` is deprecated. The component uses a
* ResizeObserver internally and doesn't need to be explicitly notified of resizes.
*/
notifyResize() {
console.warn(
`WARNING: Since Vaadin 23, notifyResize() is deprecated. The component uses a ResizeObserver internally and doesn't need to be explicitly notified of resizes.`
);
}
}

customElements.define(AvatarGroup.is, AvatarGroup);
Expand Down
81 changes: 40 additions & 41 deletions packages/avatar-group/test/avatar-group.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,31 @@ import { expect } from '@esm-bundle/chai';
import { enterKeyDown, escKeyDown, fixtureSync, nextRender, spaceKeyDown, tabKeyDown } from '@vaadin/testing-helpers';
import sinon from 'sinon';
import '../vaadin-avatar-group.js';
import { flush } from '@polymer/polymer/lib/utils/flush.js';
import { afterNextRender } from '@polymer/polymer/lib/utils/render-status.js';

/**
* Resolves once the function is invoked on the given object.
*/
function onceInvoked(object, functionName) {
return new Promise((resolve) => {
sinon.replace(object, functionName, (...args) => {
sinon.restore();
object[functionName](...args);
resolve();
});
});
}

/**
* Resolves once the ResizeObserver in AvatarGroup has processed a resize.
*/
async function onceResized(group) {
// Wait for the _onResize function to be invoked by the ResizeObserver
await onceInvoked(group, '_onResize');
// Wait for the debouncer callback in _onResize to invoke __setItemsInView
await onceInvoked(group, '__setItemsInView');
}

describe('avatar-group', () => {
let group;

Expand Down Expand Up @@ -139,17 +161,15 @@ describe('avatar-group', () => {

it('should consider element width when maxItemsVisible is set', async () => {
group.style.width = '100px';
group.notifyResize();
await nextRender(group);
await onceResized(group);

const items = group.shadowRoot.querySelectorAll('vaadin-avatar');
expect(items.length).to.equal(3);
});

it('should set abbr property correctly if maxItemsVisible and width are set', async () => {
group.style.width = '100px';
group.notifyResize();
await nextRender(group);
await onceResized(group);

const overflow = group.$.overflow;
expect(overflow.abbr).to.equal('+3');
Expand All @@ -173,50 +193,39 @@ describe('avatar-group', () => {

it('should render avatars to fit width on resize', async () => {
group.style.width = '110px';
group.dispatchEvent(new CustomEvent('iron-resize'));
await nextRender(group);
flush();
await onceResized(group);
const items = group.shadowRoot.querySelectorAll('vaadin-avatar');
expect(items.length).to.equal(3);
expect(overflow.abbr).to.equal('+3');
});

it('should render avatars using notifyResize', async () => {
group.style.width = '110px';
it('should warn when calling deprecated notifyResize()', () => {
const stub = sinon.stub(console, 'warn');
group.notifyResize();
await nextRender(group);
flush();
const items = group.shadowRoot.querySelectorAll('vaadin-avatar');
expect(items.length).to.equal(3);
expect(overflow.abbr).to.equal('+3');
stub.restore();

expect(stub.calledOnce).to.be.true;
expect(stub.args[0][0]).to.include('WARNING: Since Vaadin 23, notifyResize() is deprecated.');
});

it('should always show at least two avatars', async () => {
group.set('items', group.items.slice(0, 2));
group.style.width = '50px';
group.notifyResize();
await nextRender(group);
flush();
await onceResized(group);
const items = group.shadowRoot.querySelectorAll('vaadin-avatar:not([hidden])');
expect(items.length).to.equal(2);
});

it('should not show overlay with only one avatar', async () => {
group.style.width = '170px';
group.notifyResize();
await nextRender(group);
flush();
await onceResized(group);
expect(overflow.hasAttribute('hidden')).to.be.true;
});

it('should re-render avatars on items change', async () => {
group.style.width = '110px';
group.dispatchEvent(new CustomEvent('iron-resize'));
await nextRender(group);
flush();
group.items = group.items.slice(0, 2);
await nextRender(group);
flush();
await onceResized(group);
expect(overflow.hasAttribute('hidden')).to.be.true;
});

Expand All @@ -227,44 +236,34 @@ describe('avatar-group', () => {
done();
});
group.style.width = '110px';
group.notifyResize();
flush();
nextRender(group).then(() => overflow.click());
onceResized(group).then(() => overflow.click());
});

it('should re-render overflowing avatars on resize', (done) => {
overlay.addEventListener('vaadin-overlay-open', () => {
group.style.width = '75px';
group.notifyResize();
nextRender(group).then(() => {
flush();
onceResized(group).then(() => {
const items = overlay.content.querySelectorAll('[theme="avatar-group-item"]');
expect(items.length).to.equal(4);
done();
});
});
group.style.width = '110px';
group.notifyResize();
nextRender(group).then(() => {
flush();
onceResized(group).then(() => {
overflow.click();
});
});

it('should close overlay on resize when all avatars fit', (done) => {
overlay.addEventListener('vaadin-overlay-open', () => {
group.style.width = '';
group.notifyResize();
flush();
nextRender(group).then(() => {
onceResized(group).then(() => {
expect(overlay.opened).to.be.false;
done();
});
});
group.style.width = '110px';
group.notifyResize();
flush();
nextRender(group).then(() => overflow.click());
onceResized(group).then(() => overflow.click());
});
});

Expand Down
2 changes: 1 addition & 1 deletion wtr-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const { visualRegressionPlugin } = require('@web/test-runner-visual-regression/p
const HIDDEN_WARNINGS = [
'<vaadin-crud> Unable to autoconfigure form because the data structure is unknown. Either specify `include` or ensure at least one item is available beforehand.',
'The <vaadin-grid> needs the total number of items in order to display rows. Set the total number of items to the `size` property, or provide the total number of items in the second argument of the `dataProvider`’s `callback` call.',
/^WARNING: Since Vaadin 22, .* is deprecated.*/,
/^WARNING: Since Vaadin .* is deprecated.*/,
/^WARNING: <template> inside <[^>]+> is deprecated. Use a renderer function instead/
];

Expand Down

0 comments on commit 191badc

Please sign in to comment.