<div class="tooltip tooltip--text">
<button class="button button--icon button--fluid tooltip__trigger-button" type="button">
<span class="button__text ">
Why we recommend
</span>
</button>
<div class="tooltip__content-wrapper" aria-hidden="true" tabindex="-1">
<button class="button button--icon button--rotate-icon tooltip__close-button" type="button" aria-label="Close tooltip">
<svg class="icon " role="presentation" focusable="false">
<title>Close tooltip</title>
<use xlink:href="/images/icons-sprite.svg#close"></use>
</svg>
</button>
<h3 class="tooltip__heading">
Example title
</h3>
<div class="tooltip__content">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam venenatis nisl quis imperdiet tincidunt. Nulla massa diam, aliquet vitae laoreet a, fermentum eu velit. Quisque ornare erat in orci hendrerit feugiat at sit amet neque. Fusce elementum semper feugiat. Curabitur egestas neque in leo finibus ultricies.
</div>
</div>
</div>
<div class="tooltip {{ class }}">
{{#if triggerButton.icon}}
{{ render '@button--icon' triggerButton }}
{{else}}
{{ render '@button' triggerButton }}
{{/if}}
<div
class="tooltip__content-wrapper"
aria-hidden="true"
tabindex="-1"
>
{{ render '@button--icon' closeButton }}
<h3 class="tooltip__heading">
{{ title }}
</h3>
<div class="tooltip__content">
{{ content }}
</div>
</div>
</div>
{
"class": "tooltip--text",
"title": "Example title",
"content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam venenatis nisl quis imperdiet tincidunt. Nulla massa diam, aliquet vitae laoreet a, fermentum eu velit. Quisque ornare erat in orci hendrerit feugiat at sit amet neque. Fusce elementum semper feugiat. Curabitur egestas neque in leo finibus ultricies.",
"triggerButton": {
"tag": "button",
"class": "button--fluid tooltip__trigger-button",
"attributes": "type=\"button\"",
"text": "Why we recommend",
"icon": {
"title": "Show tooltip",
"id": "info"
}
},
"closeButton": {
"tag": "button",
"class": "button--rotate-icon tooltip__close-button",
"attributes": "type=\"button\" aria-label=\"Close tooltip\"",
"text": null,
"icon": {
"title": "Close tooltip",
"id": "close",
"hidden": true
}
}
}
$tooltip__icon-size : 24px !default;
$tooltip__content-wrapper-z-index : $z-index-high !default;
$tooltip__content-wrapper-width : 320px !default;
$tooltip__content-background : $color-primary !default;
$tooltip__content-color : $gray-lighter !default;
$tooltip__content-text-transform : initial !default;
$tooltip__after--is-open-background : $tooltip__content-background !default;
$tooltip__heading-margin : $spacer 0 !default;
$tooltip__heading-font-family : $font-family-base !default;
$tooltip__heading-font-size : $font-size-large !default;
$tooltip__heading-font-weight : $font-weight-bold !default;
$tooltip__heading-text-transform : initial !default;
$tooltip__trigger-color--text : $color-primary !default;
$tooltip__trigger-decoration-hover--text: underline !default;
$tooltip__trigger-bg-color : transparent !default;
$tooltip__trigger-icon-fill : $color-primary !default;
$tooltip__trigger-icon-fill-hover : $color-secondary !default;
$tooltip__close-bg-color : transparent !default;
$tooltip__close-icon-fill : $color-secondary !default;
@import 'tooltip-variables';
.tooltip {
position: relative;
display: flex;
justify-content: center;
&:after {
content: '';
display: none;
}
&--text {
.tooltip__trigger-button {
color: $tooltip__trigger-color--text;
&:hover,
&.focus-visible {
text-decoration: $tooltip__trigger-decoration-hover--text;
}
.button__text {
margin: 0;
}
}
}
&__content-wrapper {
position: absolute;
top: 0;
left: 0;
z-index: $tooltip__content-wrapper-z-index;
display: none;
width: $tooltip__content-wrapper-width;
height: auto;
padding: $spacer--medium $spacer--large $spacer--large;
background: $tooltip__content-background;
color: $tooltip__content-color;
font-size: $font-size-medium;
text-transform: $tooltip__content-text-transform;
transform: translate(0%, -100%);
overflow: hidden;
p {
color: $tooltip__content-color;
}
@include mq($screen-m) {
left: 50%;
transform: translate(-50%, -100%);
}
}
&__heading {
margin: $tooltip__heading-margin;
font-family: $tooltip__heading-font-family;
font-size: $tooltip__heading-font-size;
font-weight: $tooltip__heading-font-weight;
color: $tooltip__content-color;
text-transform: $tooltip__heading-text-transform;
}
&__trigger-button {
z-index: $z-index-low;
background-color: $tooltip__trigger-bg-color;
.icon {
fill: $tooltip__trigger-icon-fill;
}
}
&__close-button {
position: absolute;
right: $spacer--small;
top: $spacer--small;
margin: 0;
background-color: $tooltip__close-bg-color;
.icon {
fill: $tooltip__close-icon-fill;
}
}
&--is-open {
&:after {
position: absolute;
display: block;
width: $tooltip__icon-size;
height: $tooltip__icon-size;
background: $tooltip__after--is-open-background;
transform: rotate(45deg);
bottom: calc(100% - #{$spacer});
@include isIE() {
left: $spacer--small;
}
}
.tooltip {
&__content-wrapper {
display: block;
}
}
}
}
'use strict';
class Tooltip {
constructor(element) {
this.element = element;
this.triggerButton = element.querySelector('.tooltip__trigger-button');
this.closeButton = element.querySelector('.tooltip__close-button');
this.contentWrapper = element.querySelector('.tooltip__content-wrapper');
this.mq = '(max-width: 767px)';
this.openClass = 'tooltip--is-open';
// Global instances of event handlers to allow unbinding events
this.createGlobalEventHandlers();
// Init listeners
this.triggerButton.addEventListener('click', this.onToggleEvent);
}
open() {
this.element.classList.add(this.openClass);
this.contentWrapper.setAttribute('aria-hidden', 'false');
this.calculatePosition();
this.contentWrapper.focus();
// Add events only if tooltip is open - prevent overuse.
this.initListeners();
}
close() {
this.element.classList.remove(this.openClass);
this.contentWrapper.setAttribute('aria-hidden', 'true');
this.setContentPosition(null, null);
this.triggerButton.focus();
this.killListeners();
}
setContentPosition(left, width) {
this.contentWrapper.style.left = left;
this.contentWrapper.style.width = width;
}
// TODO: This calculation needs refactor - There's a lot of issues on different viewports size.
calculatePosition() {
let currentPosition = this.contentWrapper.getBoundingClientRect(),
leftBound = currentPosition.left,
rightBound = currentPosition.right,
windowWidth = window.innerWidth;
if (window.matchMedia(this.mq).matches) {
// Calculate full-width tooltip__content (it's positioned absolutly)
this.setContentPosition(-leftBound, windowWidth);
}
else {
if (leftBound <= 0) {
// Move tooltip__content inside window, if it bound to the left border
this.setContentPosition(-leftBound + 20, null);
}
else if (rightBound >= windowWidth) {
// Move tooltip__content inside window, if it bound to the right border
this.setContentPosition(-(rightBound - windowWidth), null);
}
else {
// Reset tooltip__content position
this.setContentPosition(null, null);
}
}
}
createGlobalEventHandlers() {
this.onEscapeEvent = event => {
if (event.which === 27) {
this.close();
}
}
this.onCloseEvent = () => this.close();
this.onToggleEvent = () => {
if (this.element.classList.contains(this.openClass)) {
this.close();
}
else {
this.open();
}
}
this.onOutsideEvent = event => {
if (!(this.element.contains(event.target) && !this.closeButton.contains(event.target))) {
this.close()
}
}
}
initListeners() {
window.addEventListener('resize', this.onCloseEvent);
window.addEventListener('keydown', this.onEscapeEvent);
window.addEventListener('click', this.onOutsideEvent);
}
killListeners() {
window.removeEventListener('resize', this.onCloseEvent);
window.removeEventListener('keydown', this.onEscapeEvent);
window.removeEventListener('click', this.onOutsideEvent);
}
}
const tooltips = [...document.querySelectorAll('.tooltip')];
tooltips.forEach(tooltip => new Tooltip(tooltip));
There are no notes for this item.