-
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 1 commit
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 | ||||
---|---|---|---|---|---|---|
|
@@ -49,6 +49,41 @@ Use `min` and `max` attribute to specify a range. | |||||
></lion-input-stepper> | ||||||
``` | ||||||
|
||||||
### Value text | ||||||
|
||||||
Use the `.valueText` property to override the value with a text. | ||||||
|
||||||
```js preview-story | ||||||
export const valueText = () => { | ||||||
const values = [ | ||||||
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. Since an input step will always have a set of discrete steps and labels (value-texts) belonging to it, maybe a better api would be an index based array corresponding with the amount of steps Otherwise you would have to do this always (there's no use case for providing just one valueText |
||||||
'first', | ||||||
'second', | ||||||
'third', | ||||||
'fourth', | ||||||
'fifth', | ||||||
'sixth', | ||||||
'seventh', | ||||||
'eighth', | ||||||
'ninth', | ||||||
'tenth', | ||||||
]; | ||||||
function onModelValueChanged(ev) { | ||||||
const inputStepper = ev.target; | ||||||
inputStepper.valueText = values[inputStepper.modelValue - 1]; | ||||||
} | ||||||
const format = { locale: 'nl-NL' }; | ||||||
return html` | ||||||
<lion-input-stepper | ||||||
label="Quality of oranges" | ||||||
min="1" | ||||||
max="10" | ||||||
name="value" | ||||||
@model-value-changed="${ev => onModelValueChanged(ev)}" | ||||||
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.
Suggested change
|
||||||
></lion-input-stepper> | ||||||
`; | ||||||
}; | ||||||
``` | ||||||
|
||||||
### Formatting | ||||||
|
||||||
Just like with the `input-amount` you can add the `formatOptions` to format the numbers to your preferences, to a different locale or adjust the amount of fractions. | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,6 +36,11 @@ export class LionInputStepper extends LocalizeMixin(LionInput) { | |
type: Number, | ||
reflect: true, | ||
}, | ||
valueText: { | ||
type: Number, | ||
okadurin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
reflect: true, | ||
gerjanvangeest marked this conversation as resolved.
Show resolved
Hide resolved
|
||
attribute: 'value-text', | ||
}, | ||
step: { | ||
type: Number, | ||
reflect: true, | ||
|
@@ -66,6 +71,8 @@ export class LionInputStepper extends LocalizeMixin(LionInput) { | |
this.formatter = formatNumber; | ||
this.min = Infinity; | ||
this.max = Infinity; | ||
/** @type {string | undefined} */ | ||
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. Maybe some description, so that this will be picked up in our api tables? |
||
this.valueText = undefined; | ||
this.step = 1; | ||
this.values = { | ||
max: this.max, | ||
|
@@ -110,15 +117,36 @@ 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')) { | ||
const displayValue = this._inputNode.value; | ||
if (this.valueText) { | ||
this.setAttribute('aria-valuetext', `${this.valueText}`); | ||
} else if (displayValue) { | ||
this.setAttribute('aria-valuetext', `${displayValue}`); | ||
} else { | ||
this.removeAttribute('aria-valuetext'); | ||
} | ||
} | ||
|
||
if (changedProperties.has('step')) { | ||
this._inputNode.step = `${this.step}`; | ||
this.values.step = this.step; | ||
|
@@ -193,8 +221,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 +233,19 @@ export class LionInputStepper extends LocalizeMixin(LionInput) { | |
} | ||
decrementButton[disableDecrementor ? 'setAttribute' : 'removeAttribute']('disabled', 'true'); | ||
incrementButton[disableIncrementor ? 'setAttribute' : 'removeAttribute']('disabled', 'true'); | ||
this.setAttribute('aria-valuenow', `${this.currentValue}`); | ||
|
||
const displayValue = this._inputNode.value; | ||
if (displayValue) { | ||
this.setAttribute('aria-valuenow', `${displayValue}`); | ||
if (!this.valueText) { | ||
// 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
?