diff --git a/packages/choice-input/src/ChoiceInputMixin.js b/packages/choice-input/src/ChoiceInputMixin.js index 62c3653ec..e85dfa002 100644 --- a/packages/choice-input/src/ChoiceInputMixin.js +++ b/packages/choice-input/src/ChoiceInputMixin.js @@ -16,13 +16,6 @@ export const ChoiceInputMixin = superclass => }; } - get events() { - return { - ...super.events, - _toggleChecked: [() => this, 'user-input-changed'], - }; - } - static get syncObservers() { return { ...super.syncObservers, @@ -104,9 +97,15 @@ export const ChoiceInputMixin = superclass => connectedCallback() { if (super.connectedCallback) super.connectedCallback(); + this.addEventListener('user-input-changed', this._toggleChecked); this._reflectCheckedToCssClass(); } + disconnectedCallback() { + if (super.disconnectedCallback) super.disconnectedCallback(); + this.removeEventListener('user-input-changed', this._toggleChecked); + } + _toggleChecked() { this.choiceChecked = !this.choiceChecked; } diff --git a/packages/field/src/FocusMixin.js b/packages/field/src/FocusMixin.js index 4f6476f34..17f33bc81 100644 --- a/packages/field/src/FocusMixin.js +++ b/packages/field/src/FocusMixin.js @@ -15,13 +15,18 @@ export const FocusMixin = dedupeMixin( }; } - get events() { - return { - ...super.events, - // Listen to focusin instead of focus, because it blurs - _onFocus: [() => this.inputElement, 'focusin'], - _onBlur: [() => this.inputElement, 'focusout'], - }; + connectedCallback() { + super.connectedCallback(); + this._onFocus = this._onFocus.bind(this); + this._onBlur = this._onBlur.bind(this); + this.inputElement.addEventListener('focusin', this._onFocus); + this.inputElement.addEventListener('focusout', this._onBlur); + } + + disconnectedCallback() { + super.disconnectedCallback(); + this.inputElement.removeEventListener('focusin', this._onFocus); + this.inputElement.removeEventListener('focusout', this._onBlur); } /** diff --git a/packages/field/src/FormatMixin.js b/packages/field/src/FormatMixin.js index 135230a2b..8a0301fc2 100644 --- a/packages/field/src/FormatMixin.js +++ b/packages/field/src/FormatMixin.js @@ -90,14 +90,6 @@ export const FormatMixin = dedupeMixin( }; } - get events() { - return { - ...super.events, - _proxyInputEvent: [() => this.inputElement, 'input'], - _onUserInputChanged: [() => this, 'user-input-changed'], - }; - } - /** * === Formatting and parsing ==== * To understand all concepts below, please consult the flow diagrams in the documentation. @@ -288,13 +280,15 @@ export const FormatMixin = dedupeMixin( connectedCallback() { super.connectedCallback(); this._reflectBackFormattedValueToUser = this._reflectBackFormattedValueToUser.bind(this); + this._reflectBackFormattedValueDebounced = () => { // Make sure this is fired after the change event of inputElement, so that formattedValue // is guaranteed to be calculated setTimeout(this._reflectBackFormattedValueToUser); }; this.inputElement.addEventListener(this.formatOn, this._reflectBackFormattedValueDebounced); - + this.inputElement.addEventListener('input', this._proxyInputEvent); + this.addEventListener('user-input-changed', this._onUserInputChanged); // Connect the value found in to the formatting/parsing/serializing loop as a fallback // mechanism. Assume the user uses the value property of the (recommended api) as // the api (this is a downwards sync). @@ -308,6 +302,8 @@ export const FormatMixin = dedupeMixin( disconnectedCallback() { super.disconnectedCallback(); + this.inputElement.removeEventListener('input', this._proxyInputEvent); + this.removeEventListener('user-input-changed', this._onUserInputChanged); this.inputElement.removeEventListener( this.formatOn, this._reflectBackFormattedValueDebounced, diff --git a/packages/field/src/LionField.js b/packages/field/src/LionField.js index d289e3ef9..18225e988 100644 --- a/packages/field/src/LionField.js +++ b/packages/field/src/LionField.js @@ -2,7 +2,6 @@ import { DelegateMixin, SlotMixin } from '@lion/core'; import { LionLitElement } from '@lion/core/src/LionLitElement.js'; import { ElementMixin } from '@lion/core/src/ElementMixin.js'; import { CssClassMixin } from '@lion/core/src/CssClassMixin.js'; -import { EventMixin } from '@lion/core/src/EventMixin.js'; import { ObserverMixin } from '@lion/core/src/ObserverMixin.js'; import { ValidateMixin } from '@lion/validate'; @@ -32,9 +31,7 @@ export class LionField extends FormControlMixin( ValidateMixin( InteractionStateMixin( FormatMixin( - EventMixin( - CssClassMixin(ElementMixin(DelegateMixin(SlotMixin(ObserverMixin(LionLitElement))))), - ), + CssClassMixin(ElementMixin(DelegateMixin(SlotMixin(ObserverMixin(LionLitElement))))), ), ), ), @@ -55,13 +52,6 @@ export class LionField extends FormControlMixin( }; } - get events() { - return { - ...super.events, - _onChange: [() => this.inputElement, 'change'], - }; - } - static get properties() { return { ...super.properties, @@ -106,6 +96,8 @@ export class LionField extends FormControlMixin( Lifecycle */ connectedCallback() { super.connectedCallback(); + this._onChange = this._onChange.bind(this); + this.inputElement.addEventListener('change', this._onChange); this._delegateInitialValueAttr(); // TODO: find a better way to do this this._setDisabledClass(); this.classList.add('form-field'); @@ -120,6 +112,7 @@ export class LionField extends FormControlMixin( }); this.__parentFormGroup.dispatchEvent(event); } + this.inputElement.removeEventListener('change', this._onChange); } /** diff --git a/packages/fieldset/src/LionFieldset.js b/packages/fieldset/src/LionFieldset.js index 2b5973dc5..c0bd020c0 100644 --- a/packages/fieldset/src/LionFieldset.js +++ b/packages/fieldset/src/LionFieldset.js @@ -1,7 +1,6 @@ import { SlotMixin, html } from '@lion/core'; import { LionLitElement } from '@lion/core/src/LionLitElement.js'; import { CssClassMixin } from '@lion/core/src/CssClassMixin.js'; -import { EventMixin } from '@lion/core/src/EventMixin.js'; import { ObserverMixin } from '@lion/core/src/ObserverMixin.js'; import { ValidateMixin } from '@lion/validate'; import { FormControlMixin } from '@lion/field'; @@ -16,7 +15,7 @@ const pascalCase = str => str.charAt(0).toUpperCase() + str.slice(1); * @extends LionLitElement */ export class LionFieldset extends FormControlMixin( - ValidateMixin(EventMixin(CssClassMixin(SlotMixin(ObserverMixin(LionLitElement))))), + ValidateMixin(CssClassMixin(SlotMixin(ObserverMixin(LionLitElement)))), ) { static get properties() { return { @@ -43,18 +42,6 @@ export class LionFieldset extends FormControlMixin( }; } - get events() { - return { - ...super.events, - __validate: [() => this, 'validation-done'], - _updateFocusedClass: [() => this, 'focused-changed'], // TODO: currently not available in InteractionStates - _updateTouchedClass: [() => this, 'touched-changed'], - _updateDirtyClass: [() => this, 'dirty-changed'], - __onFormElementRegister: [() => this, 'form-element-register'], - __onFormElementUnRegister: [() => this, 'form-element-unregister'], - }; - } - get inputElement() { return this; } @@ -118,12 +105,24 @@ export class LionFieldset extends FormControlMixin( connectedCallback() { // eslint-disable-next-line wc/guard-super-call super.connectedCallback(); + this.addEventListener('validation-done', this.__validate); + this.addEventListener('focused-changed', this._updateFocusedClass); + this.addEventListener('touched-changed', this._updateTouchedClass); + this.addEventListener('dirty-changed', this._updateDirtyClass); + this.addEventListener('form-element-register', this.__onFormElementRegister); + this.addEventListener('form-element-unregister', this.__onFormElementUnRegister); this._setRole(); } disconnectedCallback() { // eslint-disable-next-line wc/guard-super-call super.disconnectedCallback(); + this.removeEventListener('validation-done', this.__validate); + this.removeEventListener('focused-changed', this._updateFocusedClass); + this.removeEventListener('touched-changed', this._updateTouchedClass); + this.removeEventListener('dirty-changed', this._updateDirtyClass); + this.removeEventListener('form-element-register', this.__onFormElementRegister); + this.removeEventListener('form-element-unregister', this.__onFormElementUnRegister); if (this.__parentFormGroup) { const event = new CustomEvent('form-element-unregister', { detail: { element: this }, diff --git a/packages/form/src/LionForm.js b/packages/form/src/LionForm.js index 6bad320db..cc70135bc 100644 --- a/packages/form/src/LionForm.js +++ b/packages/form/src/LionForm.js @@ -18,12 +18,16 @@ export class LionForm extends DelegateMixin(LionFieldset) { }; } - get events() { - return { - ...super.events, - _submit: [() => this, 'submit'], - _reset: [() => this, 'reset'], - }; + connectedCallback() { + super.connectedCallback(); + this.addEventListener('submit', this._submit); + this.addEventListener('reset', this._reset); + } + + disconnectedCallback() { + super.disconnectedCallback(); + this.removeEventListener('submit', this._submit); + this.removeEventListener('reset', this._reset); } get formElement() { diff --git a/packages/radio-group/src/LionRadioGroup.js b/packages/radio-group/src/LionRadioGroup.js index af97d0ec4..ab7d471ef 100644 --- a/packages/radio-group/src/LionRadioGroup.js +++ b/packages/radio-group/src/LionRadioGroup.js @@ -25,13 +25,6 @@ import { LionFieldset } from '@lion/fieldset'; */ export class LionRadioGroup extends LionFieldset { - get events() { - return { - ...super.events, - _checkRadioElements: [() => this, 'model-value-changed'], - }; - } - get checkedValue() { const el = this._getCheckedRadioElement(); return el ? el.modelValue.value : ''; @@ -59,9 +52,15 @@ export class LionRadioGroup extends LionFieldset { connectedCallback() { super.connectedCallback(); + this.addEventListener('model-value-changed', this._checkRadioElements); this._setRole('radiogroup'); } + disconnectedCallback() { + super.disconnectedCallback(); + this.removeEventListener('model-value-changed', this._checkRadioElements); + } + _checkRadioElements(ev) { const { target } = ev; if (target.type !== 'radio' || target.choiceChecked === false) return; diff --git a/packages/select/src/LionSelect.js b/packages/select/src/LionSelect.js index e2be4a805..9eaf2b5fd 100644 --- a/packages/select/src/LionSelect.js +++ b/packages/select/src/LionSelect.js @@ -30,11 +30,14 @@ import { LionField } from '@lion/field'; // eslint-disable-next-line no-unused-vars export class LionSelect extends LionField { - get events() { - return { - ...super.events, - _proxyChangeEvent: [() => this.inputElement, 'change'], - }; + connectedCallback() { + super.connectedCallback(); + this.addEventListener('change', this._proxyChangeEvent); + } + + disconnectedCallback() { + super.disconnectedCallback(); + this.removeEventListener('change', this._proxyChangeEvent); } _proxyChangeEvent() {