-
Notifications
You must be signed in to change notification settings - Fork 296
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(input-stepper): add aria-valuemin, aria-valuemax and an option t… #2423
Changes from 3 commits
bb584d8
a60c1a0
f9833a7
4046dc7
71f1d7c
0f9cff9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@lion/ui': minor | ||
--- | ||
|
||
[input-stepper] add aria-valuemin, aria-valuemax and an option to set aria-valuetext |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,6 +36,10 @@ export class LionInputStepper extends LocalizeMixin(LionInput) { | |
type: Number, | ||
reflect: true, | ||
}, | ||
valueText: { | ||
type: Object, | ||
attribute: 'value-text', | ||
}, | ||
step: { | ||
type: Number, | ||
reflect: true, | ||
|
@@ -66,6 +70,11 @@ export class LionInputStepper extends LocalizeMixin(LionInput) { | |
this.formatter = formatNumber; | ||
this.min = Infinity; | ||
this.max = Infinity; | ||
/** | ||
* The aria-valuetext attribute defines the human-readable text alternative of aria-valuenow. | ||
* @type {[ Number: String] | []} | ||
gerjanvangeest marked this conversation as resolved.
Show resolved
Hide resolved
|
||
*/ | ||
this.valueText = []; | ||
gerjanvangeest marked this conversation as resolved.
Show resolved
Hide resolved
|
||
this.step = 1; | ||
this.values = { | ||
max: this.max, | ||
|
@@ -110,15 +119,29 @@ export class LionInputStepper extends LocalizeMixin(LionInput) { | |
if (changedProperties.has('min')) { | ||
this._inputNode.min = `${this.min}`; | ||
this.values.min = this.min; | ||
if (this.min !== Infinity) { | ||
this.setAttribute('aria-valuemin', `${this.min}`); | ||
} else { | ||
this.removeAttribute('aria-valuemin'); | ||
} | ||
this.__toggleSpinnerButtonsState(); | ||
} | ||
|
||
if (changedProperties.has('max')) { | ||
this._inputNode.max = `${this.max}`; | ||
this.values.max = this.max; | ||
if (this.max !== Infinity) { | ||
this.setAttribute('aria-valuemax', `${this.max}`); | ||
} else { | ||
this.removeAttribute('aria-valuemax'); | ||
} | ||
this.__toggleSpinnerButtonsState(); | ||
} | ||
|
||
if (changedProperties.has('valueText')) { | ||
this._updateAriaAttributes(); | ||
} | ||
|
||
if (changedProperties.has('step')) { | ||
this._inputNode.step = `${this.step}`; | ||
this.values.step = this.step; | ||
|
@@ -193,8 +216,8 @@ export class LionInputStepper extends LocalizeMixin(LionInput) { | |
*/ | ||
__toggleSpinnerButtonsState() { | ||
const { min, max } = this.values; | ||
const decrementButton = this.__getSlot('prefix'); | ||
const incrementButton = this.__getSlot('suffix'); | ||
const decrementButton = /** @type {HTMLButtonElement} */ (this.__getSlot('prefix')); | ||
const incrementButton = /** @type {HTMLButtonElement} */ (this.__getSlot('suffix')); | ||
const disableIncrementor = this.currentValue >= max && max !== Infinity; | ||
const disableDecrementor = this.currentValue <= min && min !== Infinity; | ||
if ( | ||
|
@@ -205,7 +228,31 @@ export class LionInputStepper extends LocalizeMixin(LionInput) { | |
} | ||
decrementButton[disableDecrementor ? 'setAttribute' : 'removeAttribute']('disabled', 'true'); | ||
incrementButton[disableIncrementor ? 'setAttribute' : 'removeAttribute']('disabled', 'true'); | ||
this.setAttribute('aria-valuenow', `${this.currentValue}`); | ||
|
||
this._updateAriaAttributes(); | ||
} | ||
|
||
/** | ||
* @protected | ||
*/ | ||
_updateAriaAttributes() { | ||
const displayValue = this._inputNode.value; | ||
if (displayValue) { | ||
this.setAttribute('aria-valuenow', `${displayValue}`); | ||
if ( | ||
Object.keys(this.valueText).length !== 0 && | ||
Object.keys(this.valueText).find(key => Number(key) === this.currentValue) | ||
) { | ||
this.setAttribute('aria-valuetext', `${this.valueText[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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we have a source explaining this behaviour + workaround? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-valuenow At least for VoiceOver the same goes up for spinbutton. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks. Maybe add the link in the test as well? |
||
this.setAttribute('aria-valuetext', `${displayValue}`); | ||
} | ||
} else { | ||
this.removeAttribute('aria-valuenow'); | ||
this.removeAttribute('aria-valuetext'); | ||
} | ||
} | ||
|
||
/** | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, can we rename it to
.valueTextMapping
?