import type { PropertyValueMap } from 'lit' import { css, html } from 'lit' import { property, state } from 'lit/decorators.js' import type { DirectiveClass, DirectiveResult } from 'lit/directive.js' import { classMap } from 'lit/directives/class-map.js' import { customElementIfNotExist } from '../../utils/customElementIfNotExist' import { UsBaseElement } from '../base/UsBaseElement' import type { ISnackbarItem } from './model/ISnackbarItem' import type { ISnackbarProps } from './model/ISnackbarProps' import UsSnackbar_css from './snackbar.pcss' import vars_css from './vars.pcss' // import '../icon/UsIcon' declare global { interface HTMLElementTagNameMap { 'us-snackbar': UsSnackbar } } @customElementIfNotExist('us-snackbar') export class UsSnackbar extends UsBaseElement implements ISnackbarProps { static styles = [ UsBaseElement.styles, css([vars_css] as TemplateStringsArray | any), css([UsSnackbar_css] as TemplateStringsArray | any), ] @property({ type: Array }) items: ISnackbarItem[] = [] @property({ type: String }) position: ISnackbarProps['position'] = 'right' @property({ type: String, attribute: 'data-testid', reflect: true }) dataTestId = 'snackbar' @state() delay = 5000 willUpdate(changedProperties: PropertyValueMap | Map) { if (changedProperties.has('items') && this.items) { if (this.items.length > 0) { this.items[0] = { ...this.items[0], show: true } if (this.items[1] && this.items[1].show) this.closePrevSnackbars() } this.closeSnackbarWithDelay(this.items[0], 0) } } render() { return html`
${this.items?.length > 0 ? html` ${this.items.map((snackbar, idx) => { return html`
${snackbar.mainText ? html`

${snackbar.mainText}

` : ''} ${snackbar.captionText ? html`

${snackbar.captionText}

` : ''}
${snackbar.links ? html` ` : ''}
` }) } ` : ''}
` } handleClose(snackbar: ISnackbarItem, idx: number | null = null) { snackbar.show = false if (idx || idx === 0) { setTimeout(() => { this.items.splice(idx, 1) this.requestUpdate() }, 300) } this.requestUpdate() } closeSnackbarWithDelay(snackbar: ISnackbarItem, idx: number | null = null) { if (snackbar) { const delay = snackbar.delaySec ? (snackbar.delaySec * 1000) : 0 const innerDelayCondition = delay && delay !== 0 setTimeout(() => { this.handleClose(snackbar, idx) }, innerDelayCondition ? delay : this.delay) } } closePrevSnackbars() { setTimeout(() => { this.items.forEach((snackbar, idx) => { if (idx !== 0) this.handleClose(snackbar, idx) }) }, 350) } getClasses(snackbar: ISnackbarItem): DirectiveResult { return classMap({ [`snackbar__container_${snackbar.variant}`]: snackbar.variant, show: snackbar.show ?? true, }) } getTitleClasses(snackbar: ISnackbarItem): DirectiveResult { return classMap({ 'snackbar__title': true, 'font-for-title-without-description': snackbar.captionText === '' || !('captionText' in snackbar), }) } getCaptionClasses(snackbar: ISnackbarItem): DirectiveResult { return classMap({ 'font-for-caption-without-title': snackbar.mainText === '' || !('mainText' in snackbar), }) } getTitleDescriptionLinksContainerClasses(snackbar: ISnackbarItem): DirectiveResult { return classMap({ 'snackbar__title-description-links-container': true, 'snackbar__title-description-links-container_direction-row': snackbar.captionText === '' || !('captionText' in snackbar), }) } getIconName(snackbar: ISnackbarItem) { switch (snackbar.variant) { case 'success': return 'circle-check-solid' case 'error': return 'circle-exclamation-solid' case 'info': return 'info-solid' case 'warning': return 'triangle-exclamation-solid' } } getIconColor(snackbar: ISnackbarItem) { switch (snackbar.variant) { case 'success': return 'var(--snackbar-success-icon-color)' case 'error': return 'var(--snackbar-error-icon-color)' case 'info': return 'var(--snackbar-info-icon-color)' case 'warning': return 'var(--snackbar-warning-icon-color)' } } }