Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Breaking: Modernize and improve notification message component #325

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .prettierrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,12 @@

module.exports = {
singleQuote: true,
overrides: [
{
files: '**/*.{hbs,yml,yaml}',
options: {
singleQuote: false,
},
},
],
};
13 changes: 0 additions & 13 deletions addon/components/notification-container.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
/* eslint-disable ember/no-classic-components, ember/no-computed-properties-in-native-classes */
import Component from '@ember/component';
import { computed } from '@ember/object';
import { htmlSafe } from '@ember/template';
import { inject as service } from '@ember/service';

import layout from '../templates/components/notification-container';
Expand All @@ -12,15 +10,4 @@ export default class NotificationContainerComponent extends Component {
tagName = '';
layout = layout;
position = 'top';
zindex = '1060';

@computed('position')
get positionClass() {
return `ember-cli-notifications-notification__container--${this.position}`;
}

@computed('zindex')
get inlineStyle() {
return htmlSafe(`z-index: ${this.zindex};`);
}
}
39 changes: 33 additions & 6 deletions addon/components/notification-message.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,17 @@ export default class NotificationMessage extends Component {

paused = false;

@computed('notification.{htmlContent,message}')
get message() {
const { htmlContent, message } = this.notification;
return htmlContent ? htmlSafe(message) : message;
}

@computed('notification.dismiss')
get dismissClass() {
return !this.notification.dismiss ? 'c-notification--in' : '';
return this.notification.dismiss
? 'ecn_notification-out'
: 'ecn_notification-in';
}

@computed('notification.onClick')
Expand Down Expand Up @@ -72,29 +80,48 @@ export default class NotificationMessage extends Component {
@action
handleOnClick(event) {
event.preventDefault();

this.notification.onClick?.(this.notification);
}

@action
removeNotification(event) {
event.preventDefault();
event.stopPropagation();
this.notifications.removeNotification(this.notification);

this.notifications.dismissNotification(this.notification);
}

@action
handleMouseEnter() {
if (this.notification.autoClear) {
let notification = this.notification;

if (notification.autoClear) {
set(this, 'paused', true);
this.notifications.pauseAutoClear(this.notification);
this.notifications.pauseAutoClear(notification);
}
}

@action
handleMouseLeave() {
if (this.notification.autoClear) {
let notification = this.notification;

if (notification.autoClear) {
set(this, 'paused', false);
this.notifications.setupAutoClear(this.notification);
this.notifications.setupAutoClear(notification);
}
}

@action
handleAnimationEnd({ animationName }) {
let notification = this.notification;

if (!notification.dismiss) {
return;
}

if (animationName.endsWith('-out')) {
this.notifications.removeNotification(notification);
}
}
}
19 changes: 7 additions & 12 deletions addon/services/notifications.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,21 +71,16 @@ export default class NotificationsService extends Service {
});
}

dismissNotification(notification) {
set(notification, 'dismiss', true);
}

removeNotification(notification) {
if (!notification) {
return;
}

notification.set('dismiss', true);

// Delay removal from DOM for dismissal animation
later(
this,
() => {
this.content.removeObject(notification);
},
500
);
this.content.removeObject(notification);
}

setupAutoClear(notification) {
Expand All @@ -96,7 +91,7 @@ export default class NotificationsService extends Service {
() => {
// Hasn't been closed manually
if (this.content.indexOf(notification) >= 0) {
this.removeNotification(notification);
this.dismissNotification(notification);
}
},
notification.remaining
Expand All @@ -116,7 +111,7 @@ export default class NotificationsService extends Service {

clearAll() {
this.content.forEach((notification) => {
this.removeNotification(notification);
this.dismissNotification(notification);
});

return this;
Expand Down
120 changes: 103 additions & 17 deletions addon/styles/components/notification-container.css
Original file line number Diff line number Diff line change
@@ -1,67 +1,153 @@
:root {
--ecn-container-position: 10px;
/* Spacing */
--ecn-spacing-1: 0.5rem;
--ecn-spacing-2: 1rem;

/* Container */
--ecn-container-z-index: 9999;
--ecn-container-position: var(--ecn-spacing-1);
--ecn-container-width: 80%;
--ecn-container-max-with: 400px;

/* Notifications */
--ecn-icon-width: 30px;
--ecn-icon-position: 10px;
--ecn-icon-color: rgba(255, 255, 255, 0.74);
--ecn-icon-color: inherit;
--ecn-icon-opacity: 0.74;
--ecn-icon-lighten-background: rgba(255, 255, 255, 0.2);
--ecn-countdown-lighten-background: rgba(255, 255, 255, 0.4);
--ecn-notification-max-height: 800px;
--ecn-notification-border-radius: 3px;
--ecn-notification-border-radius: 4px;

/* Colours */
--ecn-green: #64ce83;
--ecn-blue: #3ea2ff;
--ecn-orange: #ff7f48;
--ecn-red: #e74c3c;
--ecn-green: #22c55e;
--ecn-blue: #0ea5e9;
--ecn-orange: #f97316;
--ecn-red: #ef4444;
--ecn-white: #fff;

/* Spacing */
--ecn-spacing-1: .5rem;
--ecn-spacing-2: 1rem;
/* Types */
--ecn-success-background: var(--ecn-green);
--ecn-info-background: var(--ecn-blue);
--ecn-warning-background: var(--ecn-orange);
--ecn-error-background: var(--ecn-red);
--ecn-success-text: var(--ecn-white);
--ecn-info-text: var(--ecn-white);
--ecn-warning-text: var(--ecn-white);
--ecn-error-text: var(--ecn-white);

/* Animation */
--ecn-animation-in: notification-show 180ms 0ms
cubic-bezier(0.175, 0.885, 0.32, 1.27499);
--ecn-animation-out: notification-hide 250ms
cubic-bezier(0.33859, -0.42, 1, -0.22),
notification-out 250ms 250ms cubic-bezier(0.5, 0, 0, 1);
}

/* Prefers reduced motion */
@media (prefers-reduced-motion: reduce) {
:root {
--ecn-animation-in: notification-show 0.001ms;
--ecn-animation-out: notification-out 0.001ms;
}
}

/* Apply reduced motion in tests */
#ember-testing {
--ecn-animation-in: notification-show 0.001ms;
--ecn-animation-out: notification-out 0.001ms;
}

/* Keyframes */
@keyframes notification-show {
0% {
opacity: 0;
transform: perspective(450px) translate(0, -30px) rotateX(90deg);
}

100% {
opacity: 1;
transform: perspective(450px) translate(0, 0) rotateX(0deg);
}
}

@keyframes notification-out {
0% {
opacity: 0;
max-height: var(--ecn-notification-max-height);
transform: scale(0.8);
}

100% {
opacity: 0;
max-height: 0;
transform: scale(0.8);
}
}

@keyframes notification-hide {
0% {
opacity: 1;
transform: scale(1);
}

100% {
opacity: 0;
transform: scale(0.8);
}
}

@keyframes notification-countdown {
0% {
width: 100%;
}

100% {
width: 0%;
}
}

/* Base */
.ember-cli-notifications-notification__container {
.ecn_container {
position: fixed;
margin: 0 auto;
width: var(--ecn-container-width);
max-width: var(--ecn-container-max-with);
z-index: var(--ecn-container-z-index, 9999);
}

/* Position */
.ember-cli-notifications-notification__container--top {
.ecn_container-top {
top: var(--ecn-container-position);
right: 0;
left: 0;
}

.ember-cli-notifications-notification__container--top-left {
.ecn_container-top-left {
top: var(--ecn-container-position);
right: auto;
left: var(--ecn-container-position);
}

.ember-cli-notifications-notification__container--top-right {
.ecn_container-top-right {
top: var(--ecn-container-position);
right: var(--ecn-container-position);
left: auto;
}

.ember-cli-notifications-notification__container--bottom {
.ecn_container-bottom {
right: 0;
bottom: var(--ecn-container-position);
left: 0;
}

.ember-cli-notifications-notification__container--bottom-left {
.ecn_container-bottom-left {
right: auto;
bottom: var(--ecn-container-position);
left: var(--ecn-container-position);
}

.ember-cli-notifications-notification__container--bottom-right {
.ecn_container-bottom-right {
right: var(--ecn-container-position);
bottom: var(--ecn-container-position);
left: auto;
Expand Down
Loading