Skip to content

Commit

Permalink
v3.0 uses a component + helper architecture that removes several hack…
Browse files Browse the repository at this point in the history
…s in previous versions, and is an ember-cli addon.
  • Loading branch information
simonexmachina committed Jan 5, 2015
1 parent e5b0707 commit c2abf62
Show file tree
Hide file tree
Showing 64 changed files with 810 additions and 1,106 deletions.
4 changes: 4 additions & 0 deletions .bowerrc
@@ -0,0 +1,4 @@
{
"directory": "bower_components",
"analytics": false
}
33 changes: 33 additions & 0 deletions .editorconfig
@@ -0,0 +1,33 @@
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# editorconfig.org

root = true


[*]
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
indent_style = space
indent_size = 2

[*.js]
indent_style = space
indent_size = 2

[*.hbs]
indent_style = space
indent_size = 2

[*.css]
indent_style = space
indent_size = 2

[*.html]
indent_style = space
indent_size = 2

[*.md]
trim_trailing_whitespace = false
9 changes: 9 additions & 0 deletions .ember-cli
@@ -0,0 +1,9 @@
{
/**
Ember CLI sends analytics information by default. The data is completely
anonymous, but there are times when you might want to disable this behavior.

Setting `disableAnalytics` to true will prevent any data from being sent.
*/
"disableAnalytics": false
}
20 changes: 17 additions & 3 deletions .gitignore
@@ -1,3 +1,17 @@
node_modules/
bower_components/
tmp/
# See http://help.github.com/ignore-files/ for more about ignoring files.

# compiled output
/dist
/tmp

# dependencies
/node_modules
/bower_components

# misc
/.sass-cache
/connect.lock
/coverage/*
/libpeerconnection.log
npm-debug.log
testem.log
36 changes: 7 additions & 29 deletions .jshintrc
Expand Up @@ -2,41 +2,18 @@
"predef": [
"document",
"window",
"location",
"setTimeout",
"Ember",
"Em",
"DS",
"$",
"EmberNotify",
"ok",
"module",
"find",
"stop",
"start",
"moduleFor",
"moduleForModel",
"moduleForComponent",
"expect",
"equal",
"strictEqual",
"deepEqual",
"test",
"emq",
"setResolver",
"require"
"-Promise"
],
"node" : false,
"browser" : false,
"boss" : true,
"browser": true,
"boss": true,
"curly": false,
"debug": false,
"devel": false,
"devel": true,
"eqeqeq": true,
"evil": true,
"forin": false,
"immed": false,
"laxbreak": false,
"laxbreak": true,
"newcap": true,
"noarg": true,
"noempty": false,
Expand All @@ -50,5 +27,6 @@
"strict": false,
"white": false,
"eqnull": true,
"esnext": true
"esnext": true,
"unused": true
}
22 changes: 19 additions & 3 deletions .travis.yml
@@ -1,4 +1,20 @@
---
language: node_js
node_js:
- "0.11"
- "0.10"

sudo: false

cache:
directories:
- node_modules

before_install:
- "npm config set spin false"
- "npm install -g npm@^2"

install:
- npm install -g bower
- npm install
- bower install

script:
- npm test
37 changes: 21 additions & 16 deletions Brocfile.js
@@ -1,18 +1,23 @@
var makeModules = require('broccoli-dist-es6-module'),
mergeTrees = require('broccoli-merge-trees'),
templateCompiler = require('ember-cli-htmlbars'),
exportTree = require('broccoli-export-tree');
/* jshint node: true */
/* global require, module */

var dist = makeModules('lib/', {
global: 'EmberNotify',
packageName: 'ember-notify',
main: 'main',
shim: {
'ember': 'Ember'
}
});
var assets = templateCompiler('assets/');
var tree = mergeTrees([dist, assets]);
//tree = exportTree(tree, {destDir: 'dist'});
var EmberAddon = require('ember-cli/lib/broccoli/ember-addon');

module.exports = tree;
var app = new EmberAddon();

// Use `app.import` to add additional libraries to the generated
// output files.
//
// If you need to use different assets in different
// environments, specify an object as the first parameter. That
// object's keys should be the environment name and the values
// should be the asset to use in that environment.
//
// If the library that you are including contains AMD or ES6
// modules that you would like to import into your application
// please specify an object with the list of modules as keys
// along with the exports of each module as its value.

app.import('vendor/ember-notify.css');

module.exports = app.toTree();
10 changes: 10 additions & 0 deletions CHANGELOG.md
@@ -0,0 +1,10 @@
# Changelog

## v3.0

v3.0 uses a component + helper architecture that removes several hacks in previous versions, and
integrates with ember-cli as an addon.

