From 5cd9452df9f03db816d9cb6aaf4f444d6867951b Mon Sep 17 00:00:00 2001 From: Thijs Louisse Date: Tue, 18 Jun 2019 17:42:18 +0200 Subject: [PATCH] fix(input-datepicker): disable invoker when readonly --- .../src/LionInputDatepicker.js | 15 ++++++-- .../input-datepicker/stories/index.stories.js | 13 ++++++- .../test/lion-input-datepicker.test.js | 16 ++++++++ packages/input/src/LionInput.js | 37 ++++++++++++++++--- 4 files changed, 72 insertions(+), 9 deletions(-) diff --git a/packages/input-datepicker/src/LionInputDatepicker.js b/packages/input-datepicker/src/LionInputDatepicker.js index b636c1609..3a88ce2c8 100644 --- a/packages/input-datepicker/src/LionInputDatepicker.js +++ b/packages/input-datepicker/src/LionInputDatepicker.js @@ -197,20 +197,28 @@ export class LionInputDatepicker extends LionInputDate { */ _requestUpdate(name, oldValue) { super._requestUpdate(name, oldValue); + if (name === 'disabled') { this.__delegateDisabled(); } + + if (name === 'disabled' || name === 'readOnly') { + this.__toggleInvokerDisabled(); + } } /** * TODO: [delegation of disabled] move this to LionField (or FormControl) level */ __delegateDisabled() { - if (this.delegations.target()) { - this.delegations.target().disabled = this.disabled; + if (this.inputElement) { + this.inputElement.disabled = this.disabled; } + } + + __toggleInvokerDisabled() { if (this._invokerElement) { - this._invokerElement.disabled = this.disabled; + this._invokerElement.disabled = this.disabled || this.readOnly; } } @@ -220,6 +228,7 @@ export class LionInputDatepicker extends LionInputDate { firstUpdated(c) { super.firstUpdated(c); this.__delegateDisabled(); + this.__toggleInvokerDisabled(); } /** diff --git a/packages/input-datepicker/stories/index.stories.js b/packages/input-datepicker/stories/index.stories.js index 6f0ba74fd..80dbf1565 100644 --- a/packages/input-datepicker/stories/index.stories.js +++ b/packages/input-datepicker/stories/index.stories.js @@ -49,6 +49,17 @@ storiesOf('Forms|Input Datepicker', module) .add( 'Disabled', () => html` - + + `, + ) + .add( + 'Readonly', + () => html` + `, ); diff --git a/packages/input-datepicker/test/lion-input-datepicker.test.js b/packages/input-datepicker/test/lion-input-datepicker.test.js index 059256b4b..5297e96a9 100644 --- a/packages/input-datepicker/test/lion-input-datepicker.test.js +++ b/packages/input-datepicker/test/lion-input-datepicker.test.js @@ -128,6 +128,22 @@ describe('', () => { expect(elObj.overlayController.isShown).to.equal(false); await elObj.openCalendar(); expect(elObj.overlayController.isShown).to.equal(false); + el.disabled = false; + await elObj.openCalendar(); + expect(elObj.overlayController.isShown).to.equal(true); + }); + + it('disables invoker when host input is readonly', async () => { + const el = await fixture(html` + + `); + const elObj = new DatepickerInputObject(el); + expect(elObj.overlayController.isShown).to.equal(false); + await elObj.openCalendar(); + expect(elObj.overlayController.isShown).to.equal(false); + el.readOnly = false; + await elObj.openCalendar(); + expect(elObj.overlayController.isShown).to.equal(true); }); }); diff --git a/packages/input/src/LionInput.js b/packages/input/src/LionInput.js index 5dc702512..2552c9bdd 100644 --- a/packages/input/src/LionInput.js +++ b/packages/input/src/LionInput.js @@ -7,12 +7,21 @@ import { LionField } from '@lion/field'; * @extends LionField */ export class LionInput extends LionField { - get delegations() { + static get properties() { return { - ...super.delegations, - target: () => this.inputElement, - properties: [...super.delegations.properties, 'readOnly'], - attributes: [...super.delegations.attributes, 'readonly'], + ...super.properties, + /** + * A Boolean attribute which, if present, indicates that the user should not be able to edit + * the value of the input. The difference between disabled and readonly is that read-only + * controls can still function, whereas disabled controls generally do not function as + * controls until they are enabled. + * + * (From: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-readonly) + */ + readOnly: { + type: Boolean, + attribute: 'readonly', + }, }; } @@ -30,4 +39,22 @@ export class LionInput extends LionField { }, }; } + + _requestUpdate(name, oldValue) { + super._requestUpdate(name, oldValue); + if (name === 'readOnly') { + this.__delegateReadOnly(); + } + } + + firstUpdated(c) { + super.firstUpdated(c); + this.__delegateReadOnly(); + } + + __delegateReadOnly() { + if (this.inputElement) { + this.inputElement.readOnly = this.readOnly; + } + } }