kopia lustrzana https://github.com/shoelace-style/shoelace
fixes #699
rodzic
eb18d759f1
commit
642de684e8
|
@ -35,7 +35,11 @@
|
|||
"esbuild",
|
||||
"exportparts",
|
||||
"fieldsets",
|
||||
"formaction",
|
||||
"formdata",
|
||||
"formmethod",
|
||||
"formnovalidate",
|
||||
"formtarget",
|
||||
"FOUC",
|
||||
"FOUCE",
|
||||
"fullscreen",
|
||||
|
|
|
@ -8,6 +8,7 @@ _During the beta period, these restrictions may be relaxed in the event of a mis
|
|||
|
||||
## Next
|
||||
|
||||
- Added `form`, `formaction`, `formmethod`, `formnovalidate`, and `formtarget` attributes to `<sl-button>` [#699](https://github.com/shoelace-style/shoelace/issues/699)
|
||||
- Improved `autofocus` behavior in Safari for `<sl-dialog>` and `<sl-drawer>` [#693](https://github.com/shoelace-style/shoelace/issues/693)
|
||||
- Removed feature detection for `focus({ preventScroll })` since it no longer works in Safari
|
||||
- Removed path aliasing and third-party dependencies that it required
|
||||
|
|
|
@ -34,7 +34,20 @@ export default class SlButton extends LitElement {
|
|||
|
||||
@query('.button') button: HTMLButtonElement | HTMLLinkElement;
|
||||
|
||||
private readonly formSubmitController = new FormSubmitController(this);
|
||||
private readonly formSubmitController = new FormSubmitController(this, {
|
||||
form: (input: HTMLInputElement) => {
|
||||
// Buttons support a form attribute that points to an arbitrary form, so if this attribute it set we need to query
|
||||
// the form from the same root using its id
|
||||
if (input.hasAttribute('form')) {
|
||||
const doc = input.getRootNode() as Document | ShadowRoot;
|
||||
const formId = input.getAttribute('form')!;
|
||||
return doc.getElementById(formId) as HTMLFormElement;
|
||||
}
|
||||
|
||||
// Fall back to the closest containing form
|
||||
return input.closest('form');
|
||||
}
|
||||
});
|
||||
private readonly hasSlotController = new HasSlotController(this, '[default]', 'prefix', 'suffix');
|
||||
|
||||
@state() private hasFocus = false;
|
||||
|
@ -85,6 +98,24 @@ export default class SlButton extends LitElement {
|
|||
/** Tells the browser to download the linked file as this filename. Only used when `href` is set. */
|
||||
@property() download?: string;
|
||||
|
||||
/**
|
||||
* The "form owner" to associate the button with. If omitted, the closest containing form will be used instead. The
|
||||
* value of this attribute must be an id of a form in the same document or shadow root as the button.
|
||||
*/
|
||||
@property() form: string;
|
||||
|
||||
/** Used to override the form owner's `action` attribute. */
|
||||
@property({ attribute: 'formaction' }) formAction: string;
|
||||
|
||||
/** Used to override the form owner's `method` attribute. */
|
||||
@property({ attribute: 'formmethod' }) formMethod: 'post' | 'get';
|
||||
|
||||
/** Used to override the form owner's `novalidate` attribute. */
|
||||
@property({ attribute: 'formnovalidate', type: Boolean }) formNoValidate: boolean;
|
||||
|
||||
/** Used to override the form owner's `target` attribute. */
|
||||
@property({ attribute: 'formtarget' }) formTarget: '_self' | '_blank' | '_parent' | '_top' | string;
|
||||
|
||||
/** Simulates a click on the button. */
|
||||
click() {
|
||||
this.button.click();
|
||||
|
@ -118,7 +149,7 @@ export default class SlButton extends LitElement {
|
|||
}
|
||||
|
||||
if (this.type === 'submit') {
|
||||
this.formSubmitController.submit();
|
||||
this.formSubmitController.submit(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ import type { ReactiveController, ReactiveControllerHost, TemplateResult } from
|
|||
import { html } from 'lit';
|
||||
import { classMap } from 'lit/directives/class-map.js';
|
||||
import { ifDefined } from 'lit/directives/if-defined.js';
|
||||
import type SlButton from '../components/button/button';
|
||||
import './formdata-event-polyfill';
|
||||
|
||||
export interface FormSubmitControllerOptions {
|
||||
|
@ -84,11 +85,11 @@ export class FormSubmitController implements ReactiveController {
|
|||
}
|
||||
}
|
||||
|
||||
submit() {
|
||||
// Calling form.submit() seems to bypass the submit event and constraint validation. Instead, 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');
|
||||
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 button = document.createElement('button');
|
||||
button.type = 'submit';
|
||||
button.style.position = 'absolute';
|
||||
button.style.width = '0';
|
||||
|
@ -97,6 +98,15 @@ export class FormSubmitController implements ReactiveController {
|
|||
button.style.clipPath = 'inset(50%)';
|
||||
button.style.overflow = 'hidden';
|
||||
button.style.whiteSpace = 'nowrap';
|
||||
|
||||
// Pass form override properties through to the temporary button
|
||||
if (submitter) {
|
||||
button.formAction = submitter.formAction;
|
||||
button.formMethod = submitter.formMethod;
|
||||
button.formNoValidate = submitter.formNoValidate;
|
||||
button.formTarget = submitter.formTarget;
|
||||
}
|
||||
|
||||
this.form.append(button);
|
||||
button.click();
|
||||
button.remove();
|
||||
|
|
Ładowanie…
Reference in New Issue