- Projects that don't use ember-cli will need to stay on the v2.0 branch
- You now need to add `{{ember-notify}}` to one of your templates, usually in `application.hbs`.
-
19 changes: 11 additions & 8 deletions README.md
Expand Up @@ -10,8 +10,11 @@ The CSS animations are inspired by CSS from [alertify.js](http://fabien-d.github

## Usage

```
import Notify from 'ember-notify';
1. Add `{{ember-notify}}` to one of your templates, usually in `application.hbs`.
2. Use the `Notify` helper to display messages:

```js
import Notify from 'ember-notify/main';

Notify.info("Hello there!");
Notify.alert("This is an alert.");
Expand All @@ -22,7 +25,7 @@ Notify.warning("Hmmn, that didn't work out.");
By default the notifications close after 2.5 seconds, or you can control when they're closed.

```
var notify = Notify.alert("You can control how long it's displayed.", {
var message = Notify.alert("You can control how long it's displayed.", {
closeAfter: 10000 // or set to null to disable auto-hiding
});
notify.send('close'); // and you can trigger close from your code
Expand All @@ -42,13 +45,13 @@ Notify.alert("This one's got rounded corners.", {
});
```

### Containers

`Notify` is an instance of the `Notify.Container` class, and will automatically append itself to the `document.body` the first time you display a notification.
### Multiple Containers

#### Multiple Containers
If you want to have separate notifications and control where they're inserted into the DOM you can
have multiple `{{ember-notify}}` components, but only one of them can be the 'primary' - this is the
one that is accessed using the `Notify` helper.

If you want to have separate notifications and control where they're inserted into the DOM you can use the `{{ember-notify}}` component. Create an instance of `Notify.Container` in your controller:
All of the other containers should be used as follows:

```
import Notify from 'ember-notify';
Expand Down
Empty file added addon/.gitkeep
Empty file.
99 changes: 99 additions & 0 deletions addon/components/ember-notify.js
@@ -0,0 +1,99 @@
import Ember from 'ember';
import Notify from 'ember-notify/main';
import {Message} from 'ember-notify/main';

export default Ember.Component.extend({
primary: true,
messages: null, // this should be a Stream, maybe in Ember 2

classNames: ['ember-notify-cn'],
messageStyle: 'foundation',

init: function() {
this._super();
if (!this.get('messages')) this.set('messages', []);

if (this.get('primary')) Notify.set('primary', this);
var style = this.get('messageStyle'), klass;
if (style) {
if ('foundation' === style) klass = FoundationView;
else if ('bootstrap' === style) klass = BootstrapView;
else throw new Error(
"Unknown messageStyle %s: options are 'foundation' and 'bootstrap'".fmt(style)
);
}
this.set('messageClass', klass || this.constructor.defaultViewClass);
},
show: function(message) {
if (!(message instanceof Message)) {
message = Message.create(message);
}
this.messages.pushObject(message);
return message;
}
});

export var BaseView = Ember.View.extend({
message: null,

classNames: ['ember-notify'],
classNameBindings: ['typeCss', 'message.visible:ember-notify-show:ember-notify-hidden'],
attributeBindings: ['data-alert'],
'data-alert': '',

didInsertElement: function() {
if (Ember.isNone(this.get('message.visible'))) {
// the element is added to the DOM in its hidden state, so that
// adding the 'ember-notify-show' class triggers the CSS transition
Ember.run.schedule('afterRender', this, function() {
this.set('message.visible', true);
});
}
var closeAfter = this.get('message.closeAfter');
if (closeAfter) {
Ember.run.later(this, function() {
if (this.get('isDestroyed')) return;
this.set('message.visible', false);
this.send('close');
}, closeAfter);
}
},
typeCss: function() {
var cssClass = this.get('message.type');
if (cssClass === 'error') cssClass = 'alert error';
return cssClass;
}.property('message.type'),
close: function() {
this.send('close');
},
actions: {
close: function() {
var that = this, removeAfter;
this.set('message.visible', false);
if (removeAfter = this.get('message.removeAfter')) {
Ember.run.later(this, remove, removeAfter);
}
else {
remove();
}
function remove() {
var parentView = that.get('parentView');
if (parentView) parentView.get('messages').removeObject(that.get('message'));
}
}
}
});

export var FoundationView = BaseView.extend({
classNames: ['alert-box'],
classNameBindings: ['radius::']
});

export var BootstrapView = BaseView.extend({
classNames: ['alert'],
typeCss: function() {
var type = this.get('type');
if (type === 'alert' || type === 'error') type = 'danger';
return 'alert-%@'.fmt(type);
}.property('type')
});
55 changes: 55 additions & 0 deletions addon/main.js
@@ -0,0 +1,55 @@
import Ember from 'ember';

export default Ember.Object.extend({

info: aliasToShow('info'),
success: aliasToShow('success'),
warning: aliasToShow('warning'),
alert: aliasToShow('alert'),
error: aliasToShow('error'),

show: function(type, message, options) {
if (typeof message === 'object') {
options = message;
message = null;
}
return this.get('primary').show(Ember.merge({
message: message,
type: type
}, options));
},

primary: function(key, val) {
if (arguments.length === 1) {
Ember.assert("Can't display notifications without a {{ember-notify}} in your " +
"templates, usually in application.hbs",
this._primary
);
}
if (arguments.length === 2) {
Ember.assert("Only one <ember-notify> should be primary=true. " +
"If you want more than one then use <ember-notify primary=false messages=boundProperty>",
!this._primary || this._primary.get('isDestroyed')
);
this._primary = val;
}
return this._primary;
}.property()

}).create();

export var Message = Ember.Object.extend({
message: null,
raw: '',
type: 'info',
closeAfter: 2500,
removeAfter: 250, // allow time for the close animation to finish

visible: undefined // set to false to disable auto-showing
});

function aliasToShow(type) {
return function(message, options) {
return this.show(type, message, options);
};
}

0 comments on commit c2abf62

Please sign in to comment.