<commit_before>/**
 * @license
 * Copyright 2019 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */

import '@material/mwc-icon/mwc-icon';
import 'google3/third_party/javascript/material_web_components/m3/ripple/mwc-ripple';

import {AriaHasPopup, ariaProperty} from '@material/mwc-base/aria-property';
import {Ripple} from 'google3/third_party/javascript/material_web_components/m3/ripple/mwc-ripple';
import {RippleHandlers} from 'google3/third_party/javascript/material_web_components/m3/ripple/ripple-handlers';
import {html, LitElement, TemplateResult} from 'lit';
import {eventOptions, property, query, queryAssignedNodes, queryAsync, state} from 'lit/decorators.js';
import {ClassInfo, classMap} from 'lit/directives/class-map.js';
import {ifDefined} from 'lit/directives/if-defined.js';

/** @soyCompatible */
export abstract class Button extends LitElement {
  static override shadowRootOptions:
      ShadowRootInit = {mode: 'open', delegatesFocus: true};

  /** @soyPrefixAttribute */
  @ariaProperty
  @property({type: String, attribute: 'aria-haspopup'})
  ariaHasPopup!: AriaHasPopup;

  @property({type: Boolean, reflect: true}) disabled = false;

  @property({type: Boolean, attribute: 'trailingicon'}) trailingIcon = false;

  @property({type: String}) icon = '';

  @property({type: String}) label = '';

  @property({type: String}) ariaLabel = '';

  @property({type: Boolean}) hasIcon = false;

  @query('#button') buttonElement!: HTMLElement;

  @queryAsync('md-ripple') ripple!: Promise<Ripple|null>;

  @queryAssignedNodes('icon', true, '*')
  protected iconElement!: HTMLElement[]|null;

  @state() protected shouldRenderRipple = false;

  protected rippleHandlers = new RippleHandlers(() => {
    this.shouldRenderRipple = true;
    return this.ripple;
  });

  /** @soyTemplate */
  protected renderOverlay(): TemplateResult {
    return html``;
  }

  /** @soyTemplate */
  protected renderRipple(): TemplateResult|string {
    return this.shouldRenderRipple ?
        html`<md-ripple class="mdc-button__ripple" .disabled="${
            this.disabled}"></md-ripple>` :
        '';
  }

  /** @soyTemplate */
  protected renderOutline(): TemplateResult {
    return html``;
  }

  /**
   * @soyTemplate
   * @soyAttributes buttonAttributes: #button
   * @soyClasses buttonClasses: #button
   */
  protected override render(): TemplateResult {
    return html`
      <button
          id="button"
          class="mdc-button ${classMap(this.getRenderClasses())}"
          ?disabled="${this.disabled}"
          aria-label="${this.ariaLabel || this.label}"
          aria-haspopup="${ifDefined(this.ariaHasPopup)}"
          @focus="${this.handleRippleFocus}"
          @blur="${this.handleRippleBlur}"
          @mousedown="${this.handleRippleActivate}"
          @mouseenter="${this.handleRippleMouseEnter}"
          @mouseleave="${this.handleRippleMouseLeave}"
          @touchstart="${this.handleRippleActivate}"
          @touchend="${this.handleRippleDeactivate}"
          @touchcancel="${this.handleRippleDeactivate}">
        ${this.renderOverlay()}
        ${this.renderRipple()}
        ${this.renderOutline()}
        <span class="mdc-button__touch"></span>
        ${!this.trailingIcon ? this.renderIcon() : ''}
        <span class="mdc-button__label">${this.label}</span>
        ${this.trailingIcon ? this.renderIcon() : ''}
      </button>`;
  }

  /** @soyTemplate */
  protected getRenderClasses(): ClassInfo {
    return {
      'mdc-button--icon-leading': !this.trailingIcon && this.hasIcon,
      'mdc-button--icon-trailing': this.trailingIcon && this.hasIcon,
    };
  }

  /** @soyTemplate */
  protected getIconContainerClasses(): ClassInfo {
    return {
      'mdc-button__icon--leading': !this.trailingIcon,
      'mdc-button__icon--trailing': this.trailingIcon,
    };
  }

  /** @soyTemplate */
  protected renderIcon(): TemplateResult {
    return html`
      <span class="mdc-button__icon-slot-container ${
        classMap(this.getIconContainerClasses())}">
        <slot name="icon" @slotchange="${this.handleSlotChange}">
          ${this.icon ? this.renderFontIcon() : ''}
        </slot>
     </span>
    `;
  }

