sorvell

es2022 button.js experimental decorators (corrected)

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