import { css, html } from 'lit' import { classMap } from 'lit/directives/class-map.js' import { property, query, state } from 'lit/decorators.js' import { when } from 'lit/directives/when.js' import type { DirectiveClass, DirectiveResult } from 'lit/directive' import { customElementIfNotExist } from '../../utils/customElementIfNotExist' import { dispatchCustomEvent } from '../../utils/dispatchCustomEvent' import { UsBaseElement } from '../base/UsBaseElement' import { parseNumberFromString } from '../../utils/parseNumberFromString' import { getWidgetViewClasses } from '../../utils/getWidgetViewClasses' import { debounce } from '../../upswot-components' import type { ITransactionItem } from './models/ITransactionItem' import type { ITransactionItemData } from './models/ITransactionItemData' import UsTransactionItem_css from './transactionItem.pcss' import '../badgeGroup/UsBadgeGroup' import '../tooltip/UsTooltip' // import '../icon/UsIcon' declare global { interface HTMLElementTagNameMap { 'us-transaction-item': UsTransactionItem } } @customElementIfNotExist('us-transaction-item') export class UsTransactionItem extends UsBaseElement implements ITransactionItem { static styles = [ UsBaseElement.styles, css([UsTransactionItem_css] as TemplateStringsArray | any), ] @property({ type: Object }) transaction: ITransactionItemData = {} as ITransactionItemData @property({ type: String }) widgetView: ITransactionItem['widgetView'] = 'vertical' @property({ type: Boolean }) isRightIconShown = false @property({ type: Boolean }) isHovered = false @property({ type: Boolean }) useDefaultColorForAmount = false @state() isTooltipRendered = false @query('.info-block') infoBlock!: HTMLDivElement @query('.title-text') titleText!: HTMLParagraphElement resizeObserverContainer!: ResizeObserver containerWidth = 0 setIsTooltipRenderedDebounced = debounce(this.setIsTooltipRendered.bind(this), 300, false) disconnectedCallback(): void { this.disconnectResizeObserver() } firstUpdated(): void { this.initResizeObserver() } render() { return html`
${when(this.isBadgeGroupDisplayed() && this.isVerticalOrHorizontalSmall(), () => this.renderBadgeGroup(), )}
${when(this.isTooltipRendered, () => html`

${this.transaction.title}

${this.transaction.title}

`, () => html`

${this.transaction.title}

`, )}
${when(this.isBadgeGroupDisplayed() && !this.isVerticalOrHorizontalSmall(), () => this.renderBadgeGroup(), )}
${this.transaction.amount}
${when(this.isRightIconShown, () => html`
`, )}

${this.transaction.subtitle}

${when(this.transaction?.subamount, () => html`

${this.transaction?.subamount}

`)}
` } renderBadgeGroup() { return html`
` } getCardClasses(): DirectiveResult { const widgetViewClasses = getWidgetViewClasses(this.widgetView) return classMap({ 'transaction-item': true, 'transaction-item_new': ('isViewed' in this.transaction) && !this.transaction.isViewed, 'transaction-item_ignored': this.transaction.isIgnored || false, 'is-hovered': this.isHovered, ...widgetViewClasses, }) } getItemAmountClasses(): DirectiveResult { const amount = parseNumberFromString(this.transaction.amount) return classMap({ card__amount: true, card__amount_positive: !this.useDefaultColorForAmount && amount > 0, card__amount_negative: !this.useDefaultColorForAmount && amount < 0, }) } isBadgeGroupDisplayed(): boolean { return (this.transaction.badgeGroup && this.transaction.badgeGroup.length > 0) || (this.transaction.iconInGroup && Object.keys(this.transaction.iconInGroup).length > 0) || this.transaction.isIgnored || false } isVerticalOrHorizontalSmall() { return this.widgetView.includes('vertical') || this.widgetView.includes('horizontal-small') } setIsTooltipRendered() { this.isTooltipRendered = this.titleText.scrollHeight !== this.titleText.offsetHeight } handleClick(e: Event) { e.stopPropagation() if (this.isHovered) dispatchCustomEvent('click', this.transaction, this, false, false) } handleEnter(e: KeyboardEvent) { if (e.key === 'Enter' && this.isHovered) dispatchCustomEvent('click', this.transaction, this, false, false) } initResizeObserver() { if (this.infoBlock) this.resizeObserverContainer = this.resizeObserver() } resizeObserver(): ResizeObserver { const resizeWidgetObserver = new ResizeObserver((entries) => { for (const entry of entries) { const containerWidth = entry.contentRect.width if (this.containerWidth !== containerWidth) { this.setIsTooltipRenderedDebounced() this.containerWidth = containerWidth } } }) resizeWidgetObserver.observe(this.infoBlock, { box: 'border-box', }) return resizeWidgetObserver } disconnectResizeObserver() { if (this.resizeObserverContainer) this.resizeObserverContainer.disconnect() } }