diff --git a/README.md b/README.md index dfa0507..1a50d7c 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ [![npm](https://img.shields.io/npm/v/mystical-notification.svg)](https://www.npmjs.com/package/mystical-notification) [![npm](https://img.shields.io/npm/dt/mystical-notification.svg?label=npm%20downloads)](https://www.npmjs.com/package/mystical-notification) # Mystical-Notification -#### Just some notification crap I needed for a web app. Could use some TLC. +## What is it? + Fully customizable alert notifications. Current types are *alert* and *confirm*. Two positions for now are *top* and *bottom*. @@ -31,17 +32,27 @@ mystical.Mystical.alert({ ``` ### Public Methods -- `alert(options: MysticalOptions)` - show simple notification +- `alert(options: AlertOptions)` - shows simple alert notification +- `confirm(options: ConfirmOptions)` - shows a confirmation notification -### MysticalOptions +### Options Interfaces ```ts -interface MysticalOptions { +interface AlertOptions { template: string; backgroundColor?: string; color?: string; position?: string; // top or bottom for now } + +interface ConfirmOptions { + template: string; + backgroundColor?: string; + color?: string; + position?: string; + positiveText?: string; + negativeText?: string; +} ``` ### Contributing - `git clone https://github.com/bradmartin/mystical-notification.git` diff --git a/dist/index.d.ts b/dist/index.d.ts index 0a0e393..37ac845 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -1,9 +1,4 @@ export declare class Mystical { - private static bgColor; - private static fgColor; - private static position; - private static positiveText; - private static negativeText; /** * Creates a simple notification * @param opts [MysticalOptions] - The mystical notifications options. @@ -14,32 +9,6 @@ export declare class Mystical { * @param opts [ConfirmOptions] */ static confirm(opts: ConfirmOptions): Promise; - private static startTransition(defaults, note, top, bottom); - private static setInitStyles(defaults, note); - /** - * Starts the CSS transition and then removes from DOM - * @param id - note to remove - * @param position - note position - */ - private static removeNoteFromDom(id, position); - /** - * Helper for setTimeout with 0 - */ - private static tick(); - /** - * Helper for setTimeout with passed duration - * @param time [number] - milliseconds to wait - */ - private static wait(time); - /** - * Returns an object with the options object settings - since several args are optional - * @param opts - */ - private static createDefaultOpts(opts); - /** - * Generate random ID - */ - private static generateRandomId(); } export interface AlertOptions { template: string; diff --git a/dist/mystical.js b/dist/mystical.js index 216167b..a22f8a1 100644 --- a/dist/mystical.js +++ b/dist/mystical.js @@ -1 +1 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.mystical=e():t.mystical=e()}(this,function(){return function(t){function e(n){if(o[n])return o[n].exports;var i=o[n]={i:n,l:!1,exports:{}};return t[n].call(i.exports,i,i.exports,e),i.l=!0,i.exports}var o={};return e.m=t,e.c=o,e.i=function(t){return t},e.d=function(t,o,n){e.o(t,o)||Object.defineProperty(t,o,{configurable:!1,enumerable:!0,get:n})},e.n=function(t){var o=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(o,"a",o),o},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=0)}([function(t,e,o){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=function(){function t(){}return t.alert=function(t){var e=this,o=this.createDefaultOpts(t),n=document.createElement("div");n.id=this.generateRandomId(),n.tabIndex=-1,n.style.cssText="background-color: "+o.bg+"; border: none; user-select: none; -webkit-tap-highlight-color: rgba(255, 255, 255, 0); outline: none; cursor: pointer; color: "+o.fg+"; position: fixed; left: 0; padding: 10px; width: 100%; transition: all 0.5s ease; margin: 0 auto; overflow-x: hidden;",n.onclick=function(){e.removeNoteFromDom(n.id,o.pos)},n.onkeydown=function(t){13!==t.keyCode&&27!==t.keyCode||e.removeNoteFromDom(n.id,o.pos)},n.innerHTML='\n
\n '+t.template+"\n
\n ";var i=this.setInitStyles(o,n);document.body.appendChild(n),n.focus(),this.startTransition(o,n,i.top,i.bottom)},t.confirm=function(t){var e=this;return new Promise(function(o,n){var i=e.createDefaultOpts(t),r=document.createElement("div");r.id=e.generateRandomId(),r.tabIndex=-1,r.style.cssText="background-color: "+i.bg+"; border: none; user-select: none; -webkit-tap-highlight-color: rgba(255, 255, 255, 0); outline: none; color: "+i.fg+"; position: fixed; left: 0; padding: 10px; width: 100%; transition: all 0.5s ease; margin: 0 auto; overflow-x: hidden;",r.onkeydown=function(t){13!==t.keyCode&&27!==t.keyCode||(e.removeNoteFromDom(r.id,i.pos),o(!1))};var s=e.generateRandomId(),c=e.generateRandomId(),a="color: "+i.fg+"; background-color: "+i.bg+"; cursor: pointer; border: none; background: transparent; outline: none; margin-right: 10px; font-size: 1.1em";r.innerHTML='\n
\n '+t.template+'\n
\n \n \n
\n
\n ";var u=e.setInitStyles(i,r);document.body.appendChild(r),r.focus(),document.getElementById(s).onclick=function(){o(!0),e.removeNoteFromDom(r.id,i.pos)},document.getElementById(c).onclick=function(){o(!1),e.removeNoteFromDom(r.id,i.pos)},e.startTransition(i,r,u.top,u.bottom)})},t.startTransition=function(t,e,o,n){"top"===t.pos?this.tick().then(function(){e.style.top=o,e.style.opacity="1"}):this.tick().then(function(){e.style.bottom=n,e.style.opacity="1"})},t.setInitStyles=function(t,e){var o,n;return"top"===t.pos?(o="0px",n="",e.style.top="-200px"):(o="",n="0%",e.style.bottom="-200px"),{top:o,bottom:n}},t.removeNoteFromDom=function(t,e){var o=document.getElementById(t);"top"===e?o.style.top="-150px":o.style.bottom="-150px",this.wait(500).then(function(){o&&document.body.removeChild(o)})},t.tick=function(){return new Promise(function(t){setTimeout(t,0)})},t.wait=function(t){return new Promise(function(e){setTimeout(e,t)})},t.createDefaultOpts=function(t){return{bg:t.backgroundColor?t.backgroundColor:this.bgColor,fg:t.color?t.color:this.fgColor,pos:t.position?t.position:this.position,posText:t.positiveText?t.positiveText:this.positiveText,negText:t.negativeText?t.negativeText:this.negativeText}},t.generateRandomId=function(){return"mystical-"+(Math.floor(9e4*Math.random())+1e4)},t}();n.bgColor="#333",n.fgColor="#fff",n.position="top",n.positiveText="Yes",n.negativeText="No",e.Mystical=n}])}); \ No newline at end of file +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.mystical=e():t.mystical=e()}(this,function(){return function(t){function e(n){if(o[n])return o[n].exports;var i=o[n]={i:n,l:!1,exports:{}};return t[n].call(i.exports,i,i.exports,e),i.l=!0,i.exports}var o={};return e.m=t,e.c=o,e.i=function(t){return t},e.d=function(t,o,n){e.o(t,o)||Object.defineProperty(t,o,{configurable:!1,enumerable:!0,get:n})},e.n=function(t){var o=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(o,"a",o),o},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=0)}([function(t,e,o){"use strict";function n(t,e,o,n){"top"===t.pos?c().then(function(){e.style.top=o,e.style.opacity="1"}):c().then(function(){e.style.bottom=n,e.style.opacity="1"})}function i(t,e){var o,n;return"top"===t.pos?(o="0px",n="",e.style.top="-200px"):(o="",n="0%",e.style.bottom="-200px"),{top:o,bottom:n}}function r(t,e){var o=document.getElementById(t);"top"===e?o.style.top="-150px":o.style.bottom="-150px",u(500).then(function(){o&&document.body.removeChild(o)})}function c(){return new Promise(function(t){setTimeout(t,0)})}function u(t){return new Promise(function(e){setTimeout(e,t)})}function d(t){return{bg:t.backgroundColor?t.backgroundColor:"#333",fg:t.color?t.color:"#fff",pos:t.position?t.position:"top",posText:t.positiveText?t.positiveText:"Yes",negText:t.negativeText?t.negativeText:"No"}}function l(){return"mystical-"+(Math.floor(9e4*Math.random())+1e4)}Object.defineProperty(e,"__esModule",{value:!0});var s=function(){function t(){}return t.alert=function(t){var e=d(t),o=document.createElement("div");o.id=l(),o.tabIndex=-1,o.style.cssText="background-color: "+e.bg+"; z-index: 99999999; border: none; user-select: none; -webkit-tap-highlight-color: rgba(255, 255, 255, 0); outline: none; cursor: pointer; color: "+e.fg+"; position: fixed; left: 0; padding: 10px; width: 100%; transition: all 0.5s ease; margin: 0 auto; overflow-x: hidden;",o.onclick=function(){r(o.id,e.pos)},o.onkeydown=function(t){13!==t.keyCode&&27!==t.keyCode||r(o.id,e.pos)},o.innerHTML='\n
\n '+t.template+"\n
\n ";var c=i(e,o);document.body.appendChild(o),o.focus(),n(e,o,c.top,c.bottom)},t.confirm=function(t){return new Promise(function(e,o){var c=d(t),u=document.createElement("div");u.id=l(),u.tabIndex=-1,u.style.cssText="background-color: "+c.bg+"; z-index: 99999999; border: none; user-select: none; -webkit-tap-highlight-color: rgba(255, 255, 255, 0); outline: none; color: "+c.fg+"; position: fixed; left: 0; padding: 10px; width: 100%; transition: all 0.5s ease; margin: 0 auto; overflow-x: hidden;",u.onkeydown=function(t){13!==t.keyCode&&27!==t.keyCode||(r(u.id,c.pos),e(!1))};var s=l(),a=l(),p="color: "+c.fg+"; background-color: "+c.bg+"; cursor: pointer; border: none; background: transparent; outline: none; margin-right: 10px; font-size: 1.1em";u.innerHTML='\n
\n '+t.template+'\n
\n \n \n
\n
\n ";var f=i(c,u);document.body.appendChild(u),u.focus(),document.getElementById(s).onclick=function(){e(!0),r(u.id,c.pos)},document.getElementById(a).onclick=function(){e(!1),r(u.id,c.pos)},n(c,u,f.top,f.bottom)})},t}();e.Mystical=s}])}); \ No newline at end of file diff --git a/package.json b/package.json index b6f2efb..9cafcf8 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,9 @@ { "name": "mystical-notification", - "version": "0.3.0", + "version": "0.3.1", "description": "Web alerts I needed.", "main": "dist/mystical", - "typings": "index.d.ts", + "typings": "dist/index.d.ts", "repository": { "type": "git", "url": "https://github.com/bradmartin/mystical-notification" diff --git a/src/index.d.ts b/src/index.d.ts index 0a0e393..37ac845 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -1,9 +1,4 @@ export declare class Mystical { - private static bgColor; - private static fgColor; - private static position; - private static positiveText; - private static negativeText; /** * Creates a simple notification * @param opts [MysticalOptions] - The mystical notifications options. @@ -14,32 +9,6 @@ export declare class Mystical { * @param opts [ConfirmOptions] */ static confirm(opts: ConfirmOptions): Promise; - private static startTransition(defaults, note, top, bottom); - private static setInitStyles(defaults, note); - /** - * Starts the CSS transition and then removes from DOM - * @param id - note to remove - * @param position - note position - */ - private static removeNoteFromDom(id, position); - /** - * Helper for setTimeout with 0 - */ - private static tick(); - /** - * Helper for setTimeout with passed duration - * @param time [number] - milliseconds to wait - */ - private static wait(time); - /** - * Returns an object with the options object settings - since several args are optional - * @param opts - */ - private static createDefaultOpts(opts); - /** - * Generate random ID - */ - private static generateRandomId(); } export interface AlertOptions { template: string; diff --git a/src/index.ts b/src/index.ts index 31eebdd..8327be0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,31 +1,26 @@ export class Mystical { - private static bgColor: string = "#333" - private static fgColor: string = "#fff" - private static position: string = "top" - private static positiveText: string = "Yes" - private static negativeText: string = "No" /** * Creates a simple notification * @param opts [MysticalOptions] - The mystical notifications options. */ public static alert(opts: AlertOptions) { - const defaults = this.createDefaultOpts(opts) + const defaults = createDefaultOpts(opts) // create the main note div const note = document.createElement("div") as HTMLDivElement - note.id = this.generateRandomId() + note.id = generateRandomId() note.tabIndex = -1 - note.style.cssText = `background-color: ${defaults.bg}; border: none; user-select: none; -webkit-tap-highlight-color: rgba(255, 255, 255, 0); outline: none; cursor: pointer; color: ${defaults.fg}; position: fixed; left: 0; padding: 10px; width: 100%; transition: all 0.5s ease; margin: 0 auto; overflow-x: hidden;` + note.style.cssText = `background-color: ${defaults.bg}; z-index: 99999999; border: none; user-select: none; -webkit-tap-highlight-color: rgba(255, 255, 255, 0); outline: none; cursor: pointer; color: ${defaults.fg}; position: fixed; left: 0; padding: 10px; width: 100%; transition: all 0.5s ease; margin: 0 auto; overflow-x: hidden;` // add click event note.onclick = () => { - this.removeNoteFromDom(note.id, defaults.pos) + removeNoteFromDom(note.id, defaults.pos) } // close on enter and escape key press note.onkeydown = (ev: KeyboardEvent) => { if (ev.keyCode === 13 || ev.keyCode === 27) { - this.removeNoteFromDom(note.id, defaults.pos) + removeNoteFromDom(note.id, defaults.pos) } } @@ -34,14 +29,14 @@ export class Mystical { ${opts.template} ` - const iStyles = this.setInitStyles(defaults, note) + const iStyles = setInitStyles(defaults, note) // add the note div to the DOM document.body.appendChild(note) note.focus() // after the note div is on the DOM - to trigger the CSS transition - this.startTransition(defaults, note, iStyles.top, iStyles.bottom) + startTransition(defaults, note, iStyles.top, iStyles.bottom) } @@ -52,24 +47,24 @@ export class Mystical { public static confirm(opts: ConfirmOptions): Promise { return new Promise((resolve, reject) => { - const defaults = this.createDefaultOpts(opts) + const defaults = createDefaultOpts(opts) // create the main note div const note = document.createElement("div") as HTMLDivElement - note.id = this.generateRandomId() + note.id = generateRandomId() note.tabIndex = -1 - note.style.cssText = `background-color: ${defaults.bg}; border: none; user-select: none; -webkit-tap-highlight-color: rgba(255, 255, 255, 0); outline: none; color: ${defaults.fg}; position: fixed; left: 0; padding: 10px; width: 100%; transition: all 0.5s ease; margin: 0 auto; overflow-x: hidden;` + note.style.cssText = `background-color: ${defaults.bg}; z-index: 99999999; border: none; user-select: none; -webkit-tap-highlight-color: rgba(255, 255, 255, 0); outline: none; color: ${defaults.fg}; position: fixed; left: 0; padding: 10px; width: 100%; transition: all 0.5s ease; margin: 0 auto; overflow-x: hidden;` // close on enter and escape key press note.onkeydown = (ev: KeyboardEvent) => { if (ev.keyCode === 13 || ev.keyCode === 27) { - this.removeNoteFromDom(note.id, defaults.pos) + removeNoteFromDom(note.id, defaults.pos) resolve(false) } } - const positiveBtnId = this.generateRandomId() - const negativeBtnId = this.generateRandomId() + const positiveBtnId = generateRandomId() + const negativeBtnId = generateRandomId() const buttonStyle = `color: ${defaults.fg}; background-color: ${defaults.bg}; cursor: pointer; border: none; background: transparent; outline: none; margin-right: 10px; font-size: 1.1em` note.innerHTML = ` @@ -82,7 +77,7 @@ export class Mystical { ` - const iStyles = this.setInitStyles(defaults, note) + const iStyles = setInitStyles(defaults, note) // add the note div to the DOM document.body.appendChild(note) @@ -92,117 +87,119 @@ export class Mystical { const positiveBtn = document.getElementById(positiveBtnId) positiveBtn.onclick = () => { resolve(true) - this.removeNoteFromDom(note.id, defaults.pos) + removeNoteFromDom(note.id, defaults.pos) } // negative btn event const negativeBtn = document.getElementById(negativeBtnId) negativeBtn.onclick = () => { resolve(false) - this.removeNoteFromDom(note.id, defaults.pos) + removeNoteFromDom(note.id, defaults.pos) } // after the note div is on the DOM - to trigger the CSS transition - this.startTransition(defaults, note, iStyles.top, iStyles.bottom) + startTransition(defaults, note, iStyles.top, iStyles.bottom) }) } - private static startTransition(defaults, note, top, bottom) { - // set the top/bottom which will start the transition - if (defaults.pos === "top") { - this.tick().then(() => { - note.style.top = top - note.style.opacity = "1" - }) - } else { - this.tick().then(() => { - note.style.bottom = bottom - note.style.opacity = "1" - }) - } - } - private static setInitStyles(defaults, note) { - let top: any - let bottom: any - // set initial top/bottom position - if (defaults.pos === "top") { - top = "0px" - bottom = "" - note.style.top = "-200px" - } else { - top = "" - bottom = "0%" - note.style.bottom = "-200px" - } - - return { top: top, bottom: bottom } - } - - /** - * Starts the CSS transition and then removes from DOM - * @param id - note to remove - * @param position - note position - */ - private static removeNoteFromDom(id, position) { - let note = document.getElementById(id) - if (position === "top") { - note.style.top = "-150px" - } else { - note.style.bottom = "-150px" - } +} - this.wait(500).then(() => { - if (note) - document.body.removeChild(note) +function startTransition(defaults, note, top, bottom) { + // set the top/bottom which will start the transition + if (defaults.pos === "top") { + tick().then(() => { + note.style.top = top + note.style.opacity = "1" }) - } - - /** - * Helper for setTimeout with 0 - */ - private static tick(): Promise { - return new Promise((resolve) => { - setTimeout(resolve, 0) + } else { + tick().then(() => { + note.style.bottom = bottom + note.style.opacity = "1" }) } +} - /** - * Helper for setTimeout with passed duration - * @param time [number] - milliseconds to wait - */ - private static wait(time: number): Promise { - return new Promise((resolve) => { - setTimeout(resolve, time) - }) +function setInitStyles(defaults, note) { + let top: any + let bottom: any + // set initial top/bottom position + if (defaults.pos === "top") { + top = "0px" + bottom = "" + note.style.top = "-200px" + } else { + top = "" + bottom = "0%" + note.style.bottom = "-200px" } - /** - * Returns an object with the options object settings - since several args are optional - * @param opts - */ - private static createDefaultOpts(opts) { - const bg = opts.backgroundColor ? opts.backgroundColor : this.bgColor - const fg = opts.color ? opts.color : this.fgColor - const pos = opts.position ? opts.position : this.position - const posText = opts.positiveText ? opts.positiveText : this.positiveText - const negText = opts.negativeText ? opts.negativeText : this.negativeText - return { bg, fg, pos, posText, negText } - } + return { top: top, bottom: bottom } +} - /** - * Generate random ID - */ - private static generateRandomId() { - const x = Math.floor(Math.random() * 90000) + 10000 - return `mystical-${x}` +/** + * Starts the CSS transition and then removes from DOM + * @param id - note to remove + * @param position - note position + */ +function removeNoteFromDom(id, position) { + let note = document.getElementById(id) + if (position === "top") { + note.style.top = "-150px" + } else { + note.style.bottom = "-150px" } + wait(500).then(() => { + if (note) + document.body.removeChild(note) + }) +} + +/** + * Helper for setTimeout with 0 + */ +function tick(): Promise { + return new Promise((resolve) => { + setTimeout(resolve, 0) + }) +} + +/** + * Helper for setTimeout with passed duration + * @param time [number] - milliseconds to wait + */ +function wait(time: number): Promise { + return new Promise((resolve) => { + setTimeout(resolve, time) + }) +} + +/** + * Returns an object with the options object settings - since several args are optional + * @param opts + */ +function createDefaultOpts(opts) { + const bg = opts.backgroundColor ? opts.backgroundColor : "#333" + const fg = opts.color ? opts.color : "#fff" + const pos = opts.position ? opts.position : "top" + const posText = opts.positiveText ? opts.positiveText : "Yes" + const negText = opts.negativeText ? opts.negativeText : "No" + return { bg, fg, pos, posText, negText } +} + +/** + * Generate random ID + */ +function generateRandomId() { + const x = Math.floor(Math.random() * 90000) + 10000 + return `mystical-${x}` } + export interface AlertOptions { template: string; backgroundColor?: string;