import { css, html } from 'lit' import { property, query, state } from 'lit/decorators.js' import type { DirectiveClass, DirectiveResult } from 'lit/directive.js' import { classMap } from 'lit/directives/class-map.js' import { when } from 'lit/directives/when.js' import type { Placement } from '@floating-ui/dom' import { customElementIfNotExist, debounce } from '../../upswot-components' import { UsBaseElement } from '../base/UsBaseElement' import '../tooltip/UsTooltip' import UsTextOverflow_css from './textOverflow.pcss' declare global { interface HTMLElementTagNameMap { 'us-text-overflow': UsTextOverflow } } @customElementIfNotExist('us-text-overflow') export class UsTextOverflow extends UsBaseElement { static styles = [ UsBaseElement.styles, css([UsTextOverflow_css] as TemplateStringsArray | any), ] @property({ type: String }) widgetView = '' @property({ type: String }) corner: Placement = 'top' @property({ type: Boolean }) isTwoLinesText = false @property({ type: Boolean }) scrollable = false @state() isOverflowing = false @query('.overflow-text') overflowTextElement!: HTMLElement resizeObserver!: ResizeObserver checkForOverflowDebounced = debounce(this.checkForOverflow.bind(this), 300, false) firstUpdated() { this.resizeObserver = new ResizeObserver(() => { this.checkForOverflowDebounced() }) this.resizeObserver.observe(this) } disconnectedCallback() { if (this.resizeObserver) this.resizeObserver.disconnect() super.disconnectedCallback() } render() { return when(this.isOverflowing, () => html` `, () => html` `, ) } checkForOverflow() { requestAnimationFrame(() => { if (this.overflowTextElement) { this.isOverflowing = this.overflowTextElement.offsetWidth < this.overflowTextElement.scrollWidth if (this.isTwoLinesText) this.isOverflowing = this.overflowTextElement.offsetHeight < this.overflowTextElement.scrollHeight } }) } getTextClasses(): DirectiveResult { return classMap({ 'overflow-text': true, 'two-lines-text': this.isTwoLinesText, 'padding-right': this.isOverflowing && this.isTwoLinesText, }) } }