  // TODO: investigate removing this
  /** @soyTemplate */<commit_msg>fix(button): inline icon & remove whitespace in render function<commit_after>/**
 * @license
 * Copyright 2019 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */

import '@material/mwc-icon/mwc-icon';
import 'google3/third_party/javascript/material_web_components/m3/ripple/mwc-ripple';

import {AriaHasPopup, ariaProperty} from '@material/mwc-base/aria-property';
import {Ripple} from 'google3/third_party/javascript/material_web_components/m3/ripple/mwc-ripple';
import {RippleHandlers} from 'google3/third_party/javascript/material_web_components/m3/ripple/ripple-handlers';
import {html, LitElement, TemplateResult} from 'lit';
import {eventOptions, property, query, queryAssignedNodes, queryAsync, state} from 'lit/decorators.js';
import {ClassInfo, classMap} from 'lit/directives/class-map.js';
import {ifDefined} from 'lit/directives/if-defined.js';

/** @soyCompatible */
export abstract class Button extends LitElement {
  static override shadowRootOptions:
      ShadowRootInit = {mode: 'open', delegatesFocus: true};

  /** @soyPrefixAttribute */
  @ariaProperty
  @property({type: String, attribute: 'aria-haspopup'})
  ariaHasPopup!: AriaHasPopup;

  @property({type: Boolean, reflect: true}) disabled = false;

  @property({type: Boolean, attribute: 'trailingicon'}) trailingIcon = false;

  @property({type: String}) icon = '';

  @property({type: String}) label = '';

  @property({type: String}) ariaLabel = '';

  @property({type: Boolean}) hasIcon = false;

  @query('#button') buttonElement!: HTMLElement;

  @queryAsync('md-ripple') ripple!: Promise<Ripple|null>;

  @queryAssignedNodes('icon', true, '*')
  protected iconElement!: HTMLElement[]|null;

  @state() protected shouldRenderRipple = false;

  protected rippleHandlers = new RippleHandlers(() => {
    this.shouldRenderRipple = true;
    return this.ripple;
  });

  /** @soyTemplate */
  protected renderOverlay(): TemplateResult {
    return html``;
  }

  /** @soyTemplate */
  protected renderRipple(): TemplateResult|string {
    return this.shouldRenderRipple ?
        html`<md-ripple class="mdc-button__ripple" .disabled="${
            this.disabled}"></md-ripple>` :
        '';
  }

  /** @soyTemplate */
  protected renderOutline(): TemplateResult {
    return html``;
  }

  /**
   * @soyTemplate
   * @soyAttributes buttonAttributes: #button
   * @soyClasses buttonClasses: #button
   */
  protected override render(): TemplateResult {
    // TODO(b/182405623): restore whitespace
    return html`
      <button
          id="button"
          class="mdc-button ${classMap(this.getRenderClasses())}"
          ?disabled="${this.disabled}"
          aria-label="${this.ariaLabel || this.label}"
          aria-haspopup="${ifDefined(this.ariaHasPopup)}"
          @focus="${this.handleRippleFocus}"
          @blur="${this.handleRippleBlur}"
          @mousedown="${this.handleRippleActivate}"
          @mouseenter="${this.handleRippleMouseEnter}"
          @mouseleave="${this.handleRippleMouseLeave}"
          @touchstart="${this.handleRippleActivate}"
          @touchend="${this.handleRippleDeactivate}"
          @touchcancel="${this.handleRippleDeactivate}"><!--
        -->${this.renderOverlay()}<!--
        -->${this.renderRipple()}<!--
        -->${this.renderOutline()}<!--
        -->${this.renderTouchTarget()}<!--
        -->${
    // TODO(b/191914389): move to separate template
    !this.trailingIcon ? html`<span class="mdc-button__icon-slot-container ${
                             classMap(this.getIconContainerClasses())}">
                               <slot name="icon" @slotchange="${
                             this.handleSlotChange}">
                                  ${this.icon ? this.renderFontIcon() : ''}
                               </slot>
                              </span>` :
                         ''}<!--
        -->${this.renderLabel()}<!--
        -->${
        this.trailingIcon ?
        html`<span class="mdc-button__icon-slot-container ${
            classMap(this.getIconContainerClasses())}">
               <slot name="icon" @slotchange="${this.handleSlotChange}">
                 ${
            this.icon ?
            this.renderFontIcon() :
            ''}
               </slot>
             </span>` :
            ''    }<!--
      --></button>`;
  }

  /** @soyTemplate */
  protected getRenderClasses(): ClassInfo {
    return {
      'mdc-button--icon-leading': !this.trailingIcon && this.hasIcon,
      'mdc-button--icon-trailing': this.trailingIcon && this.hasIcon,
    };
  }

  /** @soyTemplate */
  protected getIconContainerClasses(): ClassInfo {
    return {
      'mdc-button__icon--leading': !this.trailingIcon,
      'mdc-button__icon--trailing': this.trailingIcon,
    };
  }

  /** @soyTemplate */
  protected renderTouchTarget(): TemplateResult {
    return html`
      <span class="mdc-button__touch"></span>
    `;
  }

  /** @soyTemplate */
  protected renderLabel(): TemplateResult {
    return html`
      <span class="mdc-button__label">${this.label}</span>
    `;
  }

  // TODO: investigate removing this
  /** @soyTemplate */
{'fraction_non_alphanumeric': 0.15788911441085354, 'fraction_numerical': 0.004486700138874052, 'mean_word_length': 3.1424778761061947, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5426084', 'n_tokens_mistral': 2903, 'n_tokens_neox': 2794, 'n_words': 480}