Skip to content
Snippets Groups Projects
link-box.tsx 4.69 KiB
Newer Older
  • Learn to ignore specific revisions
  • druid's avatar
    druid committed
    import {Component, ComponentInterface, Element, Prop, h, Listen} from '@stencil/core';
    
    import {LinkBoxVariants} from '../../utils/utils';
    
    druid's avatar
    druid committed
    let keys = {
      enter: 'Enter',
    };
    
    
    @Component({
      tag: 'hy-link-box',
      styleUrl: 'link-box.scss',
    
    })
    export class LinkBox implements ComponentInterface {
    
      @Prop() variant: LinkBoxVariants = LinkBoxVariants.default;
    
      @Prop() imageUrl: string = null;
      @Prop() imageAlt: string = null;
      @Prop() textTitle?: string;
      @Prop() textDescription: string = null;
      @Prop() url?: string;
      @Prop() isExternal: boolean = false;
    
      @Prop() scLabel?: string;
    
      @Prop() headerstyle: string = 'common';
      @Element() el: HTMLElement;
    
      componentDidLoad() {
        let hyMainDiv = this.el.closest('.hy-main');
        if (hyMainDiv) {
          if (!hyMainDiv.classList.contains('with-sidebar')) {
            this.headerstyle = 'large';
          }
        }
      }
    
    druid's avatar
    druid committed
      @Listen('click')
      handleClick(event) {
        this.openLink(event.currentTarget);
      }
    
      @Listen('keydown')
      handleKeyDown(event) {
        const key = (event as KeyboardEvent).code;
        if (key == keys.enter) {
          this.openLink(event.currentTarget);
        }
      }
    
      openLink(linkbox) {
        let card = linkbox.shadowRoot.querySelector('.hy-link-box-container');
        window.open(card.dataset.location, card.dataset.target);
      }
    
    
    druid's avatar
    druid committed
      @Listen('mouseenter')
      handleMouseEnter(event) {
        this.manageHoverEffect(event.currentTarget);
      }
    
      @Listen('mouseleave')
      handleMouseLeave(event) {
        this.manageHoverEffect(event.currentTarget, false);
      }
    
      @Listen('focusin')
      handleOnFocusIn(event) {
        this.manageHoverEffect(event.currentTarget);
      }
    
      @Listen('focusout')
      handleOnFocusOut(event) {
        this.manageHoverEffect(event.currentTarget, false);
      }
    
      manageHoverEffect(linkbox, hoverOn = true) {
        let title = linkbox.shadowRoot.querySelector('h3.hy-link-box__text-container__title');
    
        let boxLink = linkbox.shadowRoot.querySelector('.hy-icon-wrapper');
    
    druid's avatar
    druid committed
        if (hoverOn) {
          (title as HTMLElement).classList.add('hy-link-box__text-container__title__hover');
    
          (boxLink as HTMLElement).classList.add('hy-icon-wrapper__hover');
    
    druid's avatar
    druid committed
        } else {
          (title as HTMLElement).classList.remove('hy-link-box__text-container__title__hover');
    
          (boxLink as HTMLElement).classList.remove('hy-icon-wrapper__hover');
    
    druid's avatar
    druid committed
        }
      }
    
    
    druid's avatar
    druid committed
        const classContainerAttributes = ['hy-link-box-container'].join(' ');
    
    
        const classAttributes = [
          'hy-link-box',
          this.variant,
    
    druid's avatar
    druid committed
          `hy-link-box__${this.variant}`,
    
    druid's avatar
    druid committed
          `hy-link-box__${this.headerstyle}`,
    
          this.imageUrl ? 'hy-link-box--with-image' : null,
        ].join(' ');
    
    
    druid's avatar
    druid committed
        const classLinkAttributes = [
          'hy-link-box-link',
          `hy-link-box-link__${this.variant}`,
          `hy-link-box-link__${this.headerstyle}`,
          this.headerstyle,
    
          this.isExternal ? 'hy-link-box-link__external' : null,
    
    druid's avatar
    druid committed
        ].join(' ');
    
        const classTextContainer = ['hy-link-box__text-container', this.imageUrl ? 'hy-link-box--with-image' : null].join(
          ' '
        );
    
    druid's avatar
    druid committed
        const classTitle = [
          'hy-link-box__text-container__title',
          `hy-link-box__text-container__title__${this.variant}`,
          `hy-link-box__text-container__title__${this.headerstyle}`,
          this.imageUrl ? 'hy-link-box__text-container__title__image' : '',
          this.imageUrl ? 'image' : '',
        ].join(' ');
    
        const classDescription = [
          'hy-link-box__text-container__description',
          `hy-link-box__text-container__description__${this.variant}`,
          `hy-link-box__text-container__description__${this.headerstyle}`,
        ].join(' ');
    
    
        const aspectRatioWidth = 16;
        const aspectRatioHeight = 10;
    
        const aspect = (aspectRatioHeight / aspectRatioWidth) * 100;
        const aspectRatio = {
    
          '--aspectRatio': `${aspect}%` as 'aspectRatio',
    
    Ekaterina Kondareva's avatar
    Ekaterina Kondareva committed
        return [
    
    druid's avatar
    druid committed
          <article class={classContainerAttributes} tabindex="0" data-target={target} data-location={this.url}>
            <div class={classAttributes} aria-label={this.scLabel}>
    
              {this.imageUrl && (
                <div class="hy-link-box__image-container" style={aspectRatio}>
                  <img aria-hidden="true" src={this.imageUrl} alt={this.imageAlt} />
                </div>
              )}
    
    druid's avatar
    druid committed
                <h3 class={classTitle}>{this.textTitle}</h3>
                {this.textDescription && <div class={classDescription}>{this.textDescription}</div>}
    
              </div>
    
    druid's avatar
    druid committed
            </div>
    
            <span class={'hy-icon-wrapper'}>
              <a class={classLinkAttributes} href={this.url} target={target} aria-label={this.scLabel} tabindex="-1">
                <hy-icon icon={'hy-icon-arrow-to-right'} size={32} />
              </a>
            </span>
    
    Ekaterina Kondareva's avatar
    Ekaterina Kondareva committed
          </article>,
        ];