import { unsafeCSSVarV2 } from '@blocksuite/affine-shared/theme'; import type { Placement } from '@floating-ui/dom'; import type { TemplateResult } from 'lit'; import { css, html, LitElement, nothing } from 'lit'; import { property } from 'lit/decorators.js'; import { cache } from 'lit/directives/cache.js'; import { styleMap } from 'lit/directives/style-map.js'; export class EditorIconButton extends LitElement { static override styles = css` :host([disabled]), :host(:disabled) { pointer-events: none; cursor: not-allowed; color: var(--affine-text-disable-color); } .icon-container { position: relative; display: flex; align-items: center; padding: var(--icon-container-padding); color: ${unsafeCSSVarV2('icon/primary')}; border-radius: 4px; cursor: pointer; white-space: nowrap; box-sizing: border-box; width: var(--icon-container-width, unset); height: var(--icon-container-height, unset); justify-content: var(--justify, unset); user-select: none; } :host([active]) .icon-container.active-mode-color { color: var(--affine-primary-color); } :host([active]) .icon-container.active-mode-border { border: 1px solid var(--affine-brand-color); } :host([active]) .icon-container.active-mode-background { background: var(--affine-hover-color); } .icon-container[coming] { cursor: not-allowed; color: var(--affine-text-disable-color); } ::slotted(svg) { flex-shrink: 0; font-size: var(--icon-size, 20px); } ::slotted(.label) { flex: 1; padding: 0 4px; overflow: hidden; white-space: nowrap; line-height: var(--label-height, var(--icon-size, 20px)); } ::slotted(.label.padding0) { padding: 0; } ::slotted(.label.ellipsis) { text-overflow: ellipsis; } ::slotted(.label.medium) { font-weight: 500; } .icon-container[with-hover]::before { content: ''; display: block; background: var(--affine-hover-color); position: absolute; width: 100%; height: 100%; top: 0; left: 0; border-radius: 4px; } `; constructor() { super(); // Allow activate button by pressing Enter key this.addEventListener('keypress', event => { if (this.disabled) { return; } if (event.key === 'Enter' && !event.isComposing) { this.click(); } }); // Prevent click event when disabled this.addEventListener( 'click', event => { if (this.disabled) { event.stopPropagation(); event.preventDefault(); } }, { capture: true } ); } override connectedCallback() { super.connectedCallback(); this.tabIndex = 0; this.role = 'button'; } override render() { const tooltip = this.coming ? '(Coming soon)' : this.tooltip; const classnames = `icon-container active-mode-${this.activeMode} ${this.hoverState ? 'hovered' : ''}`; const padding = this.iconContainerPadding; const iconContainerStyles = styleMap({ '--icon-container-width': this.iconContainerWidth, '--icon-container-height': this.iconContainerHeight, '--icon-container-padding': Array.isArray(padding) ? padding.map(v => `${v}px`).join(' ') : `${padding}px`, '--icon-size': this.iconSize, '--justify': this.justify, '--label-height': this.labelHeight, }); return html`