fix(core): add DisabledMixin to manage disabled

This commit is contained in:
Thomas Allmer 2019-07-25 16:00:29 +02:00 committed by Mikhail Bashkirov
parent 1d4378edb7
commit 0d64792ff5
3 changed files with 151 additions and 0 deletions

View file

@ -51,3 +51,4 @@ export { DelegateMixin } from './src/DelegateMixin.js';
export { DomHelpersMixin } from './src/DomHelpersMixin.js'; export { DomHelpersMixin } from './src/DomHelpersMixin.js';
export { LionSingleton } from './src/LionSingleton.js'; export { LionSingleton } from './src/LionSingleton.js';
export { SlotMixin } from './src/SlotMixin.js'; export { SlotMixin } from './src/SlotMixin.js';
export { DisabledMixin } from './src/DisabledMixin.js';

View file

@ -0,0 +1,64 @@
import { dedupeMixin } from './dedupeMixin.js';
/**
* #DisabledMixin
*
* @polymerMixin
* @mixinFunction
*/
export const DisabledMixin = dedupeMixin(
superclass =>
// eslint-disable-next-line no-shadow
class DisabledMixin extends superclass {
static get properties() {
return {
disabled: {
type: Boolean,
reflect: true,
},
};
}
constructor() {
super();
this.__requestedToBeDisabled = false;
this.__isUserSettingDisabled = true;
this.__restoreDisabledTo = false;
this.disabled = false;
}
makeRequestToBeDisabled() {
if (this.__requestedToBeDisabled === false) {
this.__requestedToBeDisabled = true;
this.__restoreDisabledTo = this.disabled;
this.__internalSetDisabled(true);
}
}
retractRequestToBeDisabled() {
if (this.__requestedToBeDisabled === true) {
this.__requestedToBeDisabled = false;
this.__internalSetDisabled(this.__restoreDisabledTo);
}
}
__internalSetDisabled(value) {
this.__isUserSettingDisabled = false;
this.disabled = value;
this.__isUserSettingDisabled = true;
}
_requestUpdate(name, oldValue) {
super._requestUpdate(name, oldValue);
if (name === 'disabled') {
if (this.__isUserSettingDisabled) {
this.__restoreDisabledTo = this.disabled;
}
if (this.disabled === false && this.__requestedToBeDisabled === true) {
this.__internalSetDisabled(true);
}
}
}
},
);

View file

@ -0,0 +1,86 @@
import { expect, fixture, html } from '@open-wc/testing';
import { LitElement } from '../index.js';
import { DisabledMixin } from '../src/DisabledMixin.js';
describe('DisabledMixin', () => {
before(() => {
class CanBeDisabled extends DisabledMixin(LitElement) {}
customElements.define('can-be-disabled', CanBeDisabled);
});
it('reflects disabled to attribute', async () => {
const el = await fixture(html`
<can-be-disabled></can-be-disabled>
`);
expect(el.hasAttribute('disabled')).to.be.false;
el.disabled = true;
await el.updateComplete;
expect(el.hasAttribute('disabled')).to.be.true;
});
it('can be requested to be disabled', async () => {
const el = await fixture(html`
<can-be-disabled></can-be-disabled>
`);
el.makeRequestToBeDisabled();
expect(el.disabled).to.be.true;
await el.updateComplete;
expect(el.hasAttribute('disabled')).to.be.true;
});
it('will not allow to become enabled after makeRequestToBeDisabled()', async () => {
const el = await fixture(html`
<can-be-disabled></can-be-disabled>
`);
el.makeRequestToBeDisabled();
expect(el.disabled).to.be.true;
el.disabled = false;
expect(el.disabled).to.be.true;
});
it('will stay disabled after retractRequestToBeDisabled() if it was disabled before', async () => {
const el = await fixture(html`
<can-be-disabled disabled></can-be-disabled>
`);
el.makeRequestToBeDisabled();
el.retractRequestToBeDisabled();
expect(el.disabled).to.be.true;
});
it('will become enabled after retractRequestToBeDisabled() if it was enabled before', async () => {
const el = await fixture(html`
<can-be-disabled></can-be-disabled>
`);
el.makeRequestToBeDisabled();
expect(el.disabled).to.be.true;
el.retractRequestToBeDisabled();
expect(el.disabled).to.be.false;
});
it('may allow multiple calls to makeRequestToBeDisabled()', async () => {
const el = await fixture(html`
<can-be-disabled></can-be-disabled>
`);
el.makeRequestToBeDisabled();
el.makeRequestToBeDisabled();
el.retractRequestToBeDisabled();
expect(el.disabled).to.be.false;
});
it('will restore last state after retractRequestToBeDisabled()', async () => {
const el = await fixture(html`
<can-be-disabled></can-be-disabled>
`);
el.makeRequestToBeDisabled();
el.disabled = true;
el.retractRequestToBeDisabled();
expect(el.disabled).to.be.true;
el.makeRequestToBeDisabled();
el.disabled = false;
el.retractRequestToBeDisabled();
expect(el.disabled).to.be.false;
});
});