fix(ui): fix focus first erroneous for listbox
This commit is contained in:
parent
856c2650be
commit
1dce98d4a8
3 changed files with 37 additions and 4 deletions
5
.changeset/tender-moles-tell.md
Normal file
5
.changeset/tender-moles-tell.md
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
"@lion/ui": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
fix focus first erroneous for listbox
|
||||||
|
|
@ -10,6 +10,15 @@ const throwFormNodeError = () => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {FormRegistrarHost} formEl
|
||||||
|
* @returns {boolean}
|
||||||
|
*/
|
||||||
|
function hasFocusableChildren(formEl) {
|
||||||
|
// this implies all children have the same type (either all of them are focusable or none of them are)
|
||||||
|
return formEl.formElements?.some(child => child._focusableNode);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LionForm: form wrapper providing extra features and integration with lion-field elements.
|
* LionForm: form wrapper providing extra features and integration with lion-field elements.
|
||||||
*
|
*
|
||||||
|
|
@ -63,7 +72,7 @@ export class LionForm extends LionFieldset {
|
||||||
this.dispatchEvent(new Event('submit', { bubbles: true }));
|
this.dispatchEvent(new Event('submit', { bubbles: true }));
|
||||||
|
|
||||||
if (this.hasFeedbackFor?.includes('error')) {
|
if (this.hasFeedbackFor?.includes('error')) {
|
||||||
this._setFocusOnFirstErroneousFormElement(this);
|
this._setFocusOnFirstErroneousFormElement(/** @type { * & FormRegistrarHost } */ (this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -95,7 +104,7 @@ export class LionForm extends LionFieldset {
|
||||||
element.formElements.find(child => child.hasFeedbackFor.includes('error')) ||
|
element.formElements.find(child => child.hasFeedbackFor.includes('error')) ||
|
||||||
element.formElements[0];
|
element.formElements[0];
|
||||||
|
|
||||||
if (firstFormElWithError.formElements?.length > 0) {
|
if (hasFocusableChildren(firstFormElWithError)) {
|
||||||
this._setFocusOnFirstErroneousFormElement(firstFormElWithError);
|
this._setFocusOnFirstErroneousFormElement(firstFormElWithError);
|
||||||
} else {
|
} else {
|
||||||
firstFormElWithError._focusableNode.focus();
|
firstFormElWithError._focusableNode.focus();
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,8 @@ import '@lion/ui/define/lion-fieldset.js';
|
||||||
import { LionField, Required } from '@lion/ui/form-core.js';
|
import { LionField, Required } from '@lion/ui/form-core.js';
|
||||||
import '@lion/ui/define/lion-field.js';
|
import '@lion/ui/define/lion-field.js';
|
||||||
import '@lion/ui/define/lion-validation-feedback.js';
|
import '@lion/ui/define/lion-validation-feedback.js';
|
||||||
|
import '@lion/ui/define/lion-listbox.js';
|
||||||
|
import '@lion/ui/define/lion-option.js';
|
||||||
import '@lion/ui/define/lion-form.js';
|
import '@lion/ui/define/lion-form.js';
|
||||||
import {
|
import {
|
||||||
aTimeout,
|
aTimeout,
|
||||||
|
|
@ -223,7 +224,7 @@ describe('<lion-form>', () => {
|
||||||
expect(document.activeElement).to.equal(el.formElements[1]._inputNode);
|
expect(document.activeElement).to.equal(el.formElements[1]._inputNode);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sets focus on submit to the first erroneous form element with a fieldset', async () => {
|
it('sets focus on submit to the first erroneous form element within a fieldset', async () => {
|
||||||
const el = await fixture(html`
|
const el = await fixture(html`
|
||||||
<lion-form>
|
<lion-form>
|
||||||
<form>
|
<form>
|
||||||
|
|
@ -266,4 +267,22 @@ describe('<lion-form>', () => {
|
||||||
// @ts-ignore [allow-protected] in test
|
// @ts-ignore [allow-protected] in test
|
||||||
expect(document.activeElement).to.equal(fieldset.formElements[0]._inputNode);
|
expect(document.activeElement).to.equal(fieldset.formElements[0]._inputNode);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('sets focus on submit to the first form element within a erroneous listbox', async () => {
|
||||||
|
const el = await fixture(html`
|
||||||
|
<lion-form>
|
||||||
|
<form>
|
||||||
|
<lion-listbox name="name" .validators="${[new Required()]}">
|
||||||
|
<lion-option value="a">a</lion-option>
|
||||||
|
<lion-option value="b">b</lion-option>
|
||||||
|
</lion-listbox>
|
||||||
|
<button type="submit">submit</button>
|
||||||
|
</form>
|
||||||
|
</lion-form>
|
||||||
|
`);
|
||||||
|
const button = /** @type {HTMLButtonElement} */ (el.querySelector('button'));
|
||||||
|
button.click();
|
||||||
|
const listboxEl = el.formElements[0];
|
||||||
|
expect(document.activeElement).to.equal(listboxEl._inputNode);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue