Skip to content

Commit

Permalink
Closes #13 - added timer functionality & updated readme
Browse files Browse the repository at this point in the history
  • Loading branch information
codewithkyle committed Nov 9, 2020
1 parent ff6deb0 commit ad87514
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 28 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Expand Up @@ -10,9 +10,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

- ability to autofocus buttons ([#14](https://github.com/codewithkyle/notifyjs/issues/14))
- CDN compatible version
- CDN compatible version (ES Module)
- role attributes to snackbar and toast notifications
- toast notificaitons can contain buttons ([#15](https://github.com/codewithkyle/notifyjs/issues/15))
- toast notification timers ([#13](https://github.com/codewithkyle/notifyjs/issues/13))
- updated readme

### Fixed

Expand Down
67 changes: 45 additions & 22 deletions README.md
@@ -1,6 +1,6 @@
# Notify.js

Notify.js is a hyper-lightweight utility library helping to manage simple [snackbar](https://material.io/develop/web/components/snackbars/) and [toaster](https://www.carbondesignsystem.com/components/notification/code/) notifications.
Notify.js is a hyper-lightweight utility library for managing simple [snackbar](https://material.io/develop/web/components/snackbars/) and [toaster](https://www.carbondesignsystem.com/components/notification/code/) notifications.

## Installation

Expand All @@ -10,8 +10,23 @@ Download Notify.js via NPM:
npm i --save @codewithkyle/notifyjs
```

Or use the CDN version:

```javascript
import { Notifier, snackbar, toast } from "https://cdn.jsdelivr.net/npm/@codewithkyle/notifyjs@2.1.0/notify.min.mjs;
```
## Usage
1. [Notification Manager](#notification-manager)
1. [Global Notifications](#global-manager)
1. [Snackbar Notification](#snackbar-notification)
1. [Snackbar Interface](#snackbar-interface)
1. [Snackbar HTML Structure](#snackbar-html-structure)
1. [Toast Notification](#toast-notification)
1. [Toast Interface](#toast-interface)
1. [Toast HTML Structure](#toast-html-structure)
There are two ways to use this package. You can create a Notification Manager or use the global manager. Each manager has a queue and new notifications are placed in the queue in the order that they're requested. The queue can be skipped by settings the `force` value to true.
### Notification Manager
Expand Down Expand Up @@ -53,12 +68,31 @@ notifier.toast({
title: "Toast notificaitons require a title",
message: "And they require a message",
});
// Adds an action button
notifier.snackbar({
message: "All snackbar notifications require a message",
buttons: [
{
label: "Update",
callback: () => {
console.log("User clicked the update button");
},
},
],
});
```
---
## Snackbar Notification
Snackbar notifications are great for quick one-off notifications.
### Snackbar Interface
```typescript
interface NotificationOptions {
interface SnackbarNotification {
message: string;
duration?: number; // in seconds
closeable?: boolean;
Expand All @@ -75,25 +109,7 @@ interface NotificationOptions {
}
```
### User Interaction

Notify.js also allows for user interactions via a button element. The action requires a custom label for the button along with a callback function that will be called when the `click` event is fired on the button.

```typescript
notify({
message: "A new version of this application is available",
buttons: [
{
label: "Update",
callback: () => {
console.log("User clicked the update button");
},
},
],
});
```

### HTML Structure
### Snackbar HTML Structure
```html
<snackbar-component>
Expand All @@ -107,8 +123,14 @@ notify({
</snackbar-component>
```
---
## Toast Notification
Toaster notifications are great for application-like notification systems where users will need to recieve warnings, updates, successes, and errors.
### Toast Interface
```typescript
type ToasterNotification = {
title: string;
Expand All @@ -125,10 +147,11 @@ type ToasterNotification = {
classes?: Array<string> | string;
autofocus?: boolean;
}>;
timer?: "vertical" | "horizontal";
};
```
### HTML Structure
### Toast HTML Structure
```html
<toaster-component>
Expand Down
23 changes: 23 additions & 0 deletions src/notifier.ts
Expand Up @@ -29,6 +29,14 @@ export class Notifier {
for (let i = this.toaster.length - 1; i >= 0; i--) {
if (this.toaster[i]?.duration && this.toaster[i]?.duration !== Infinity) {
this.toaster[i].duration -= deltaTime;
if (this.toaster[i].timer){
const scale = this.toaster[i].duration / this.toaster[i].timerDuration;
if (this.toaster[i].timer === "vertical"){
this.toaster[i].timerEl.style.transform = `scaleY(${scale})`;
}else{
this.toaster[i].timerEl.style.transform = `scaleX(${scale})`;
}
}
if (this.toaster[i].duration <= 0) {
this.toaster[i].el.remove();
this.toaster.splice(i, 1);
Expand Down Expand Up @@ -231,7 +239,22 @@ export class Notifier {
}
}

if (settings?.timer && toast.duration !== Infinity){
if (settings.timer === "vertical" || settings.timer === "horizontal"){
toast.timer = settings.timer;
}else{
console.error("Toaster timer value only accpets 'vertical' or 'horizontal'");
toast.timer = null;
}
toast.timerDuration = toast.duration;
}else{
toast.timer = null;
}

toast.el = new ToastComponent(toast as ToasterNotification);
if (toast.timer){
toast.timerEl = toast.el.querySelector("toast-timer");
}
this.toaster.push(toast as ToasterNotification);

let shell = document.body.querySelector("toaster-component") || null;
Expand Down
11 changes: 11 additions & 0 deletions src/toast-component.ts
Expand Up @@ -80,6 +80,17 @@ export class ToastComponent extends HTMLElement {
closeButton.addEventListener("click", this.handleCloseClickEvent);
this.appendChild(closeButton);
}

if (this.settings.timer){
const timer = document.createElement("toast-timer");
timer.className = this.settings.timer;
if (this.settings.timer === "horizontal"){
timer.style.transform = "scaleX(1)";
}else{
timer.style.transform = "scaleY(1)";
}
this.append(timer);
}
}

connectedCallback(){
Expand Down
3 changes: 3 additions & 0 deletions src/types.d.ts
Expand Up @@ -27,6 +27,9 @@ export type ToasterNotification = {
classes?: string[];
uid: string;
el: HTMLElement;
timerEl?: HTMLElement;
autofocus?: boolean;
buttons?: Array<NotificationButton>;
timer?: "vertical" | "horizontal";
timerDuration?: number;
};
34 changes: 29 additions & 5 deletions test/index.html
Expand Up @@ -165,10 +165,10 @@
toaster-component toast-component.-green i{color:#48bb78}
toaster-component toast-component i{width:24px;height:24px;position:relative;display:inline-flex;justify-content:center;align-items:center;margin-right:1rem;color:#4299e1}
toaster-component toast-component i svg{width:18px;height:18px}
toaster-component toast-component copy-wrapper{display:block;flex:1}
toaster-component toast-component copy-wrapper{display:block;flex:1;z-index: 2;}
toaster-component toast-component copy-wrapper h3{display:block;color:var(--white);font-weight:var(--font-bold);margin-bottom:.25rem}
toaster-component toast-component copy-wrapper p{display:block;color:var(--neutral-300);font-size:var(--font-sm);line-height:1.618}
toaster-component toast-component .close{width:24px;height:24px;position:absolute;top:.5rem;right:.5rem;display:flex;justify-content:center;align-items:center;color:var(--white)}
toaster-component toast-component .close{z-index: 2;width:24px;height:24px;position:absolute;top:.5rem;right:.5rem;display:flex;justify-content:center;align-items:center;color:var(--white)}
toaster-component toast-component .close:hover::before,
toaster-component toast-component .close:focus::before{transform:scale(1)}
toaster-component toast-component .close:active::before{opacity:.15}
Expand All @@ -181,7 +181,7 @@
flex-flow: row wrap;
align-items: center;
justify-content: flex-end;
margin-top: 0.5rem;
margin-top: 0.75rem;
}
toaster-component toast-component toast-actions button{
height: 36px;
Expand All @@ -202,7 +202,7 @@
toaster-component toast-component toast-actions button::before{content:"";display:inline-block;width:100%;height:100%;border-radius:0.25rem;background-color:var(--primary-500);opacity:.06;position:absolute;top:0;left:0;transform:scale(0);transition:all 150ms var(--ease-bounce)}
@keyframes grow{
from{
transform:translateY(150%);
transform:translateY(50%);
opacity: 0;
}
to{
Expand All @@ -223,10 +223,32 @@
width: calc(300px + 2rem);
}
toast-component{
transform: translateY(150%);
transform: translateY(50%);
opacity: 0;
animation: grow 300ms forwards var(--ease-in);
}
toast-timer{
position: absolute;
background-color: var(--white);

}
toast-timer.vertical{
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0.07;
transform-origin: bottom center;
z-index: 1;
}
toast-timer.horizontal{
opacity: 0.3;
bottom: 0;
left: 0;
height: 8px;
width: 100%;
transform-origin: right center;
}
</style>
</head>
<body>
Expand Down Expand Up @@ -265,6 +287,8 @@
callback: ()=>{ location.reload(); },
},
],
timer: "horizontal",
duration: 10,
});
});
</script>
Expand Down

0 comments on commit ad87514

Please sign in to comment.