Skip to content

Commit

Permalink
Merge branch 'release/0.2.14'
Browse files Browse the repository at this point in the history
  • Loading branch information
igorprado committed May 3, 2017
2 parents 7731449 + 3d6e955 commit f7ad149
Show file tree
Hide file tree
Showing 11 changed files with 136 additions and 35 deletions.
2 changes: 1 addition & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
}
},
"rules": {
"react/display-name": 2,
"react/display-name": 0,
"react/jsx-curly-spacing": [2, "always"],
"react/jsx-no-duplicate-props": 2,
"react/jsx-no-undef": 2,
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# CHANGELOG

## 0.2.14 - May 3, 2017

* Ability to [edit notifications](https://github.com/igorprado/react-notification-system#removenotificationnotification). (thanks to @syndbg)
* Removed deprecation warning. Now using `prop-types` and `create-react-class`packages. (thanks to @andrewBalekha)
* Fix calling `onRemove` before updating the notifications state. (thanks to @szdc)

## 0.2.13 - Mar 14, 2017

* UMD support. (thanks to @jochenberger)
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ Returns the notification object to be used to programmatically dismiss a notific

Remove a notification programmatically. You can pass an object returned by `addNotification()` or by `onAdd()` callback. If passing an object, you need to make sure it must contain the `uid` property. You can pass only the `uid` too: `removeNotification(uid)`.


### `editNotification(notification)`

Edit a notification programmatically. You can pass an object previously returned by `addNotification()` or by `onAdd()` callback. If passing an object, you need to make sure it must contain the `uid` property. You can pass only the `uid` too: `editNotification(uid)`.


### `clearNotifications()`

Removes ALL notifications programatically.
Expand Down
3 changes: 2 additions & 1 deletion example/src/scripts/App.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
var React = require('react');
var ReactDOM = require('react-dom');
var createReactClass = require('create-react-class');
var NotificationSystem = require('NotificationSystem');
var constants = require('constants');
var NotificationGenerator = require('./NotificationGenerator');
Expand All @@ -14,7 +15,7 @@ var _getRandomPosition = function() {
// Styles
require('styles/base');

NotificationSystemExample = React.createClass({
NotificationSystemExample = createReactClass({

displayName: 'App',

Expand Down
3 changes: 2 additions & 1 deletion example/src/scripts/CustomElement.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
var React = require('react');
var PropTypes = require('prop-types');

function buttonClicked() {
alert('I\'m a custom button inside a custom element that was clicked');
Expand All @@ -14,7 +15,7 @@ function CustomElement(props) {
}

CustomElement.propTypes = {
name: React.PropTypes.string
name: PropTypes.string
};

module.exports = CustomElement;
8 changes: 5 additions & 3 deletions example/src/scripts/NotificationGenerator.jsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
var React = require('react');
var createReactClass = require('create-react-class');
var PropTypes = require('prop-types');

// Styles
require('styles/generator');

module.exports = React.createClass({
module.exports = createReactClass({

displayName: 'NotificationGenerator',

Expand Down Expand Up @@ -134,8 +136,8 @@ module.exports = React.createClass({
},

propTypes: {
notifications: React.PropTypes.func.isRequired,
allowHTML: React.PropTypes.func
notifications: PropTypes.func.isRequired,
allowHTML: PropTypes.func
},

render: function() {
Expand Down
6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-notification-system",
"version": "0.2.13",
"version": "0.2.14",
"description": "A React Notification System fully customized",
"main": "dist/NotificationSystem.js",
"scripts": {
Expand Down Expand Up @@ -32,7 +32,9 @@
},
"homepage": "https://github.com/igorprado/react-notification-system",
"dependencies": {
"object-assign": "^4.0.1"
"create-react-class": "^15.5.1",
"object-assign": "^4.0.1",
"prop-types": "^15.5.6"
},
"peerDependencies": {
"react": "0.14.x || ^15.0.0",
Expand Down
10 changes: 6 additions & 4 deletions src/NotificationContainer.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
var React = require('react');
var createReactClass = require('create-react-class');
var PropTypes = require('prop-types');
var NotificationItem = require('./NotificationItem');
var Constants = require('./constants');

var NotificationContainer = React.createClass({
var NotificationContainer = createReactClass({

propTypes: {
position: React.PropTypes.string.isRequired,
notifications: React.PropTypes.array.isRequired,
getStyles: React.PropTypes.object
position: PropTypes.string.isRequired,
notifications: PropTypes.array.isRequired,
getStyles: PropTypes.object
},

_style: {},
Expand Down
20 changes: 11 additions & 9 deletions src/NotificationItem.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
var React = require('react');
var createReactClass = require('create-react-class');
var PropTypes = require('prop-types');
var ReactDOM = require('react-dom');
var Constants = require('./constants');
var Helpers = require('./helpers');
Expand All @@ -24,17 +26,17 @@ var whichTransitionEvent = function() {
return transition;
};

var NotificationItem = React.createClass({
var NotificationItem = createReactClass({

propTypes: {
notification: React.PropTypes.object,
getStyles: React.PropTypes.object,
onRemove: React.PropTypes.func,
allowHTML: React.PropTypes.bool,
noAnimation: React.PropTypes.bool,
children: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.element
notification: PropTypes.object,
getStyles: PropTypes.object,
onRemove: PropTypes.func,
allowHTML: PropTypes.bool,
noAnimation: PropTypes.bool,
children: PropTypes.oneOfType([
PropTypes.string,
PropTypes.element
])
},

Expand Down
75 changes: 61 additions & 14 deletions src/NotificationSystem.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
var React = require('react');
var createReactClass = require('create-react-class');
var PropTypes = require('prop-types');
var merge = require('object-assign');
var NotificationContainer = require('./NotificationContainer');
var Constants = require('./constants');
var Styles = require('./styles');

var NotificationSystem = React.createClass({
var NotificationSystem = createReactClass({

uid: 3400,

Expand Down Expand Up @@ -66,17 +68,18 @@ var NotificationSystem = React.createClass({
var notifications = this.state.notifications.filter(function(toCheck) {
if (toCheck.uid === uid) {
notification = toCheck;
return false;
}
return toCheck.uid !== uid;
return true;
});

if (notification && notification.onRemove) {
notification.onRemove(notification);
}

if (this._isMounted) {
this.setState({ notifications: notifications });
}

if (notification && notification.onRemove) {
notification.onRemove(notification);
}
},

getInitialState: function() {
Expand All @@ -86,12 +89,12 @@ var NotificationSystem = React.createClass({
},

propTypes: {
style: React.PropTypes.oneOfType([
React.PropTypes.bool,
React.PropTypes.object
style: PropTypes.oneOfType([
PropTypes.bool,
PropTypes.object
]),
noAnimation: React.PropTypes.bool,
allowHTML: React.PropTypes.bool
noAnimation: PropTypes.bool,
allowHTML: PropTypes.bool
},

getDefaultProps: function() {
Expand Down Expand Up @@ -152,18 +155,63 @@ var NotificationSystem = React.createClass({
return _notification;
},

removeNotification: function(notification) {
getNotificationRef: function(notification) {
var self = this;
var foundNotification = null;

Object.keys(this.refs).forEach(function(container) {
if (container.indexOf('container') > -1) {
Object.keys(self.refs[container].refs).forEach(function(_notification) {
var uid = notification.uid ? notification.uid : notification;
if (_notification === 'notification-' + uid) {
self.refs[container].refs[_notification]._hideNotification();
// NOTE: Stop iterating further and return the found notification.
// Since UIDs are uniques and there won't be another notification found.
foundNotification = self.refs[container].refs[_notification];
return;
}
});
}
});

return foundNotification;
},

removeNotification: function(notification) {
var foundNotification = this.getNotificationRef(notification);
return foundNotification && foundNotification._hideNotification();
},

editNotification: function(notification, newNotification) {
var foundNotification = null;
// NOTE: Find state notification to update by using
// `setState` and forcing React to re-render the component.
var uid = notification.uid ? notification.uid : notification;

var newNotifications = this.state.notifications.filter(function(stateNotification) {
if (uid === stateNotification.uid) {
foundNotification = stateNotification;
return false;
}

return true;
});


if (!foundNotification) {
return;
}

newNotifications.push(
merge(
{},
foundNotification,
newNotification
)
);

this.setState({
notifications: newNotifications
});
},

clearNotifications: function() {
Expand Down Expand Up @@ -221,7 +269,6 @@ var NotificationSystem = React.createClass({
<div className="notifications-wrapper" style={ this._getStyles.wrapper() }>
{ containers }
</div>

);
}
});
Expand Down
32 changes: 32 additions & 0 deletions test/notification-system.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,38 @@ describe('Notification Component', function() {
done();
});

it('should edit an existing notification using returned object', (done) => {
const notificationCreated = component.addNotification(defaultNotification);
const notification = TestUtils.scryRenderedDOMComponentsWithClass(instance, 'notification');
expect(notification.length).toEqual(1);

const newTitle = 'foo';
const newContent = 'foobar';

component.editNotification(notificationCreated, { title: newTitle, message: newContent });
clock.tick(1000);
const notificationEdited = TestUtils.findRenderedDOMComponentWithClass(instance, 'notification');
expect(notificationEdited.getElementsByClassName('notification-title')[0].textContent).toEqual(newTitle);
expect(notificationEdited.getElementsByClassName('notification-message')[0].textContent).toEqual(newContent);
done();
});

it('should edit an existing notification using uid', (done) => {
const notificationCreated = component.addNotification(defaultNotification);
const notification = TestUtils.scryRenderedDOMComponentsWithClass(instance, 'notification');
expect(notification.length).toEqual(1);

const newTitle = 'foo';
const newContent = 'foobar';

component.editNotification(notificationCreated.uid, { title: newTitle, message: newContent });
clock.tick(1000);
const notificationEdited = TestUtils.findRenderedDOMComponentWithClass(instance, 'notification');
expect(notificationEdited.getElementsByClassName('notification-title')[0].textContent).toEqual(newTitle);
expect(notificationEdited.getElementsByClassName('notification-message')[0].textContent).toEqual(newContent);
done();
});

it('should remove all notifications', done => {
component.addNotification(defaultNotification);
component.addNotification(defaultNotification);
Expand Down

0 comments on commit f7ad149

Please sign in to comment.