├── .gitignore
├── .npmignore
├── History.md
├── Makefile
├── Readme.md
├── component.json
├── index.js
├── notification.css
├── package.json
├── template.html
├── template.js
└── test
└── index.html
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | test/*.js
3 | test/*.css
4 | components
5 | build
6 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | test
2 |
--------------------------------------------------------------------------------
/History.md:
--------------------------------------------------------------------------------
1 |
2 | 0.0.7 / 2015-07-21
3 | ==================
4 |
5 | * component: update "dom" to v1.0.8
6 | * docs: add note about optional ms for `hide()`
7 |
8 | 0.0.6 / 2015-03-11
9 | ==================
10 |
11 | * re-add the `package.json` file
12 | * component: update "dom" to v1.0.7
13 | * component: update "emitter" to v1.2.0
14 | * component: update "description"
15 | * component: Pin deps (#10)
16 | * More readable HTML entity for the close button
17 |
18 | 0.0.4 / 2014-03-17
19 | ==================
20 |
21 | * Use escaped "×"
22 | * switching over to component/dom (as per @ianstormtaylor's comment)
23 | * remove jquery dependency
24 | * add test command to Makefile
25 | * Update emitter to 1.0.1
26 | * add .license property to component.json
27 | * add private .classname option
28 |
29 | 0.0.3 / 2012-08-30
30 | ==================
31 |
32 | * add "close" event
33 | * add `.Notification` export
34 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 |
2 | build: notification.css index.js template.js components
3 | @component build
4 |
5 | template.js: template.html
6 | @component convert $<
7 |
8 | components:
9 | @component install
10 |
11 | clean:
12 | @rm -fr build components
13 |
14 | test: build
15 | @open test/index.html
16 |
17 | .PHONY: clean test
18 |
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | # Notification
2 |
3 | Notification component with a clean slate to build off of,
4 | style and position them however you like.
5 |
6 | 
7 |
8 | These don't _have_ to look like growl style notifications, use
9 | your trusty friend CSS.
10 |
11 | ## Installation
12 |
13 | ```
14 | $ npm install notification-component
15 | ```
16 |
17 | ## Features
18 |
19 | - events for composition
20 | - structural CSS letting you decide on style
21 | - transient notifications
22 | - transient closable notifications
23 | - sticky (implicitly closable) notifications
24 | - notification classes (info, warn, error)
25 | - fluent API
26 |
27 | ## Events
28 |
29 | - `close` the notification is closed via the X
30 | - `click` the notification is clicked
31 |
32 | ## API
33 |
34 | ### notify(msg)
35 |
36 | Notify with the given `msg` and no title. The
37 | notification will hide after 4 seconds by default.
38 |
39 | ### notify(title, msg)
40 |
41 | Notify with the given `msg` and `title`. The
42 | notification will hide after 4 seconds by default.
43 |
44 | ### notify.info(title, [msg])
45 |
46 | Same as `notify()`
47 |
48 | ### notify.warn(title, [msg])
49 |
50 | Same as `notify()` with a `warn` class for styling.
51 |
52 | ### notify.error(title, [msg])
53 |
54 | Same as `notify()` with a `error` class for styling.
55 |
56 | ### Notification#sticky()
57 |
58 | Make the notification sticky, aka it will not close
59 | automatically, and it will automatically be `.closable()`.
60 |
61 | ### Notification#show()
62 |
63 | Show the notification.
64 |
65 | ### Notification#hide([ms])
66 |
67 | Hide the notification immediately or wait ms.
68 |
69 | ### Notification#closable()
70 |
71 | Mark the notification as closable, adding an "X" so the user
72 | may explicitly close it.
73 |
74 | ### Notification#effect(name)
75 |
76 | One of the following effects, or define your own with class `name`:
77 |
78 | - `slide`
79 | - `fade`
80 | - `scale`
81 |
82 | ## License
83 |
84 | MIT
85 |
--------------------------------------------------------------------------------
/component.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "notification",
3 | "description": "Notification component for the client (growl-like)",
4 | "version": "0.0.7",
5 | "keywords": [
6 | "notify",
7 | "notification",
8 | "ui",
9 | "growl"
10 | ],
11 | "dependencies": {
12 | "component/dom": "1.0.7",
13 | "component/emitter": "1.2.0",
14 | "segmentio/on-body": "0.0.1"
15 | },
16 | "scripts": [
17 | "index.js",
18 | "template.js"
19 | ],
20 | "styles": [
21 | "notification.css"
22 | ],
23 | "license": "MIT"
24 | }
25 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * Module dependencies.
4 | */
5 |
6 | var dom = require('dom');
7 | var Emitter = require('emitter');
8 | var onBody = require('on-body');
9 |
10 | /**
11 | * Expose `notify`.
12 | */
13 |
14 | exports = module.exports = notify;
15 |
16 | /**
17 | * Notification list.
18 | */
19 |
20 | var list = dom('
');
21 |
22 | /**
23 | * Append to body when it exists.
24 | */
25 |
26 | onBody(function (body) {
27 | list.appendTo(body);
28 | });
29 |
30 | /**
31 | * Return a new `Notification` with the given
32 | * (optional) `title` and `msg`.
33 | *
34 | * @param {String} title or msg
35 | * @param {String} msg
36 | * @return {Dialog}
37 | * @api public
38 | */
39 |
40 | function notify(title, msg){
41 | switch (arguments.length) {
42 | case 2:
43 | return new Notification({ title: title, message: msg })
44 | .show()
45 | .hide(4000);
46 | case 1:
47 | return new Notification({ message: title })
48 | .show()
49 | .hide(4000);
50 | }
51 | }
52 |
53 | /**
54 | * Construct a notification function for `type`.
55 | *
56 | * @param {String} type
57 | * @return {Function}
58 | * @api private
59 | */
60 |
61 | function type(type) {
62 | return function(title, msg){
63 | return notify.apply(this, arguments)
64 | .type(type);
65 | };
66 | }
67 |
68 | /**
69 | * Notification methods.
70 | */
71 |
72 | exports.info = notify;
73 | exports.warn = type('warn');
74 | exports.error = type('error');
75 |
76 | /**
77 | * Expose constructor.
78 | */
79 |
80 | exports.Notification = Notification;
81 |
82 | /**
83 | * Initialize a new `Notification`.
84 | *
85 | * Options:
86 | *
87 | * - `title` dialog title
88 | * - `message` a message to display
89 | *
90 | * @param {Object} options
91 | * @api public
92 | */
93 |
94 | function Notification(options) {
95 | Emitter.call(this);
96 | options = options || {};
97 | this.el = dom(require('./template'));
98 | this.render(options);
99 | if (options.classname) this.el.addClass(options.classname);
100 | if (Notification.effect) this.effect(Notification.effect);
101 | }
102 |
103 | /**
104 | * Inherit from `Emitter.prototype`.
105 | */
106 |
107 | Notification.prototype = new Emitter;
108 |
109 | /**
110 | * Render with the given `options`.
111 | *
112 | * @param {Object} options
113 | * @api public
114 | */
115 |
116 | Notification.prototype.render = function(options){
117 | var el = this.el
118 | , title = options.title
119 | , msg = options.message
120 | , self = this;
121 |
122 | el.find('.close').on('click', function(){
123 | self.emit('close');
124 | self.hide();
125 | return false;
126 | });
127 |
128 | el.on('click', function(e){
129 | e.preventDefault();
130 | self.emit('click', e);
131 | });
132 |
133 | el.find('.title').text(title);
134 | if (!title) el.find('.title').remove();
135 |
136 | // message
137 | if ('string' == typeof msg) {
138 | el.find('p').text(msg);
139 | } else if (msg) {
140 | el.find('p').replace(msg.el || msg);
141 | }
142 |
143 | setTimeout(function(){
144 | el.removeClass('hide');
145 | }, 0);
146 | };
147 |
148 | /**
149 | * Enable the dialog close link.
150 | *
151 | * @return {Notification} for chaining
152 | * @api public
153 | */
154 |
155 | Notification.prototype.closable = function(){
156 | this.el.addClass('closable');
157 | return this;
158 | };
159 |
160 | /**
161 | * Set the effect to `type`.
162 | *
163 | * @param {String} type
164 | * @return {Notification} for chaining
165 | * @api public
166 | */
167 |
168 | Notification.prototype.effect = function(type){
169 | this._effect = type;
170 | this.el.addClass(type);
171 | return this;
172 | };
173 |
174 | /**
175 | * Show the notification.
176 | *
177 | * @return {Notification} for chaining
178 | * @api public
179 | */
180 |
181 | Notification.prototype.show = function(){
182 | this.el.appendTo(list);
183 | return this;
184 | };
185 |
186 | /**
187 | * Set the notification `type`.
188 | *
189 | * @param {String} type
190 | * @return {Notification} for chaining
191 | * @api public
192 | */
193 |
194 | Notification.prototype.type = function(type){
195 | this._type = type;
196 | this.el.addClass(type);
197 | return this;
198 | };
199 |
200 | /**
201 | * Make it stick (clear hide timer), and make it closable.
202 | *
203 | * @return {Notification} for chaining
204 | * @api public
205 | */
206 |
207 | Notification.prototype.sticky = function(){
208 | return this.hide(0).closable();
209 | };
210 |
211 | /**
212 | * Hide the dialog with optional delay of `ms`,
213 | * otherwise the notification is removed immediately.
214 | *
215 | * @return {Number} ms
216 | * @return {Notification} for chaining
217 | * @api public
218 | */
219 |
220 | Notification.prototype.hide = function(ms){
221 | var self = this;
222 |
223 | // duration
224 | if ('number' == typeof ms) {
225 | clearTimeout(this.timer);
226 | if (!ms) return this;
227 | this.timer = setTimeout(function(){
228 | self.hide();
229 | }, ms);
230 | return this;
231 | }
232 |
233 | // hide / remove
234 | this.el.addClass('hide');
235 | if (this._effect) {
236 | setTimeout(function(self){
237 | self.remove();
238 | }, 500, this);
239 | } else {
240 | self.remove();
241 | }
242 |
243 | return this;
244 | };
245 |
246 | /**
247 | * Hide the notification without potential animation.
248 | *
249 | * @return {Dialog} for chaining
250 | * @api public
251 | */
252 |
253 | Notification.prototype.remove = function(){
254 | this.el.remove();
255 | return this;
256 | };
--------------------------------------------------------------------------------
/notification.css:
--------------------------------------------------------------------------------
1 |
2 | #notifications {
3 | position: fixed;
4 | top: 10px;
5 | right: 15px;
6 | }
7 |
8 | #notifications li {
9 | margin-bottom: 5px;
10 | list-style: none;
11 | }
12 |
13 | .notification {
14 | position: relative;
15 | max-width: 600px;
16 | min-width: 250px;
17 | border: 1px solid #eee;
18 | background: white;
19 | z-index: 100;
20 | }
21 |
22 | .notification .content {
23 | padding: 15px 20px;
24 | }
25 |
26 | .notification .title {
27 | margin: 0 0 5px 0;
28 | font-size: 16px;
29 | font-weight: normal;
30 | }
31 |
32 | .notification p {
33 | margin: 0;
34 | padding: 0;
35 | font-size: .9em;
36 | }
37 |
38 | .notification .close {
39 | position: absolute;
40 | top: 5px;
41 | right: 10px;
42 | text-decoration: none;
43 | color: #888;
44 | display: none;
45 | }
46 |
47 | .notification.closable .close {
48 | display: block;
49 | }
50 |
51 | .notification .close:hover {
52 | color: black;
53 | }
54 |
55 | .notification .close:active {
56 | margin-top: 1px;
57 | }
58 |
59 | /* close */
60 |
61 | .notification .close {
62 | position: absolute;
63 | top: 3px;
64 | right: 10px;
65 | text-decoration: none;
66 | color: #888;
67 | font-size: 16px;
68 | font-weight: bold;
69 | display: none;
70 | }
71 |
72 | /* slide */
73 |
74 | .notification.slide {
75 | -webkit-transition: opacity 300ms, top 300ms;
76 | -moz-transition: opacity 300ms, top 300ms;
77 | }
78 |
79 | .notification.slide.hide {
80 | opacity: 0;
81 | top: -500px;
82 | }
83 |
84 | /* fade */
85 |
86 | .notification.fade {
87 | -webkit-transition: opacity 300ms;
88 | -moz-transition: opacity 300ms;
89 | }
90 |
91 | .notification.fade.hide {
92 | opacity: 0;
93 | }
94 |
95 | /* scale */
96 |
97 | .notification.scale {
98 | -webkit-transition: -webkit-transform 300ms;
99 | -moz-transition: -moz-transform 300ms;
100 | -webkit-transform: scale(1);
101 | -moz-transform: scale(1);
102 | }
103 |
104 | .notification.scale.hide {
105 | -webkit-transform: scale(0);
106 | -moz-transform: scale(0);
107 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "notification",
3 | "description": "Notification component for the client (growl-like)",
4 | "version": "0.0.7",
5 | "keywords": [
6 | "notify",
7 | "notification",
8 | "ui",
9 | "growl"
10 | ],
11 | "dependencies": {
12 | "component-emitter": "1.2.0",
13 | "component-dom": "1.0.8",
14 | "on-body": "0.0.1"
15 | },
16 | "component": {
17 | "styles": [
18 | "notification.css"
19 | ],
20 | "scripts": {
21 | "notification": "index.js"
22 | },
23 | "templates": {
24 | "notification": "notification.html"
25 | }
26 | },
27 | "browser": {
28 | "dom": "component-dom",
29 | "emitter": "component-emitter"
30 | },
31 | "repository": {
32 | "type": "git",
33 | "url": "git://github.com/component/notification.git"
34 | },
35 | "license": "MIT"
36 | }
37 |
--------------------------------------------------------------------------------
/template.html:
--------------------------------------------------------------------------------
1 | -
2 |
3 |
Title
4 |
×
5 |
Message
6 |
7 |
8 |
--------------------------------------------------------------------------------
/template.js:
--------------------------------------------------------------------------------
1 | module.exports = '- \n \n
\n';
--------------------------------------------------------------------------------
/test/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Notification
5 |
6 |
7 |
13 |
14 |
15 | Notification
16 |
17 |
20 | notify('hello')
21 | notify('title', 'msg')
22 | notify.warn('hello')
23 | notify.error('hello')
24 | notify('msg).sticky()
25 | notify('msg).effect('slide')
26 | notify('msg).effect('fade')
27 | notify('msg).effect('scale')
28 |
29 |
--------------------------------------------------------------------------------