import type { PropertyValueMap } from 'lit' import { css, html } from 'lit' import { property, query, queryAll, 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 { debounce } from '../../../upswot-components' import { customElementIfNotExist } from '../../../utils/customElementIfNotExist' import { UsBaseElement } from '../../base/UsBaseElement' import { getWidgetViewClasses } from '../../../utils/getWidgetViewClasses' import type { IDetailedInfo } from '../models/IDetailedInfo' import type { IDetailedExtendedList, IDetailedList } from '../models/IDetailedList' import type { IBadgeGroupItem } from '../../badgeGroup/models/IBadgeGroupItem' import UsDetailedList_css from './detailedList.pcss' import '../../badgeGroup/UsBadgeGroup' import '../../tooltip/UsTooltip' declare global { interface HTMLElementTagNameMap { 'us-detailed-list': UsDetailedList } } @customElementIfNotExist('us-detailed-list') export class UsDetailedList extends UsBaseElement { static styles = [ UsBaseElement.styles, css([UsDetailedList_css] as TemplateStringsArray | any), ] @property({ type: Array }) list: IDetailedList[] = [] @property({ type: String }) widgetView: IDetailedInfo['widgetView'] = 'vertical' @property({ type: Boolean }) isIgnored = false @state() extendedList: IDetailedExtendedList[] = [] @query('.detailed-list') listBlock!: HTMLDivElement @queryAll('.description-text') descriptionBlocks!: HTMLDivElement[] resizeObserverContainer!: ResizeObserver containerWidth = 0 setIsTooltipRenderedDebounced = debounce(this.setIsTooltipRendered.bind(this), 300, false) willUpdate(changedProperties: PropertyValueMap | Map): void { if (changedProperties.has('list') && this.list.length) this.setExtendedList() } disconnectedCallback(): void { this.disconnectResizeObserver() } firstUpdated(): void { this.initResizeObserver() } render() { return html`
${this.extendedList.map((detail: IDetailedExtendedList) => { switch (detail.type) { case 'badge-group': return html`
${detail.title}
` case 'description': return html`
${detail.title}
${when(detail.isTooltipRendered, () => html`

${detail.value}

${detail.value}
`, () => html`

${detail.value}

`, )}
` case 'text': return html`
${detail.title}

${detail.value}

` default: return null } })}
` } setExtendedList() { this.extendedList = this.list.map((item: IDetailedList) => { return item.type === 'description' ? { ...item, isTooltipRendered: false } : item }) } setIsTooltipRendered() { let index = 0 if (this.descriptionBlocks && this.descriptionBlocks.length) { this.extendedList = this.extendedList.map((item: IDetailedExtendedList) => { if (item.type === 'description') { const element = this.descriptionBlocks[index] if (element) { index++ return { ...item, isTooltipRendered: element.scrollHeight !== element.offsetHeight } } } return item }) } } initResizeObserver() { if (this.listBlock) 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.listBlock, { box: 'border-box', }) return resizeWidgetObserver } disconnectResizeObserver() { if (this.resizeObserverContainer) this.resizeObserverContainer.disconnect() } getDetailedListClasses(): DirectiveResult { const widgetViewClasses = getWidgetViewClasses(this.widgetView) return classMap({ 'detailed-list': true, ...widgetViewClasses, }) } }