sorvell

es2022 button.js compiled decorators experiment

Sep 8th, 2023 (edited)
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import '../../focus/md-focus-ring.js';
  2. import '../../ripple/ripple.js';
  3. import { isServer, nothing, html as html$1, LitElement } from 'lit';
  4. import { property, query, queryAssignedElements } from 'lit/decorators.js';
  5. import { classMap } from 'lit/directives/class-map.js';
  6. import { literal, html } from 'lit/static-html.js';
  7. import { requestUpdateOnAriaChange } from '../../internal/aria/delegate.js';
  8. import { internals } from '../../internal/controller/element-internals.js';
  9. import { isActivationClick, dispatchActivationClick } from '../../internal/controller/events.js';
  10. import { setupFormSubmitter } from '../../internal/controller/form-submitter.js';
  11.  
  12. /**
  13.  * @license
  14.  * Copyright 2019 Google LLC
  15.  * SPDX-License-Identifier: Apache-2.0
  16.  */
  17. /**
  18.  * A button component.
  19.  */
  20. let Button = (() => {
  21.     let _classSuper = LitElement;
  22.     return class Button extends _classSuper {
  23.         static {
  24.             requestUpdateOnAriaChange(Button);
  25.             setupFormSubmitter(Button);
  26.         }
  27.         /** @nocollapse */
  28.         static formAssociated = true;
  29.         /** @nocollapse */
  30.         static shadowRootOptions = { mode: 'open', delegatesFocus: true };
  31.         #disabled = false
  32.         /**
  33.          * Whether or not the button is disabled.
  34.          */
  35.         get disabled() { return this.#disabled; }
  36.         set disabled(value) { const old = this.disabled; this.#disabled = value; this.requestUpdate('disabled', old, {type: Boolean, reflect: true});}
  37.         #href = '';
  38.         /**
  39.          * The URL that the link button points to.
  40.          */
  41.         get href() { return this.#href; }
  42.         set href(value) { const old = this.href; this.#href = value; this.requestUpdate('href', old, {});}
  43.         #target = '';
  44.         /**
  45.          * Where to display the linked `href` URL for a link button. Common options
  46.          * include `_blank` to open in a new tab.
  47.          */
  48.         get target() { return this.#target; }
  49.         set target(value) { const old = this.target; this.#target = value; this.requestUpdate('target', name, {});}
  50.         #trailingIcon = false;
  51.         /**
  52.          * Whether to render the icon at the inline end of the label rather than the
  53.          * inline start.
  54.          *
  55.          * _Note:_ Link buttons cannot have trailing icons.
  56.          */
  57.         get trailingIcon() { return this.#trailingIcon; }
  58.         set trailingIcon(value) { const old = this.trailingIcon; this.#trailingIcon = value; this.requestUpdate('trailingIcon', old, {type: Boolean, attribute: 'trailing-icon'})};}
  59.         #hasIcon = false;
  60.         /**
  61.          * Whether to display the icon or not.
  62.          */
  63.         get hasIcon() { return this.#hasIcon; }
  64.         set hasIcon(value) { const old = this.hasIcon; this.#hasIcon = value; this.requestUpdate('hasIcon', old, {type: Boolean, attribute: 'has-icon'});}
  65.         #type = 'submit';
  66.         get type() { return this.#type; }
  67.         set type(value) { const old = this.type; this.#type = value; this.requestUpdate('type', old, {});}
  68.         #value = '';
  69.         get value() { return this.#value; }
  70.         set value(value) { const old = this.value; this.#value = value; this.requestUpdate('value', old, {});}
  71.         get name() {
  72.             return this.getAttribute('name') ?? '';
  73.         }
  74.         set name(name) {
  75.             this.setAttribute('name', name);
  76.         }
  77.         /**
  78.          * The associated form element with which this element's value will submit.
  79.          */
  80.         get form() {
  81.             return this[internals].form;
  82.         }
  83.         get buttonElement() { return this.shadowRoot.querySelector('.button'); }
  84.         get assignedIcons() { return this.shadowRoot.querySelector('slot[name=icon]').assignedElements({flatten: true}); }
  85.         constructor() {
  86.             super();
  87.             if (!isServer) {
  88.                 this.addEventListener('click', this.handleActivationClick);
  89.             }
  90.         }
  91.         focus() {
  92.             this.buttonElement?.focus();
  93.         }
  94.         blur() {
  95.             this.buttonElement?.blur();
  96.         }
  97.         render() {
  98.             // Link buttons may not be disabled
  99.             const isDisabled = this.disabled && !this.href;
  100.             const button = this.href ? literal `a` : literal `button`;
  101.             // Needed for closure conformance
  102.             const { ariaLabel, ariaHasPopup, ariaExpanded } = this;
  103.             return html `
  104.       <${button}
  105.         class="button ${classMap(this.getRenderClasses())}"
  106.         ?disabled=${isDisabled}
  107.         aria-label="${ariaLabel || nothing}"
  108.         aria-haspopup="${ariaHasPopup || nothing}"
  109.         aria-expanded="${ariaExpanded || nothing}"
  110.         href=${this.href || nothing}
  111.         target=${this.target || nothing}
  112.       >${this.renderContent()}</${button}>`;
  113.         }
  114.         getRenderClasses() {
  115.             return {
  116.                 'button--icon-leading': !this.trailingIcon && this.hasIcon,
  117.                 'button--icon-trailing': this.trailingIcon && this.hasIcon,
  118.             };
  119.         }
  120.         renderContent() {
  121.             // Link buttons may not be disabled
  122.             const isDisabled = this.disabled && !this.href;
  123.             const icon = html$1 `<slot name="icon" @slotchange="${this.handleSlotChange}"></slot>`;
  124.             return html$1 `
  125.       ${this.renderElevation?.()}
  126.       ${this.renderOutline?.()}
  127.       <md-focus-ring part="focus-ring"></md-focus-ring>
  128.       <md-ripple class="button__ripple" ?disabled="${isDisabled}"></md-ripple>
  129.       <span class="touch"></span>
  130.       ${this.trailingIcon ? nothing : icon}
  131.       <span class="button__label"><slot></slot></span>
  132.       ${this.trailingIcon ? icon : nothing}
  133.     `;
  134.         }
  135.         handleActivationClick = (event) => {
  136.             if (!isActivationClick((event)) || !this.buttonElement) {
  137.                 return;
  138.             }
  139.             this.focus();
  140.             dispatchActivationClick(this.buttonElement);
  141.         };
  142.         handleSlotChange() {
  143.             this.hasIcon = this.assignedIcons.length > 0;
  144.         }
  145.     };
  146. })();
  147.  
  148. export { Button };
Advertisement
Add Comment
Please, Sign In to add comment