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()
}
}