diff --git a/src/components/link-box-list/link-box-list.tsx b/src/components/link-box-list/link-box-list.tsx index 353962d30cd34853043592b42ee6fe585c0b27f0..7cee12691b18621842787fbec3d770af80b012bc 100644 --- a/src/components/link-box-list/link-box-list.tsx +++ b/src/components/link-box-list/link-box-list.tsx @@ -58,7 +58,13 @@ export class LinkBoxList implements ComponentInterface { } render() { - const classAttributes = [this.variant, 'hy-link-box-list', `hy-link-box-list__${this.headerstyle}`].join(' '); + const classAttributes = [ + 'hy-link-box-list', + this.variant, + `hy-link-box-list__${this.variant}`, + `hy-link-box-list__${this.headerstyle}`, + ].join(' '); + /* - Logic: - 3 items: big @@ -70,7 +76,7 @@ export class LinkBoxList implements ComponentInterface { - 9 items: big * */ const classItem = this.getBoxClassName(this._dataItems.length); - const classItemAttributes = [this.variant, classItem].join(' '); + const classItemAttributes = [this.variant, `hy-link-box__${this.variant}`, classItem].join(' '); return ( <Host> diff --git a/src/components/link-box/link-box.scss b/src/components/link-box/link-box.scss index 6afc166b6e8a131c3ed7dbb8f16222288e12b20b..b6a36f3a7fbd71a958b124bf53a533f4838dc446 100644 --- a/src/components/link-box/link-box.scss +++ b/src/components/link-box/link-box.scss @@ -16,31 +16,14 @@ @include breakpoint($extrawide) { margin-right: var(--gutter-extrawide); } - - .hy-link-box__link { - bottom: 12px; - position: absolute; - right: -6px; - - svg { - background-color: var(--brand-main-light); - box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.1); - fill: var(--grayscale-white); - padding: 10.29px; - } - } - article { - position: relative; - width: 100%; - } } :host(.big) { display: flex; @include breakpoint($narrow) { flex-grow: 1; - max-width: calc(((100% - #{var(--gutter-narrow)} * 11) / 12) * 4 + #{var(--gutter-narrow)} * 3); - width: calc(((100% - #{var(--gutter-narrow)} * 11) / 12) * 4 + #{var(--gutter-narrow)} * 3); + max-width: calc(((100% - #{var(--gutter-narrow)} * 11) / 12) * 6 + #{var(--gutter-narrow)} * 5); + width: calc(((100% - #{var(--gutter-narrow)} * 11) / 12) * 6 + #{var(--gutter-narrow)} * 5); } @include breakpoint($wide) { max-width: calc(((100% - #{var(--gutter-wide)} * 11) / 12) * 4 + #{var(--gutter-wide)} * 3); @@ -68,13 +51,17 @@ width: calc(((100% - #{var(--gutter-extrawide)} * 11) / 12) * 3 + #{var(--gutter-extrawide)} * 2); } } -:host(.big:nth-of-type(3n + 0)) { - display: flex; - margin-right: 0; + +:host(.content.big:nth-of-type(3n + 0)) { + @include breakpoint($wide) { + display: flex; + margin-right: 0; + } } -:host(.small:nth-of-type(2n + 0)) { +:host(:nth-of-type(2n + 0)) { display: flex; + margin-right: 0; @include breakpoint($narrow) { margin-right: 0; } @@ -98,13 +85,16 @@ margin-right: 0; } -.hy-link-box { - text-decoration: none; +.hy-link-box-container { + position: relative; + width: 100%; - @include breakpoint($wide) { - text-align: left; + &:hover { + cursor: pointer; } +} +.hy-link-box { &__image-container { display: flex; justify-content: stretch; @@ -130,52 +120,242 @@ width: 100%; } } -} -// placed in Landing pages -.hy-link-box.landing { - .hy-link-box__text-container { - margin-bottom: 68px; - padding: 0 16px; + // Front and Landing pages + &__landing { + .hy-link-box__text-container { + margin-bottom: 60px; + padding: 0 12px; - &__title { - @include font-weight($bold); - @include font-size(40px, 44px); - color: var(--brand-main-nearly-black); - font-family: var(--main-font-family); - letter-spacing: -1.26px; - margin-bottom: 20px; - margin-top: 28px; + @include breakpoint($narrow) { + padding: 0 16px; + } + @include breakpoint($wide) { + padding: 0 12px; + } + @include breakpoint($xlarge) { + padding: 0 16px; + } + + &__title { + @include font-size(22px, 28px); + @include font-weight($bold); + color: var(--brand-main-nearly-black); + font-family: var(--main-font-family); + letter-spacing: -0.6px; + margin-bottom: 8px; + // Margin if there is no image above the title + margin-top: 20px; + // Margin if there is an image above the title + &__image { + margin-top: 16px; + } + + @include breakpoint($narrow) { + @include font-size(24px, 30px); + color: var(--grayscale-black); + letter-spacing: -0.7px; + } + @include breakpoint($wide) { + margin-top: 24px; + &__image { + margin-top: 18px; + } + } + @include breakpoint($extrawide) { + // with sidebar + &__common { + @include font-size(24px, 30px); + letter-spacing: -0.7px; + } + // without sidebar + &__large { + @include font-size(28px, 36px); + letter-spacing: -0.8px; + margin-bottom: 12px; + margin-top: 32px; + } + &__large.image { + // Margin if there is an image above the title + margin-top: 20px; + } + } + @include breakpoint($xlarge) { + // Both with and without sidebar + @include font-size(28px, 36px); + letter-spacing: -0.8px; + margin-bottom: 12px; + // Margin if there is no image above the title + margin-top: 32px; + // Margin if there is an image above the title + &__image { + margin-top: 20px; + } + } + } + + &__description { + @include font-size(14px, 18px); + color: var(--grayscale-dark); + font-family: var(--main-font-family); + letter-spacing: -0.2px; + margin-bottom: 12px; + + @include breakpoint($extrawide) { + // with sidebar + &__common { + @include font-size(14px, 18px); + letter-spacing: -0.2px; + } + // without sidebar + &__large { + @include font-size(16px, 22px); + letter-spacing: -0.2px; + } + } + @include breakpoint($xlarge) { + // Both with and without sidebar + @include font-size(16px, 22px); + letter-spacing: -0.2px; + } + } } - &__description { - @include font-size(20px, 32px); - color: var(--brand-main-nearly-black); - font-family: var(--main-font-family); - letter-spacing: -0.1px; + } + + // Content pages + &__content { + .hy-link-box__text-container { + margin-bottom: 60px; + padding: 0 12px; + + @include breakpoint($narrow) { + padding: 0 16px; + } + @include breakpoint($wide) { + padding: 0 12px; + } + + &__title { + @include font-size(18px, 22px); + @include font-weight($bold); + color: var(--brand-main-nearly-black); + font-family: var(--main-font-family); + letter-spacing: -0.5px; + margin-bottom: 8px; + // Margin if there is no image above the title + margin-top: 24px; + // Margin if there is an image above the title + &__image { + margin-top: 20px; + } + + @include breakpoint($wide) { + // Margin if there is an image above the title + &__image { + margin-top: 16px; + } + } + @include breakpoint($extrawide) { + // with sidebar + &__common { + @include font-size(18px, 22px); + letter-spacing: -0.5px; + } + // without sidebar + &__large { + @include font-size(20px, 24px); + letter-spacing: -0.6px; + margin-bottom: 12px; + // Margin if there is no image above the title + margin-top: 32px; + // Margin if there is an image above the title + &__image { + margin-top: 20px; + } + } + } + @include breakpoint($xlarge) { + // both with and without sidebar + @include font-size(20px, 24px); + letter-spacing: -0.6px; + margin-bottom: 12px; + // Margin if there is no image above the title + margin-top: 32px; + // Margin if there is an image above the title + &__image { + margin-top: 20px; + } + } + } + + &__description { + @include font-size(14px, 18px); + color: var(--grayscale-dark); + font-family: var(--main-font-family); + letter-spacing: -0.2px; + margin-bottom: 10px; + } } } -} -// placed in Content pages -.hy-link-box.content { + // General styles for title .hy-link-box__text-container { - margin-bottom: 68px; - padding: 0 12px; - &__title { - @include font-weight($bold); - @include font-size(20px, 26px); - color: var(--brand-main-nearly-black); - font-family: var(--main-font-family); - letter-spacing: -0.63px; - margin-bottom: 11px; - margin-top: 20px; + &__hover { + color: var(--brand-main); + text-decoration: underline; + } + } + } +} + +.hy-icon-wrapper { + background-color: var(--brand-main-light); + bottom: 12px; + overflow: hidden; + position: absolute; + right: -6px; + z-index: 10; + + &__hover { + background-color: var(--brand-main); + } +} + +.hy-link-box-link { + display: block; + + svg { + background-color: transparent; + box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.05); + fill: var(--grayscale-white); + height: 32px; + padding: 6px; + width: 32px; + } + + &__external { + transform: rotate(-45deg); + } + + @include breakpoint($extrawide) { + // without sidebar, Landing MAJOR variation only + &__landing.large { + svg { + height: 40px; + padding: 8px; + width: 40px; + } } - &__description { - @include font-size(14px, 20px); - color: var(--grayscale-dark); - font-family: var(--main-font-family); - letter-spacing: -0.2px; + } + @include breakpoint($xlarge) { + // MAJOR (Landing and Front pages) + &__landing { + svg { + height: 40px; + padding: 8px; + width: 40px; + } } } } diff --git a/src/components/link-box/link-box.tsx b/src/components/link-box/link-box.tsx index b5b3e87435be454233fda3f943c043fbca9870b9..8887976924e845ca3f0dc1e15b674b5124401b54 100644 --- a/src/components/link-box/link-box.tsx +++ b/src/components/link-box/link-box.tsx @@ -1,6 +1,10 @@ -import {Component, ComponentInterface, Element, Prop, h} from '@stencil/core'; +import {Component, ComponentInterface, Element, Prop, h, Listen} from '@stencil/core'; import {LinkBoxVariants} from '../../utils/utils'; +let keys = { + enter: 'Enter', +}; + @Component({ tag: 'hy-link-box', styleUrl: 'link-box.scss', @@ -27,20 +31,94 @@ export class LinkBox implements ComponentInterface { } } + @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); + } + + @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'); + if (hoverOn) { + (title as HTMLElement).classList.add('hy-link-box__text-container__title__hover'); + (boxLink as HTMLElement).classList.add('hy-icon-wrapper__hover'); + } else { + (title as HTMLElement).classList.remove('hy-link-box__text-container__title__hover'); + (boxLink as HTMLElement).classList.remove('hy-icon-wrapper__hover'); + } + } + render() { + const classContainerAttributes = ['hy-link-box-container'].join(' '); + const classAttributes = [ 'hy-link-box', this.variant, + `hy-link-box__${this.variant}`, this.headerstyle, + `hy-link-box__${this.headerstyle}`, this.imageUrl ? 'hy-link-box--with-image' : null, ].join(' '); - const classLinkAttributes = ['hy-link-box__link', this.headerstyle].join(' '); + 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, + ].join(' '); const classTextContainer = ['hy-link-box__text-container', this.imageUrl ? 'hy-link-box--with-image' : null].join( ' ' ); + 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 target = this.isExternal ? '_blank' : '_self'; const aspectRatioWidth = 16; @@ -51,22 +129,24 @@ export class LinkBox implements ComponentInterface { }; return [ - <article> - <a class={classAttributes} href={this.url} target={target} aria-label={this.scLabel}> + <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> )} <div class={classTextContainer}> - <h3 class="hy-link-box__text-container__title">{this.textTitle}</h3> - {this.textDescription && <div class="hy-link-box__text-container__description">{this.textDescription}</div>} + <h3 class={classTitle}>{this.textTitle}</h3> + {this.textDescription && <div class={classDescription}>{this.textDescription}</div>} </div> - </a> + </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> </article>, - <div class={classLinkAttributes} aria-hidden="true"> - <hy-icon icon={'hy-icon-arrow-right'} size={48} /> - </div>, ]; } }