kopia lustrzana https://github.com/shoelace-style/shoelace
improve form control listeners
rodzic
5e444a4f7c
commit
fc938ea3eb
|
@ -18,6 +18,7 @@ _During the beta period, these restrictions may be relaxed in the event of a mis
|
|||
- Fixed a bug that resulted in a console error being thrown on keydown in `<sl-dropdown>` [#719](https://github.com/shoelace-style/shoelace/issues/719)
|
||||
- Fixed a bug that prevented `<sl-dropdown>` from being closed when opened initially [#720](https://github.com/shoelace-style/shoelace/issues/720)
|
||||
- Fixed a bug that caused the test runner to fail when using a locale other than en-US [#726](https://github.com/shoelace-style/shoelace/issues/726)
|
||||
- Improved form submit logic so most user-added event listeners will run after form data is attached and validation occurs [#718](https://github.com/shoelace-style/shoelace/issues/718)
|
||||
- Updated `<sl-tab-group>` and `<sl-menu>` to cycle through tabs and menu items instead of stopping at the first/last when using the keyboard
|
||||
- Removed path aliasing (again) because it doesn't work with Web Test Runner's esbuild plugin
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@ export interface FormSubmitControllerOptions {
|
|||
|
||||
export class FormSubmitController implements ReactiveController {
|
||||
host?: ReactiveControllerHost & Element;
|
||||
form?: HTMLFormElement | null;
|
||||
options: FormSubmitControllerOptions;
|
||||
|
||||
constructor(host: ReactiveControllerHost & Element, options?: Partial<FormSubmitControllerOptions>) {
|
||||
|
@ -40,20 +39,15 @@ export class FormSubmitController implements ReactiveController {
|
|||
}
|
||||
|
||||
hostConnected() {
|
||||
this.form = this.options.form(this.host);
|
||||
|
||||
if (this.form) {
|
||||
this.form.addEventListener('formdata', this.handleFormData);
|
||||
this.form.addEventListener('submit', this.handleFormSubmit);
|
||||
}
|
||||
// We use the capture phase and listen on the document to intercept the event as soon as possible. Otherwise, the
|
||||
// user may attach listeners that run before we have a chance to do validation.
|
||||
document.addEventListener('formdata', this.handleFormData, { capture: true });
|
||||
document.addEventListener('submit', this.handleFormSubmit, { capture: true });
|
||||
}
|
||||
|
||||
hostDisconnected() {
|
||||
if (this.form) {
|
||||
this.form.removeEventListener('formdata', this.handleFormData);
|
||||
this.form.removeEventListener('submit', this.handleFormSubmit);
|
||||
this.form = undefined;
|
||||
}
|
||||
document.removeEventListener('formdata', this.handleFormData, { capture: true });
|
||||
document.removeEventListener('submit', this.handleFormSubmit, { capture: true });
|
||||
}
|
||||
|
||||
handleFormData(event: FormDataEvent) {
|
||||
|
@ -73,10 +67,11 @@ export class FormSubmitController implements ReactiveController {
|
|||
}
|
||||
|
||||
handleFormSubmit(event: Event) {
|
||||
const form = this.options.form(this.host);
|
||||
const disabled = this.options.disabled(this.host);
|
||||
const reportValidity = this.options.reportValidity;
|
||||
|
||||
if (this.form && !this.form.noValidate && !disabled && !reportValidity(this.host)) {
|
||||
if (event.target === form && !disabled && !form?.noValidate && !reportValidity(this.host)) {
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
|
@ -84,15 +79,16 @@ export class FormSubmitController implements ReactiveController {
|
|||
|
||||
/** Submits the form, triggering validation and form data injection. */
|
||||
submit(submitter?: HTMLInputElement | SlButton) {
|
||||
// Calling form.submit() bypasses the submit event and constraint validation. To prevent this, we can inject a
|
||||
// native submit button into the form, "click" it, then remove it to simulate a standard form submission.
|
||||
if (this.form) {
|
||||
const form = this.options.form(this.host);
|
||||
|
||||
if (form) {
|
||||
// Calling form.submit() bypasses the submit event and constraint validation. To prevent this, we can inject a
|
||||
// native submit button into the form, "click" it, then remove it to simulate a standard form submission.
|
||||
const button = document.createElement('button');
|
||||
button.type = 'submit';
|
||||
button.style.position = 'absolute';
|
||||
button.style.width = '0';
|
||||
button.style.height = '0';
|
||||
button.style.clip = 'rect(0 0 0 0)';
|
||||
button.style.clipPath = 'inset(50%)';
|
||||
button.style.overflow = 'hidden';
|
||||
button.style.whiteSpace = 'nowrap';
|
||||
|
@ -106,7 +102,7 @@ export class FormSubmitController implements ReactiveController {
|
|||
});
|
||||
}
|
||||
|
||||
this.form.append(button);
|
||||
form.append(button);
|
||||
button.click();
|
||||
button.remove();
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue