fix(field): aria ordering within a FormControl
This commit is contained in:
parent
fe9b90973f
commit
73e9dc5849
2 changed files with 59 additions and 4 deletions
|
|
@ -186,8 +186,10 @@ export const FormControlMixin = dedupeMixin(
|
||||||
__reflectAriaAttr(attrName, nodes, reorder) {
|
__reflectAriaAttr(attrName, nodes, reorder) {
|
||||||
if (this._inputNode) {
|
if (this._inputNode) {
|
||||||
if (reorder) {
|
if (reorder) {
|
||||||
|
const insideNodes = nodes.filter(n => this.contains(n));
|
||||||
|
const outsideNodes = nodes.filter(n => !this.contains(n));
|
||||||
// eslint-disable-next-line no-param-reassign
|
// eslint-disable-next-line no-param-reassign
|
||||||
nodes = getAriaElementsInRightDomOrder(nodes);
|
nodes = [...getAriaElementsInRightDomOrder(insideNodes), ...outsideNodes];
|
||||||
}
|
}
|
||||||
const string = nodes.map(n => n.id).join(' ');
|
const string = nodes.map(n => n.id).join(' ');
|
||||||
this._inputNode.setAttribute(attrName, string);
|
this._inputNode.setAttribute(attrName, string);
|
||||||
|
|
@ -464,7 +466,12 @@ export const FormControlMixin = dedupeMixin(
|
||||||
* Meant for Application Developers wanting to add to aria-labelledby attribute.
|
* Meant for Application Developers wanting to add to aria-labelledby attribute.
|
||||||
* @param {Element} element
|
* @param {Element} element
|
||||||
*/
|
*/
|
||||||
addToAriaLabelledBy(element, { idPrefix, reorder } = { reorder: true }) {
|
addToAriaLabelledBy(element, customConfig = {}) {
|
||||||
|
const { idPrefix, reorder } = {
|
||||||
|
reorder: true,
|
||||||
|
...customConfig,
|
||||||
|
};
|
||||||
|
|
||||||
// eslint-disable-next-line no-param-reassign
|
// eslint-disable-next-line no-param-reassign
|
||||||
element.id = element.id || `${idPrefix}-${this._inputId}`;
|
element.id = element.id || `${idPrefix}-${this._inputId}`;
|
||||||
if (!this._ariaLabelledNodes.includes(element)) {
|
if (!this._ariaLabelledNodes.includes(element)) {
|
||||||
|
|
@ -478,7 +485,13 @@ export const FormControlMixin = dedupeMixin(
|
||||||
* Meant for Application Developers wanting to add to aria-describedby attribute.
|
* Meant for Application Developers wanting to add to aria-describedby attribute.
|
||||||
* @param {Element} element
|
* @param {Element} element
|
||||||
*/
|
*/
|
||||||
addToAriaDescribedBy(element, { idPrefix, reorder } = { reorder: true }) {
|
addToAriaDescribedBy(element, customConfig = {}) {
|
||||||
|
const { idPrefix, reorder } = {
|
||||||
|
// chronologically sorts children of host element('this')
|
||||||
|
reorder: true,
|
||||||
|
...customConfig,
|
||||||
|
};
|
||||||
|
|
||||||
// eslint-disable-next-line no-param-reassign
|
// eslint-disable-next-line no-param-reassign
|
||||||
element.id = element.id || `${idPrefix}-${this._inputId}`;
|
element.id = element.id || `${idPrefix}-${this._inputId}`;
|
||||||
if (!this._ariaDescribedNodes.includes(element)) {
|
if (!this._ariaDescribedNodes.includes(element)) {
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,49 @@ describe('FormControlMixin', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('adds aria-live="politie" to the feedback slot', async () => {
|
it('internally sorts aria-describedby and aria-labelledby ids', async () => {
|
||||||
|
const wrapper = await fixture(html`
|
||||||
|
<div id="wrapper">
|
||||||
|
<div id="additionalLabelA">should go after input internals</div>
|
||||||
|
<div id="additionalDescriptionA">should go after input internals</div>
|
||||||
|
<${tag}>
|
||||||
|
<input slot="input" />
|
||||||
|
<label slot="label">Added to label by default</label>
|
||||||
|
<div slot="feedback">Added to description by default</div>
|
||||||
|
</${tag}>
|
||||||
|
<div id="additionalLabelB">should go after input internals</div>
|
||||||
|
<div id="additionalDescriptionB">should go after input internals</div>
|
||||||
|
</div>`);
|
||||||
|
const el = wrapper.querySelector(elem);
|
||||||
|
|
||||||
|
const { _inputNode } = el;
|
||||||
|
console.log('_inputNode', _inputNode);
|
||||||
|
|
||||||
|
// 1. addToAriaLabelledBy()
|
||||||
|
// external inputs should go in order defined by user
|
||||||
|
el.addToAriaLabelledBy(wrapper.querySelector('#additionalLabelB'));
|
||||||
|
el.addToAriaLabelledBy(wrapper.querySelector('#additionalLabelA'));
|
||||||
|
|
||||||
|
expect(
|
||||||
|
_inputNode.getAttribute('aria-labelledby').indexOf(`label-${el._inputId}`) <
|
||||||
|
_inputNode.getAttribute('aria-labelledby').indexOf('additionalLabelB') <
|
||||||
|
_inputNode.getAttribute('aria-labelledby').indexOf('additionalLabelA'),
|
||||||
|
);
|
||||||
|
|
||||||
|
// 2. addToAriaDescribedBy()
|
||||||
|
// Check if the aria attr is filled initially
|
||||||
|
el.addToAriaDescribedBy(wrapper.querySelector('#additionalDescriptionB'));
|
||||||
|
el.addToAriaDescribedBy(wrapper.querySelector('#additionalDescriptionA'));
|
||||||
|
|
||||||
|
// Should be placed in the end
|
||||||
|
expect(
|
||||||
|
_inputNode.getAttribute('aria-describedby').indexOf(`feedback-${el._inputId}`) <
|
||||||
|
_inputNode.getAttribute('aria-describedby').indexOf('additionalDescriptionB') <
|
||||||
|
_inputNode.getAttribute('aria-describedby').indexOf('additionalDescriptionA'),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('adds aria-live="polite" to the feedback slot', async () => {
|
||||||
const lionField = await fixture(html`
|
const lionField = await fixture(html`
|
||||||
<${tag}>
|
<${tag}>
|
||||||
${inputSlot}
|
${inputSlot}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue