pull/667/head
Cory LaViska 2022-02-28 09:59:32 -05:00
rodzic eb18d759f1
commit 642de684e8
4 zmienionych plików z 52 dodań i 6 usunięć

Wyświetl plik

@ -35,7 +35,11 @@
"esbuild",
"exportparts",
"fieldsets",
"formaction",
"formdata",
"formmethod",
"formnovalidate",
"formtarget",
"FOUC",
"FOUCE",
"fullscreen",

Wyświetl plik

@ -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

Wyświetl plik

@ -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);
}
}

Wyświetl plik

@ -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();