UNPKG

chrome-devtools-frontend

Version:
104 lines (90 loc) 3.55 kB
// Copyright 2021 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. /* eslint-disable @devtools/no-lit-render-outside-of-view, @devtools/enforce-custom-element-definitions-location */ import '../../kit/kit.js'; import * as Lit from '../../lit/lit.js'; import iconButtonStyles from './iconButton.css.js'; const {html} = Lit; export interface IconWithTextData { iconName: string; iconColor?: string; iconWidth?: string; iconHeight?: string; text?: string; } export interface IconButtonData { clickHandler?: () => void; groups: IconWithTextData[]; leadingText?: string; trailingText?: string; accessibleName?: string; compact?: boolean; } export class IconButton extends HTMLElement { readonly #shadow = this.attachShadow({mode: 'open'}); #clickHandler: undefined|(() => void) = undefined; #groups: IconWithTextData[] = []; #compact = false; #leadingText = ''; #trailingText = ''; #accessibleName: string|undefined; set data(data: IconButtonData) { this.#groups = data.groups.map(group => ({...group})); // Ensure we make a deep copy. this.#clickHandler = data.clickHandler; this.#trailingText = data.trailingText ?? ''; this.#leadingText = data.leadingText ?? ''; this.#accessibleName = data.accessibleName; this.#compact = Boolean(data.compact); this.#render(); } get data(): IconButtonData { return { groups: this.#groups.map(group => ({...group})), // Ensure we make a deep copy. accessibleName: this.#accessibleName, clickHandler: this.#clickHandler, leadingText: this.#leadingText, trailingText: this.#trailingText, compact: this.#compact, }; } #onClickHandler(event: Event): void { if (this.#clickHandler) { event.preventDefault(); this.#clickHandler(); } } #render(): void { const buttonClasses = Lit.Directives.classMap({ 'icon-button': true, 'with-click-handler': Boolean(this.#clickHandler), compact: this.#compact, }); const filteredGroups = this.#groups.filter(counter => counter.text !== undefined) .filter((_, index) => this.#compact ? index === 0 : true); // Disabled until https://crbug.com/1079231 is fixed. // clang-format off Lit.render(html` <style>${iconButtonStyles}</style> <button class=${buttonClasses} @click=${this.#onClickHandler} aria-label=${Lit.Directives.ifDefined(this.#accessibleName)}> ${(!this.#compact && this.#leadingText) ? html`<span class="icon-button-title">${this.#leadingText}</span>` : Lit.nothing} ${filteredGroups.map(counter => html` <devtools-icon class="status-icon" name=${counter.iconName} style="color: ${counter.iconColor}; width: ${counter.iconWidth || 'var(--sys-size-7)'}; height: ${counter.iconHeight || 'var(--sys-size-7)'}"> </devtools-icon> ${this.#compact ? html`<!-- Force line-height for this element --><span>&#8203;</span>` : Lit.nothing} <span class="icon-button-title">${counter.text}</span>`, )} </button> ${(!this.#compact && this.#trailingText) ? html`<span class="icon-button-title">${this.#trailingText}</span>` : Lit.nothing} `, this.#shadow, { host: this}); // clang-format on } } // eslint-disable-next-line @devtools/enforce-custom-element-prefix customElements.define('icon-button', IconButton); declare global { interface HTMLElementTagNameMap { 'icon-button': IconButton; } }