@vaadin/field-base
Advanced tools
Comparing version 23.0.0-beta1 to 23.0.0-beta2
{ | ||
"name": "@vaadin/field-base", | ||
"version": "23.0.0-beta1", | ||
"version": "23.0.0-beta2", | ||
"publishConfig": { | ||
@@ -35,3 +35,3 @@ "access": "public" | ||
"@polymer/polymer": "^3.0.0", | ||
"@vaadin/component-base": "23.0.0-beta1", | ||
"@vaadin/component-base": "23.0.0-beta2", | ||
"lit": "^2.0.0" | ||
@@ -44,3 +44,3 @@ }, | ||
}, | ||
"gitHead": "467244b76021176c109df675799b07029b293e58" | ||
"gitHead": "a276f7a0fd00e5459b87267468e0dd0d4fb6f7f3" | ||
} |
@@ -9,2 +9,3 @@ /** | ||
import { FocusMixinClass } from '@vaadin/component-base/src/focus-mixin.js'; | ||
import { TabindexMixinClass } from '@vaadin/component-base/src/tabindex-mixin.js'; | ||
@@ -16,3 +17,7 @@ /** | ||
base: T | ||
): T & Constructor<DelegateFocusMixinClass> & Constructor<DisabledMixinClass> & Constructor<FocusMixinClass>; | ||
): T & | ||
Constructor<DelegateFocusMixinClass> & | ||
Constructor<DisabledMixinClass> & | ||
Constructor<FocusMixinClass> & | ||
Constructor<TabindexMixinClass>; | ||
@@ -19,0 +24,0 @@ export declare class DelegateFocusMixinClass { |
@@ -7,4 +7,4 @@ /** | ||
import { dedupingMixin } from '@polymer/polymer/lib/utils/mixin.js'; | ||
import { DisabledMixin } from '@vaadin/component-base/src/disabled-mixin.js'; | ||
import { FocusMixin } from '@vaadin/component-base/src/focus-mixin.js'; | ||
import { TabindexMixin } from '@vaadin/component-base/src/tabindex-mixin.js'; | ||
@@ -15,8 +15,8 @@ /** | ||
* @polymerMixin | ||
* @mixes DisabledMixin | ||
* @mixes FocusMixin | ||
* @mixes TabindexMixin | ||
*/ | ||
export const DelegateFocusMixin = dedupingMixin( | ||
(superclass) => | ||
class DelegateFocusMixinClass extends FocusMixin(DisabledMixin(superclass)) { | ||
class DelegateFocusMixinClass extends FocusMixin(TabindexMixin(superclass)) { | ||
static get properties() { | ||
@@ -45,2 +45,15 @@ return { | ||
observer: '_focusElementChanged' | ||
}, | ||
/** | ||
* Indicates whether the element can be focused and where it participates in sequential keyboard navigation. | ||
* | ||
* By default, the host element does not have tabindex attribute. Instead, `focusElement` should have it. | ||
* Toggling `tabindex` attribute on the host element propagates its value to `focusElement`. | ||
* | ||
* @protected | ||
*/ | ||
tabindex: { | ||
type: Number, | ||
value: undefined | ||
} | ||
@@ -109,2 +122,3 @@ }; | ||
this._addFocusListeners(element); | ||
this.__forwardTabIndex(this.tabindex); | ||
} else if (oldElement) { | ||
@@ -169,6 +183,8 @@ this._removeFocusListeners(oldElement); | ||
* @param {boolean} disabled | ||
* @param {boolean} oldDisabled | ||
* @protected | ||
* @override | ||
*/ | ||
_disabledChanged(disabled) { | ||
super._disabledChanged(disabled); | ||
_disabledChanged(disabled, oldDisabled) { | ||
super._disabledChanged(disabled, oldDisabled); | ||
@@ -183,3 +199,35 @@ if (this.focusElement) { | ||
} | ||
/** | ||
* Override an observer from `TabindexMixin`. | ||
* Do not call super to remove tabindex attribute | ||
* from the host after it has been forwarded. | ||
* @param {string} tabindex | ||
* @protected | ||
* @override | ||
*/ | ||
_tabindexChanged(tabindex) { | ||
this.__forwardTabIndex(tabindex); | ||
} | ||
/** @private */ | ||
__forwardTabIndex(tabindex) { | ||
if (tabindex !== undefined && this.focusElement) { | ||
this.focusElement.tabIndex = tabindex; | ||
// Preserve tabindex="-1" on the host element | ||
if (tabindex !== -1) { | ||
this.tabindex = undefined; | ||
} | ||
} | ||
if (this.disabled && tabindex) { | ||
// If tabindex attribute was changed while component was disabled | ||
if (tabindex !== -1) { | ||
this.__lastTabIndex = tabindex; | ||
} | ||
this.tabindex = undefined; | ||
} | ||
} | ||
} | ||
); |
@@ -7,3 +7,3 @@ /** | ||
import { ControllerMixin } from '@vaadin/component-base/src/controller-mixin.js'; | ||
import { SlotMixin } from '@vaadin/component-base/src/slot-mixin.js'; | ||
import { ErrorController } from './error-controller.js'; | ||
import { FieldAriaController } from './field-aria-controller.js'; | ||
@@ -20,7 +20,6 @@ import { HelperController } from './helper-controller.js'; | ||
* @mixes LabelMixin | ||
* @mixes SlotMixin | ||
* @mixes ValidateMixin | ||
*/ | ||
export const FieldMixin = (superclass) => | ||
class FieldMixinClass extends ValidateMixin(LabelMixin(ControllerMixin(SlotMixin(superclass)))) { | ||
class FieldMixinClass extends ValidateMixin(LabelMixin(ControllerMixin(superclass))) { | ||
static get properties() { | ||
@@ -43,3 +42,4 @@ return { | ||
errorMessage: { | ||
type: String | ||
type: String, | ||
observer: '_errorMessageChanged' | ||
}, | ||
@@ -61,16 +61,9 @@ | ||
/** @protected */ | ||
get slots() { | ||
return { | ||
...super.slots, | ||
'error-message': () => { | ||
const error = document.createElement('div'); | ||
error.textContent = this.errorMessage; | ||
return error; | ||
} | ||
}; | ||
static get observers() { | ||
return ['_invalidChanged(invalid)', '_requiredChanged(required)']; | ||
} | ||
static get observers() { | ||
return ['_updateErrorMessage(invalid, errorMessage)', '_invalidChanged(invalid)', '_requiredChanged(required)']; | ||
/** @protected */ | ||
get _errorId() { | ||
return this._errorController.errorId; | ||
} | ||
@@ -83,3 +76,3 @@ | ||
get _errorNode() { | ||
return this._getDirectSlotChild('error-message'); | ||
return this._errorController.node; | ||
} | ||
@@ -103,11 +96,9 @@ | ||
// Ensure every instance has unique ID | ||
const uniqueId = (FieldMixinClass._uniqueFieldId = 1 + FieldMixinClass._uniqueFieldId || 0); | ||
this._errorId = `error-${this.localName}-${uniqueId}`; | ||
this._fieldAriaController = new FieldAriaController(this); | ||
this._helperController = new HelperController(this); | ||
this._errorController = new ErrorController(this); | ||
this.addController(this._fieldAriaController); | ||
this.addController(this._helperController); | ||
this.addController(this._errorController); | ||
@@ -125,26 +116,3 @@ this._labelController.addEventListener('label-changed', (event) => { | ||
/** @protected */ | ||
ready() { | ||
super.ready(); | ||
const error = this._errorNode; | ||
if (error) { | ||
error.id = this._errorId; | ||
this.__applyCustomError(); | ||
this._updateErrorMessage(this.invalid, this.errorMessage); | ||
} | ||
} | ||
/** @private */ | ||
__applyCustomError() { | ||
const error = this.__errorMessage; | ||
if (error && error !== this.errorMessage) { | ||
this.errorMessage = error; | ||
delete this.__errorMessage; | ||
} | ||
} | ||
/** @private */ | ||
__helperChanged(hasHelper, helperNode) { | ||
@@ -170,28 +138,7 @@ if (hasHelper) { | ||
/** | ||
* @param {boolean} invalid | ||
* @param {string | null | undefined} errorMessage | ||
* @protected | ||
*/ | ||
_updateErrorMessage(invalid, errorMessage) { | ||
const error = this._errorNode; | ||
if (!error) { | ||
return; | ||
} | ||
// save the custom error message content | ||
if (error.textContent && !errorMessage) { | ||
this.__errorMessage = error.textContent.trim(); | ||
} | ||
const hasError = Boolean(invalid && errorMessage); | ||
error.textContent = hasError ? errorMessage : ''; | ||
error.hidden = !hasError; | ||
this.toggleAttribute('has-error-message', hasError); | ||
// Role alert will make the error message announce immediately | ||
// as the field becomes invalid | ||
if (hasError) { | ||
error.setAttribute('role', 'alert'); | ||
} else { | ||
error.removeAttribute('role'); | ||
} | ||
_errorMessageChanged(errorMessage) { | ||
this._errorController.setErrorMessage(errorMessage); | ||
} | ||
@@ -230,2 +177,4 @@ | ||
_invalidChanged(invalid) { | ||
this._errorController.setInvalid(invalid); | ||
// This timeout is needed to prevent NVDA from announcing the error message twice: | ||
@@ -239,3 +188,3 @@ // 1. Once adding the `[role=alert]` attribute by the `_updateErrorMessage` method (OK). | ||
if (invalid) { | ||
this._fieldAriaController.setErrorId(this._errorId); | ||
this._fieldAriaController.setErrorId(this._errorController.errorId); | ||
} else { | ||
@@ -242,0 +191,0 @@ this._fieldAriaController.setErrorId(null); |
@@ -110,5 +110,3 @@ /** | ||
this.inputElement.focus(); | ||
this.clear(); | ||
this.inputElement.dispatchEvent(new Event('input', { bubbles: true, composed: true })); | ||
this.inputElement.dispatchEvent(new Event('change', { bubbles: true })); | ||
this.__clear(); | ||
} | ||
@@ -141,6 +139,4 @@ | ||
if (event.key === 'Escape' && this.clearButtonVisible) { | ||
const dispatchChange = !!this.value; | ||
this.clear(); | ||
dispatchChange && this.inputElement.dispatchEvent(new Event('change', { bubbles: true })); | ||
if (event.key === 'Escape' && this.clearButtonVisible && !!this.value) { | ||
this.__clear(); | ||
} | ||
@@ -172,2 +168,9 @@ } | ||
} | ||
/** @private */ | ||
__clear() { | ||
this.clear(); | ||
this.inputElement.dispatchEvent(new Event('input', { bubbles: true, composed: true })); | ||
this.inputElement.dispatchEvent(new Event('change', { bubbles: true })); | ||
} | ||
}; |
@@ -7,3 +7,2 @@ /** | ||
import { KeyboardMixin } from '@vaadin/component-base/src/keyboard-mixin.js'; | ||
import { TabindexMixin } from '@vaadin/component-base/src/tabindex-mixin.js'; | ||
import { DelegateFocusMixin } from './delegate-focus-mixin.js'; | ||
@@ -17,6 +16,19 @@ | ||
* @mixes KeyboardMixin | ||
* @mixes TabindexMixin | ||
*/ | ||
export const ShadowFocusMixin = (superClass) => | ||
class ShadowFocusMixinClass extends TabindexMixin(DelegateFocusMixin(KeyboardMixin(superClass))) { | ||
class ShadowFocusMixinClass extends DelegateFocusMixin(KeyboardMixin(superClass)) { | ||
static get properties() { | ||
return { | ||
/** | ||
* Indicates whether the element can be focused and where it participates in sequential keyboard navigation. | ||
* | ||
* @protected | ||
*/ | ||
tabindex: { | ||
type: Number, | ||
value: 0 | ||
} | ||
}; | ||
} | ||
/** | ||
@@ -23,0 +35,0 @@ * Override an event listener from `KeyboardMixin` |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
113977
59
3160
+ Added@vaadin/component-base@23.0.0-beta2(transitive)
- Removed@vaadin/component-base@23.0.0-beta1(transitive)