diff --git a/packages/ui/components/input-stepper/src/LionInputStepper.js b/packages/ui/components/input-stepper/src/LionInputStepper.js index 13b25361b..5c4017d35 100644 --- a/packages/ui/components/input-stepper/src/LionInputStepper.js +++ b/packages/ui/components/input-stepper/src/LionInputStepper.js @@ -21,6 +21,19 @@ export class LionInputStepper extends LocalizeMixin(LionInput) { .input-group__container > .input-group__input ::slotted(.form-control) { text-align: center; } + + .input-stepper__value { + position: absolute; + width: 1px; + height: 1px; + overflow: hidden; + clip-path: inset(100%); + clip: rect(1px, 1px, 1px, 1px); + white-space: nowrap; + border: 0; + margin: 0; + padding: 0; + } `, ]; } @@ -84,6 +97,7 @@ export class LionInputStepper extends LocalizeMixin(LionInput) { this.__increment = this.__increment.bind(this); this.__decrement = this.__decrement.bind(this); + this.__boundOnEnterButton = this._onEnterButton.bind(this); this.__boundOnLeaveButton = this._onLeaveButton.bind(this); } @@ -94,11 +108,13 @@ export class LionInputStepper extends LocalizeMixin(LionInput) { min: this.min, step: this.step, }; - - this.role = 'spinbutton'; + if (this._inputNode) { + this._inputNode.role = 'spinbutton'; + this._inputNode.setAttribute('aria-live', 'polite'); + this._inputNode.setAttribute('inputmode', 'decimal'); + this._inputNode.setAttribute('autocomplete', 'off'); + } this.addEventListener('keydown', this.__keyDownHandler); - this._inputNode.setAttribute('inputmode', 'decimal'); - this._inputNode.setAttribute('autocomplete', 'off'); this.__setDefaultValidators(); this.__toggleSpinnerButtonsState(); } @@ -120,9 +136,9 @@ export class LionInputStepper extends LocalizeMixin(LionInput) { this._inputNode.min = `${this.min}`; this.values.min = this.min; if (this.min !== Infinity) { - this.setAttribute('aria-valuemin', `${this.min}`); + this._inputNode.setAttribute('aria-valuemin', `${this.min}`); } else { - this.removeAttribute('aria-valuemin'); + this._inputNode.removeAttribute('aria-valuemin'); } this.__toggleSpinnerButtonsState(); } @@ -131,9 +147,9 @@ export class LionInputStepper extends LocalizeMixin(LionInput) { this._inputNode.max = `${this.max}`; this.values.max = this.max; if (this.max !== Infinity) { - this.setAttribute('aria-valuemax', `${this.max}`); + this._inputNode.setAttribute('aria-valuemax', `${this.max}`); } else { - this.removeAttribute('aria-valuemax'); + this._inputNode.removeAttribute('aria-valuemax'); } this.__toggleSpinnerButtonsState(); } @@ -146,14 +162,6 @@ export class LionInputStepper extends LocalizeMixin(LionInput) { this._inputNode.step = `${this.step}`; this.values.step = this.step; } - - if (changedProperties.has('_ariaLabelledNodes')) { - this.__reflectAriaAttrToSpinButton('aria-labelledby', this._ariaLabelledNodes); - } - - if (changedProperties.has('_ariaDescribedNodes')) { - this.__reflectAriaAttrToSpinButton('aria-describedby', this._ariaDescribedNodes); - } } get slots() { @@ -164,22 +172,6 @@ export class LionInputStepper extends LocalizeMixin(LionInput) { }; } - /** - * Based on FormControlMixin __reflectAriaAttr() - * - * Will handle help text, validation feedback and character counter, - * prefix/suffix/before/after (if they contain data-description flag attr). - * Also, contents of id references that will be put in the ._ariaDescribedby property - * from an external context, will be read by a screen reader. - * @param {string} attrName - * @param {Element[]} nodes - * @private - */ - __reflectAriaAttrToSpinButton(attrName, nodes) { - const string = nodes.map(n => n.id).join(' '); - this.setAttribute(attrName, string); - } - /** * Set aria labels and apply validators * @private @@ -228,7 +220,6 @@ export class LionInputStepper extends LocalizeMixin(LionInput) { } decrementButton[disableDecrementor ? 'setAttribute' : 'removeAttribute']('disabled', 'true'); incrementButton[disableIncrementor ? 'setAttribute' : 'removeAttribute']('disabled', 'true'); - this._updateAriaAttributes(); } @@ -238,21 +229,22 @@ export class LionInputStepper extends LocalizeMixin(LionInput) { _updateAriaAttributes() { const displayValue = this._inputNode.value; if (displayValue) { - this.setAttribute('aria-valuenow', `${displayValue}`); + this._inputNode.setAttribute('aria-valuenow', `${displayValue}`); if ( Object.keys(this.valueTextMapping).length !== 0 && Object.keys(this.valueTextMapping).find(key => Number(key) === this.currentValue) ) { - this.setAttribute('aria-valuetext', `${this.valueTextMapping[this.currentValue]}`); + this.__valueText = this.valueTextMapping[this.currentValue]; } else { // VoiceOver announces percentages once the valuemin or valuemax are used. // This can be fixed by setting valuetext to the same value as valuenow // https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-valuenow - this.setAttribute('aria-valuetext', `${displayValue}`); + this.__valueText = displayValue; } + this._inputNode.setAttribute('aria-valuetext', `${this.__valueText}`); } else { - this.removeAttribute('aria-valuenow'); - this.removeAttribute('aria-valuetext'); + this._inputNode.removeAttribute('aria-valuenow'); + this._inputNode.removeAttribute('aria-valuetext'); } } @@ -374,6 +366,7 @@ export class LionInputStepper extends LocalizeMixin(LionInput) {