UNPKG

@material/web

Version:
159 lines 5.24 kB
/** * @license * Copyright 2019 Google LLC * SPDX-License-Identifier: Apache-2.0 */ var _a; import { __decorate } from "tslib"; import '../../focus/md-focus-ring.js'; import '../../ripple/ripple.js'; import { html, isServer, LitElement, nothing } from 'lit'; import { property, query, queryAssignedElements } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; import { html as staticHtml, literal } from 'lit/static-html.js'; import { requestUpdateOnAriaChange } from '../../internal/aria/delegate.js'; import { internals } from '../../internal/controller/element-internals.js'; import { dispatchActivationClick, isActivationClick } from '../../internal/controller/events.js'; import { setupFormSubmitter } from '../../internal/controller/form-submitter.js'; /** * A button component. */ export class Button extends LitElement { get name() { return this.getAttribute('name') ?? ''; } set name(name) { this.setAttribute('name', name); } /** * The associated form element with which this element's value will submit. */ get form() { return this[internals].form; } constructor() { super(); /** * Whether or not the button is disabled. */ this.disabled = false; /** * The URL that the link button points to. */ this.href = ''; /** * Where to display the linked `href` URL for a link button. Common options * include `_blank` to open in a new tab. */ this.target = ''; /** * Whether to render the icon at the inline end of the label rather than the * inline start. * * _Note:_ Link buttons cannot have trailing icons. */ this.trailingIcon = false; /** * Whether to display the icon or not. */ this.hasIcon = false; this.type = 'submit'; this.value = ''; /** @private */ this[_a] = this /* needed for closure */.attachInternals(); this.handleActivationClick = (event) => { if (!isActivationClick((event)) || !this.buttonElement) { return; } this.focus(); dispatchActivationClick(this.buttonElement); }; if (!isServer) { this.addEventListener('click', this.handleActivationClick); } } focus() { this.buttonElement?.focus(); } blur() { this.buttonElement?.blur(); } render() { // Link buttons may not be disabled const isDisabled = this.disabled && !this.href; const button = this.href ? literal `a` : literal `button`; // Needed for closure conformance const { ariaLabel, ariaHasPopup, ariaExpanded } = this; return staticHtml ` <${button} class="button ${classMap(this.getRenderClasses())}" ?disabled=${isDisabled} aria-label="${ariaLabel || nothing}" aria-haspopup="${ariaHasPopup || nothing}" aria-expanded="${ariaExpanded || nothing}" href=${this.href || nothing} target=${this.target || nothing} >${this.renderContent()}</${button}>`; } getRenderClasses() { return { 'button--icon-leading': !this.trailingIcon && this.hasIcon, 'button--icon-trailing': this.trailingIcon && this.hasIcon, }; } renderContent() { // Link buttons may not be disabled const isDisabled = this.disabled && !this.href; const icon = html `<slot name="icon" @slotchange="${this.handleSlotChange}"></slot>`; return html ` ${this.renderElevation?.()} ${this.renderOutline?.()} <md-focus-ring part="focus-ring"></md-focus-ring> <md-ripple class="button__ripple" ?disabled="${isDisabled}"></md-ripple> <span class="touch"></span> ${this.trailingIcon ? nothing : icon} <span class="button__label"><slot></slot></span> ${this.trailingIcon ? icon : nothing} `; } handleSlotChange() { this.hasIcon = this.assignedIcons.length > 0; } } _a = internals; (() => { requestUpdateOnAriaChange(Button); setupFormSubmitter(Button); })(); /** @nocollapse */ Button.formAssociated = true; /** @nocollapse */ Button.shadowRootOptions = { mode: 'open', delegatesFocus: true }; __decorate([ property({ type: Boolean, reflect: true }) ], Button.prototype, "disabled", void 0); __decorate([ property() ], Button.prototype, "href", void 0); __decorate([ property() ], Button.prototype, "target", void 0); __decorate([ property({ type: Boolean, attribute: 'trailing-icon' }) ], Button.prototype, "trailingIcon", void 0); __decorate([ property({ type: Boolean, attribute: 'has-icon' }) ], Button.prototype, "hasIcon", void 0); __decorate([ property() ], Button.prototype, "type", void 0); __decorate([ property() ], Button.prototype, "value", void 0); __decorate([ query('.button') ], Button.prototype, "buttonElement", void 0); __decorate([ queryAssignedElements({ slot: 'icon', flatten: true }) ], Button.prototype, "assignedIcons", void 0); //# sourceMappingURL=button.js.map