Skip to content

Commit

Permalink
feat(button): adds type property to support form submit and reset
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 535748632
  • Loading branch information
material-web-copybara authored and copybara-github committed May 27, 2023
1 parent 8634d31 commit 545ce0d
Showing 1 changed file with 43 additions and 1 deletion.
44 changes: 43 additions & 1 deletion button/lib/button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {html as staticHtml, literal} from 'lit/static-html.js';

import {ARIAMixinStrict} from '../../aria/aria.js';
import {requestUpdateOnAriaChange} from '../../aria/delegate.js';
import {dispatchActivationClick, isActivationClick} from '../../controller/events.js';
import {dispatchActivationClick, isActivationClick, redispatchEvent} from '../../controller/events.js';

/**
* A button component.
Expand All @@ -24,6 +24,11 @@ export abstract class Button extends LitElement {
requestUpdateOnAriaChange(this);
}

/** @nocollapse */
static get formAssociated() {
return true;
}

static override shadowRootOptions:
ShadowRootInit = {mode: 'open', delegatesFocus: true};

Expand Down Expand Up @@ -63,11 +68,24 @@ export abstract class Button extends LitElement {
*/
@property({type: Boolean}) preventClickDefault = false;

/**
* Specifies the type of button, used for controlling forms. When type
* is `submit`, the containing form is submitted; when it is `reset` the
* form is reset.
*/
@property() type: ''|'submit'|'reset' = '';

@query('.md3-button') private readonly buttonElement!: HTMLElement|null;

@queryAssignedElements({slot: 'icon', flatten: true})
private readonly assignedIcons!: HTMLElement[];

private readonly internals =
(this as HTMLElement /* needed for closure */).attachInternals();

// flag to avoid processing redispatched event.
private isRedispatchingEvent = false;

constructor() {
super();
if (!isServer) {
Expand Down Expand Up @@ -168,9 +186,33 @@ export abstract class Button extends LitElement {
}

private handleClick(e: MouseEvent) {
if (this.isRedispatchingEvent) {
return;
}
if (this.preventClickDefault) {
e.preventDefault();
}
// based on type, trigger form action.
const {type, internals: {form}} = this;
if (!form) {
return;
}
const isSubmit = type === 'submit', isReset = type === 'reset';
if (!(isSubmit || isReset)) {
return;
}
e.stopPropagation();
this.isRedispatchingEvent = true;
const prevented = !redispatchEvent(this, e);
this.isRedispatchingEvent = false;
if (prevented) {
return;
}
if (isSubmit) {
form.requestSubmit();
} else if (isReset) {
form.reset();
}
}

private handleSlotChange() {
Expand Down

0 comments on commit 545ce0d

Please sign in to comment.