<div class="efl-global-notifications priority-1 " data-icon-type="priority-1" data-behavior="efl-global-notifications" data-notification-id="">
<div class="efl-global-notifications__wrapper">
<button class="efl-global-notifications__close"></button>
<div class="efl-global-notifications__wrapper--icon">
<canvas class="notifications-icon rive-priority-1" width="60" height="60"></canvas>
</div>
<div class="efl-global-notifications__wrapper--info">
<div class="efl-global-notifications__section">
<div class="title">The notification title goes here</div>
<p data-copy="The notification message Example. This is a reminder that on the 00/00/00 at 0 PM to">The notification message Example. This is a reminder that on the 00/00/00 at 0 PM to</p>
</div>
</div>
</div>
</div>
No notes defined.
{
"modifier": "priority-1",
"title": "The notification title goes here",
"copy": "The notification message Example. This is a reminder that on the 00/00/00 at 0 PM to"
}
import { Rive, Fit, Layout } from '@rive-app/canvas';
export const notificationAnimation = (
notificationEle,
iconType,
riveCanvas
) => {
// Rive
let riveFile;
if (riveCanvas) {
const lyout = new Layout({
fit: Fit.Cover,
});
if (iconType === 'priority-1') {
riveFile =
'/assets/example-content/global_notification-status_message.riv';
} else if (iconType === 'priority-2') {
riveFile = '/assets/example-content/quiz_notification.riv';
} else if (iconType === 'priority-3') {
riveFile = '/assets/example-content/global_notification-profile.riv';
}
const riveAnimation = new Rive({
src: riveFile,
canvas: riveCanvas,
layout: lyout,
onLoad: () => {
riveAnimation.resizeDrawingSurfaceToCanvas();
},
});
if (iconType === 'priority-1') {
riveAnimation.play('Timeline 1');
} else if (iconType === 'priority-2') {
riveAnimation.play('Active');
} else {
const { profileCompletion } = notificationEle.querySelector(
'.efl-global-notifications__completion'
).dataset;
riveAnimation.play(profileCompletion);
}
}
};
export default parentElement => {
let deferredPrompt;
const MOBILE_BREAKPOINT = 820;
const { iconType } = parentElement.dataset;
const nothanksCta = parentElement.querySelector('.no-thanks-cta');
const homescreenCta = parentElement.querySelector('.add-homescreen-cta');
const closeBtn = parentElement.querySelectorAll(
'.efl-global-notifications__close'
);
const riveCanvas = parentElement.querySelector('.notifications-icon');
const homescreenPrompt = parentElement.classList.contains(
'add-to-homescreen'
);
notificationAnimation(parentElement, iconType, riveCanvas);
if (closeBtn) {
closeBtn.forEach(btn => {
btn.addEventListener('click', e => {
e.preventDefault();
parentElement.classList.add('hidden');
});
});
}
if (homescreenPrompt) {
if ('serviceWorker' in navigator) {
// Register a service worker hosted at the root of the
// site using the default scope.
navigator.serviceWorker.register('/js/service-worker.js').then(
registration => {
console.log('Service worker registration succeeded:', registration);
},
error => {
console.log('Service worker registration failed:', error);
}
);
} else {
console.log('Service workers are not supported.');
}
// eslint-disable-next-line no-param-reassign
parentElement.classList.add('hidden');
window.addEventListener('beforeinstallprompt', e => {
// Prevent Chrome 67 and earlier from automatically showing the prompt
e.preventDefault();
// Stash the event so it can be triggered later.
deferredPrompt = e;
// Update UI to notify the user they can add to home screen
// eslint-disable-next-line no-param-reassign
parentElement.classList.remove('hidden');
homescreenCta.addEventListener('click', event => {
event.preventDefault();
// hide our user interface that shows our A2HS button
parentElement.classList.add('hidden');
// Show the prompt
deferredPrompt.prompt();
// Wait for the user to respond to the prompt
deferredPrompt.userChoice.then(choiceResult => {
if (choiceResult.outcome === 'accepted') {
console.log('User accepted the A2HS prompt');
} else {
console.log('User dismissed the A2HS prompt');
}
deferredPrompt = null;
});
});
});
const removeAddToHomescreen = e => {
e.preventDefault();
localStorage.setItem('addToHomescreen', 'true');
// eslint-disable-next-line no-param-reassign
parentElement.style.display = 'none';
};
const noThanksCta = () => {
const noThanksCtaClicked = localStorage.getItem('addToHomescreen');
if (noThanksCtaClicked) {
// eslint-disable-next-line no-param-reassign
parentElement.style.display = 'none';
} else {
nothanksCta.addEventListener('click', removeAddToHomescreen);
}
};
noThanksCta();
}
if (window.innerWidth < MOBILE_BREAKPOINT) {
const notificationDescription = parentElement.querySelectorAll(
'.efl-global-notifications__section p'
);
if (notificationDescription) {
notificationDescription.forEach(currentEle => {
if (currentEle.innerHTML.length > 60) {
const description = currentEle.innerHTML.substring(0, 70);
currentEle.innerHTML = description; // eslint-disable-line no-param-reassign
const readMoreSpan = document.createElement('span');
currentEle.appendChild(readMoreSpan);
readMoreSpan.className = 'read-more';
readMoreSpan.innerHTML = 'Read More';
const readMorebtn = parentElement.querySelectorAll('.read-more');
readMorebtn.forEach(btn => {
btn.addEventListener('click', e => {
e.preventDefault();
const getDescription = e.target.closest(
'.efl-global-notifications__section p'
);
const dataCopyValue = getDescription.getAttribute('data-copy');
getDescription.style.overflow = 'unset'; // eslint-disable-line no-param-reassign
getDescription.style.display = 'block'; // eslint-disable-line no-param-reassign
getDescription.innerHTML = dataCopyValue; // eslint-disable-line no-param-reassign
});
});
}
});
}
}
};
.efl-global-notifications {
background: $white;
border: 2px solid $grey;
border-radius: 1.6rem;
padding: 2.4rem 1.6rem;
max-width: 35.9rem;
filter: drop-shadow(0 4px 3.2rem rgba(0, 0, 0, 0.24));
&__wrapper {
display: flex;
position: relative;
button {
display: flex;
justify-content: center;
align-items: center;
border: none;
cursor: pointer;
background-color: transparent;
color: $blue;
padding: 0.5rem;
position: absolute;
right: 0;
top: -0.8rem;
z-index: 1;
&:hover {
background-color: $grey-light;
}
&::after {
content: '';
display: block;
width: 1.6rem;
height: 1.6rem;
background: url('./assets/images/notifications-close.svg') no-repeat
center;
background-size: contain;
}
}
&--icon {
width: 4rem;
height: 4rem;
display: flex;
min-width: 5.6rem;
canvas {
width: 6rem;
height: 6rem;
position: relative;
}
img {
position: relative;
width: 6.3rem;
height: 6.3rem;
max-width: 6.3rem;
}
}
&--info {
width: 100%;
padding-left: 1.6rem;
margin-left: 1.3rem;
}
}
&__section {
position: relative;
.title {
@extend .efl-heading-4;
color: $blue;
margin-bottom: 0.8rem;
font-weight: 700;
@include text-limit(2);
max-width: calc(100% - 3rem);
}
p {
@extend .efl-p-small;
color: $color-interface-light;
@include text-limit(2);
max-width: calc(100% - 3rem);
}
.read-more {
padding-left: 10px;
color: #214c99;
text-decoration: underline;
cursor: pointer;
}
.cta.inline-cta {
@extend .efl-p-small;
display: inline-block;
color: #0068b2;
text-decoration: underline;
text-transform: initial;
background-color: transparent;
padding: 0;
border: none;
min-height: unset;
}
&::before {
content: '';
border-left: 1px solid #dfdfdf;
height: 100%;
width: 1px;
display: flex;
position: absolute;
left: -1.6rem;
}
}
&.read {
.efl-global-notifications__section {
.title,
p {
color: $grey;
}
}
}
&__completion {
padding-top: 1.6rem;
&::before {
content: '';
border-top: 1px solid #dfdfdf;
height: 1px;
width: 100%;
left: 0;
display: block;
position: absolute;
}
&--info {
position: relative;
left: -1.6rem;
display: flex;
flex-direction: column;
row-gap: 0.5rem;
margin-top: 1.6rem;
.status {
display: flex;
flex-direction: row;
align-items: center;
border-radius: 2px;
padding: 0.8rem 1.6rem;
cursor: pointer;
&:hover {
background: #eceef3;
}
span {
@extend .efl-p-small;
color: #5b6885;
font-weight: 700;
margin-left: 0.8rem;
}
.cta.add-cta {
@extend .efl-p-small;
visibility: hidden;
font-weight: 700;
letter-spacing: -0.01em;
border-radius: 4px;
color: #fff;
min-height: auto;
background: #004f9f;
padding: 2px 8px;
margin-left: auto;
}
&:hover .cta.add-cta {
visibility: visible;
}
&.completed {
span {
color: $grey;
}
}
}
}
}
&__homescreen {
display: flex;
.cta.no-thanks-cta {
max-width: 8.2rem;
font-size: 1.6rem;
line-height: 2rem;
font-weight: 700;
color: #5b6885;
background-color: transparent;
text-decoration: underline;
padding: 0;
border: none;
margin-right: 2.4rem;
}
.cta.add-homescreen-cta {
max-width: 17.7rem;
background-color: #214c99;
font-weight: 700;
font-size: 1.6rem;
line-height: 2rem;
letter-spacing: 0.06em;
padding: 0 1.5rem;
&:hover {
background-color: #e1261c;
color: #fff;
}
}
}
&.priority-3 {
.efl-global-notifications__wrapper--icon {
height: unset;
}
.efl-global-notifications__section::before {
content: none;
}
}
&.add-to-homescreen {
max-width: calc(100vw - 16px);
position: fixed;
width: 100vw;
bottom: 5.4rem;
left: 8px;
z-index: 99;
padding: 3.2rem;
.efl-global-notifications__section {
margin-bottom: 1.6rem;
}
.efl-global-notifications__wrapper button {
display: none;
}
.efl-global-notifications__wrapper--icon {
width: unset;
height: unset;
min-width: unset;
}
.efl-global-notifications__wrapper--icon img {
top: -0.5rem;
width: 5.6rem;
max-width: 5.6rem;
height: 5.6rem;
}
.efl-global-notifications__wrapper--info {
margin-left: initial;
}
.efl-global-notifications__section::before {
content: none;
}
}
@media screen and (min-width: $mq-medium) {
max-width: 49.9rem;
&__wrapper {
&--info {
overflow: hidden;
}
}
&__section {
.title {
max-width: 100%;
}
}
&__homescreen {
position: initial;
width: 100%;
.cta.no-thanks-cta {
max-width: 11.5rem;
font-size: 24px;
line-height: 26px;
font-weight: 500;
margin-right: 3.2rem;
}
.cta.add-homescreen-cta {
width: 100%;
max-width: 20.1rem;
}
}
&.add-to-homescreen {
top: 13.4rem;
right: 2.4rem;
left: initial;
bottom: initial;
max-width: 49.9rem;
padding: 3.2rem 5.4rem 3.2rem 2.4rem;
.efl-global-notifications__section {
margin-bottom: 2.4rem;
.read-more {
padding-left: 10px;
color: #214c99;
text-decoration: underline;
cursor: pointer;
}
}
.efl-global-notifications__wrapper--icon img {
width: 7.2rem;
max-width: 7.2rem;
height: 7.2rem;
}
.efl-global-notifications__wrapper--info {
padding-left: 2.2rem;
max-width: unset;
}
}
}
@media screen and (min-width: 1440px) {
&.add-to-homescreen {
right: calc(50vw - 70rem + 2.4rem);
}
}
@media screen and (max-width: $mq-medium) {
&.add-to-homescreen {
.efl-global-notifications__section .title {
font-weight: 500;
}
}
}
@media screen and (max-width: 375px) {
&.add-to-homescreen {
.efl-global-notifications__section .title {
max-width: 22.3rem;
}
}
}
@media screen and (max-width: $mq-small) {
&__homescreen {
position: relative;
right: 6.2rem;
}
}
}
<div class="efl-global-notifications {{modifier}} {{#if add-homescreen}}hidden{{/if}}" data-icon-type="{{modifier}}" data-behavior="efl-global-notifications" {{#unless add-homescreen}}data-notification-id="{{notification-id}}"{{/unless}}>
<div class="efl-global-notifications__wrapper">
<button class="efl-global-notifications__close"></button>
<div class="efl-global-notifications__wrapper--icon">
{{#unless add-homescreen}}
<canvas class="notifications-icon rive-{{modifier}}" width="60" height="60"></canvas>
{{/unless}}
{{#if add-homescreen}}
<img src="{{image}}" alt="" />
{{/if}}
</div>
<div class="efl-global-notifications__wrapper--info">
<div class="efl-global-notifications__section">
<div class="title">{{title}}</div>
{{#unless add-homescreen}}
<p data-copy="{{copy}}">{{copy}}</p>
{{/unless}}
</div>
{{#if profile-completion}}
<div class="efl-global-notifications__completion" data-profile-completion="{{profile-complete-percentage}}">
<div class="efl-global-notifications__completion--info">
{{#each profile-completion}}
<div class="status">
{{#if isCompleted}}
<img src="/assets/example-content/global-notification/profile-completed.svg" data-completed-img="/assets/example-content/global-notification/profile-completed.svg" alt="" />
{{else}}
<img src="/assets/example-content/global-notification/profile-not-completed.svg" data-completed-img="/assets/example-content/global-notification/profile-completed.svg" alt="" />
{{/if}}
<span>{{copy}}</span>
{{#if add-cta}}
{{render '@cta' add-cta merge='true'}}
{{/if}}
</div>
{{/each}}
</div>
</div>
{{/if}}
{{#if add-homescreen}}
<div class="efl-global-notifications__homescreen">
{{render '@cta' no-thanks-cta merge='true'}}
{{render '@cta' add-homescreen-cta merge='true'}}
</div>
{{/if}}
</div>
</div>
</div>